diff --git a/scripts/render.js b/scripts/render.js index 2be9977d..cee81315 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -275,18 +275,23 @@ function make_pipeline(pipeline) { pipeline.gpu = render._main.make_pipeline(pipeline); } +var shader_type = "msl"; + function make_shader(sh_file) { - var file = `shaders/spirv/${sh_file}.spv` + var file = `shaders/${shader_type}/${sh_file}.${shader_type}` + var refl = json.decode(io.slurp(`shaders/reflection/${sh_file}.json`)) if (shader_cache[file]) return shader_cache[file] var shader = { code: io.slurpbytes(file), + format: shader_type, stage: sh_file.endsWith("vert") ? "vertex" : "fragment", num_samplers: refl.separate_samplers ? refl.separate_samplers.length : 0, num_textures: 0, num_storage_buffers: refl.separate_storage_buffers ? refl.separate_storage_buffers.length : 0, - num_uniform_buffers: refl.ubos ? refl.ubos.length : 0 + num_uniform_buffers: refl.ubos ? refl.ubos.length : 0, + entrypoint: shader_type === "msl" ? "main0" : "main" } shader.gpu = render._main.make_shader(shader) @@ -414,7 +419,6 @@ function render_camera(camera) var camera = prosperon.camera; var draw_cmds = group_sprites_by_texture(render_queue); - console.log(json.encode(draw_cmds)) for (var group of draw_cmds) { var pipeline = sprite_pipeline; var mesh = spritemesh; diff --git a/shaders/compile.sh b/shaders/compile.sh index bcf29585..00068103 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -3,44 +3,31 @@ # Ensure directories exist mkdir -p spirv mkdir -p msl -mkdir -p dxil mkdir -p reflection # Vertex shaders for filename in *.vert.hlsl; do - if [ -f "$filename" ]; then - echo "compiling ${filename}" - shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}" - shadercross "$filename" -o "msl/${filename/.hlsl/.msl}" - shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}" - - # Generate reflection JSON - spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" - fi + if [ -f "$filename" ]; then echo "compiling ${filename}" + dxc -spirv -T vs_6_0 -Fo "spirv/${filename/.hlsl/.spv}" "$filename" + spirv-cross "spirv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" + fi done # Fragment shaders for filename in *.frag.hlsl; do - if [ -f "$filename" ]; then - echo "compiling ${filename}" - shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}" - shadercross "$filename" -o "msl/${filename/.hlsl/.msl}" - shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}" - - # Generate reflection JSON - spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" - fi + if [ -f "$filename" ]; then echo "compiling ${filename}" + dxc -spirv -T ps_6_0 -Fo "spirv/${filename/.hlsl/.spv}" "$filename" + spirv-cross "spirv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" + fi done # Compute shaders for filename in *.comp.hlsl; do - if [ -f "$filename" ]; then - echo "compiling ${filename}" - shadercross "$filename" -o "spirv/${filename/.hlsl/.spv}" - shadercross "$filename" -o "msl/${filename/.hlsl/.msl}" - shadercross "$filename" -o "dxil/${filename/.hlsl/.dxil}" - - # Generate reflection JSON - spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" - fi + if [ -f "$filename" ]; then echo "compiling ${filename}" + dxc -spirv -T cs_6_0 -Fo "spirv/${filename/.hlsl/.spv}" "$filename" + spirv-cross "spirv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + spirv-cross "spirv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" + fi done diff --git a/source/jsffi.c b/source/jsffi.c index 61d2aeba..7bc44f6b 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -4171,6 +4171,10 @@ static JSValue js_gpu_make_shader(JSContext *js, JSValueConst self, int argc, JS SDL_GPUDevice *gpu = js2SDL_GPUDevice(js, self); JSValue obj = argv[0]; + + JSValue jsfile = JS_GetPropertyStr(js,obj,"file"); + const char *file = JS_ToCString(js,jsfile); + JS_FreeValue(js,jsfile); // code JSValue code_val = JS_GetPropertyStr(js, obj, "code"); @@ -4214,18 +4218,41 @@ static JSValue js_gpu_make_shader(JSContext *js, JSValueConst self, int argc, JS Uint32 uniform_bufs = 0; JS_ToUint32(js, &uniform_bufs, uniform_bufs_val); JS_FreeValue(js, uniform_bufs_val); + + // format + JSValue format_val = JS_GetPropertyStr(js, obj, "format"); + const char *format_str = JS_ToCString(js, format_val); + SDL_GPUShaderFormat format = SDL_GPU_SHADERFORMAT_SPIRV; // default to SPIR-V + if (format_str) { + if (!strcmp(format_str, "private")) format = SDL_GPU_SHADERFORMAT_PRIVATE; + else if (!strcmp(format_str, "spv")) format = SDL_GPU_SHADERFORMAT_SPIRV; + else if (!strcmp(format_str, "dxbc")) format = SDL_GPU_SHADERFORMAT_DXBC; + else if (!strcmp(format_str, "dxil")) format = SDL_GPU_SHADERFORMAT_DXIL; + else if (!strcmp(format_str, "msl")) format = SDL_GPU_SHADERFORMAT_MSL; + else if (!strcmp(format_str, "metallib")) format = SDL_GPU_SHADERFORMAT_METALLIB; + JS_FreeCString(js, format_str); + } + JS_FreeValue(js, format_val); + + JSValue entry_val = JS_GetPropertyStr(js,obj,"entrypoint"); + const char *entry = JS_ToCString(js,entry_val); + JS_FreeValue(js,entry_val); + + printf("format str is %s; format value is %d\n", format_str, format); SDL_GPUShaderCreateInfo info = {0}; info.code_size = code_size; info.code = code_data; - info.entrypoint = "main"; - info.format = SDL_GPU_SHADERFORMAT_SPIRV; + info.entrypoint = entry; + info.format = format; info.stage = stage; info.num_samplers = samplers; info.num_storage_textures = textures; info.num_storage_buffers = storage_bufs; info.num_uniform_buffers = uniform_bufs; info.props = 0; // No extension properties by default + + JS_FreeCString(js,entry); SDL_GPUShader *shader = SDL_CreateGPUShader(gpu, &info); if (!shader) @@ -4392,6 +4419,22 @@ JSC_CCALL(gpu_query_fence, return JS_NewBool(js,SDL_QueryGPUFence(gpu,fence)); ) +JSC_CCALL(gpu_shader_format, + SDL_GPUDevice *gpu = js2SDL_GPUDevice(js,self); + SDL_GPUShaderFormat fmt = SDL_GetGPUShaderFormats(gpu); + if (!fmt) return JS_ThrowReferenceError(js, "Shader format available invalid."); + + JSValue arr = JS_NewArray(js); + int i = 0; + if (fmt & SDL_GPU_SHADERFORMAT_PRIVATE) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".private")); + if (fmt & SDL_GPU_SHADERFORMAT_SPIRV) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".spv")); + if (fmt & SDL_GPU_SHADERFORMAT_DXBC) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".dxbc")); + if (fmt & SDL_GPU_SHADERFORMAT_DXIL) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".dxil")); + if (fmt & SDL_GPU_SHADERFORMAT_MSL) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".msl")); + if (fmt & SDL_GPU_SHADERFORMAT_METALLIB) JS_SetPropertyUint32(js, arr, i++, JS_NewString(js, ".metallib")); + return arr; +) + static const JSCFunctionListEntry js_SDL_GPUDevice_funcs[] = { MIST_FUNC_DEF(gpu, claim_window, 1), MIST_FUNC_DEF(gpu, make_pipeline, 1), // loads pipeline state into an object @@ -4412,7 +4455,8 @@ static const JSCFunctionListEntry js_SDL_GPUDevice_funcs[] = { MIST_FUNC_DEF(gpu, upload, 3), MIST_FUNC_DEF(gpu, mainRT, 1), MIST_FUNC_DEF(gpu, wait_for_fences, 2), - MIST_FUNC_DEF(gpu, query_fence, 1) + MIST_FUNC_DEF(gpu, query_fence, 1), + MIST_FUNC_DEF(gpu, shader_format, 0), }; JSC_CCALL(renderpass_bind_pipeline,