diff --git a/src/base/base.cgh b/src/base/base.cgh index 040650b0..576a93c7 100644 --- a/src/base/base.cgh +++ b/src/base/base.cgh @@ -765,23 +765,24 @@ Struct(SamplerStateHandle) { u32 v; }; //- Shader constants -/* D3D12: 64 maximum root constants - * Vulkan: 32 maximum push constants - * +/* + * NOTE: D3d12 exposes 64 root constants, and vulkan 32 push constants. + * Other constants past the max can be used by the graphics + * implementation backend layer. */ -#define MaxShaderConstants (32) -#define MaxDeclarableShaderConstants (MaxShaderConstants - 1) /* 1 constant reserved for generic async compute queue check */ +#define MaxShaderConstants (8) #if IsLanguageC - #define ShaderConstant(type, name, slot) \ - StaticAssert(sizeof(type) <= 4); \ - StaticAssert(slot < MaxDeclarableShaderConstants); \ + #define ForceShaderConstant(type, name, slot) \ Enum(name##__shaderconstantenum) { name = slot }; \ Struct(name##__shaderconstanttype) { type v; } + #define ShaderConstant(type, name, slot) \ + StaticAssert(sizeof(type) <= 4); \ + StaticAssert(slot < MaxShaderConstants); \ + ForceShaderConstant(type, name, slot) #elif IsLanguageG - #define ShaderConstant(type, name, slot) cbuffer name : register(b##slot) { type name; } - - cbuffer IsAsyncCompute : register(b31) { b32 IsAsyncCompute; } + #define ForceShaderConstant(type, name, slot) cbuffer name : register(b##slot) { type name; } + #define ShaderConstant(type, name, slot) ForceShaderConstant(type, name, slot) #endif //////////////////////////////////////////////////////////// diff --git a/src/base/base_shader.gh b/src/base/base_shader.gh index e532b55c..2d88d81a 100644 --- a/src/base/base_shader.gh +++ b/src/base/base_shader.gh @@ -115,3 +115,203 @@ Vec2 NdcFromUv(Vec2 uv) result += Vec2(-1, 1); return result; } + +//////////////////////////////////////////////////////////// +//~ String helpers + +/* https://therealmjp.github.io/posts/hlsl-printf/ */ +template +u32 U32FromChar(in T c) +{ + if(c == ' ') + return 32; + if(c == '!') + return 33; + if(c == '\"' || c == '\"') + return 34; + if(c == '#') + return 35; + if(c == '$') + return 36; + if(c == '%') + return 37; + if(c == '&') + return 38; + if(c == '\'') + return 39; + if(c == '(') + return 40; + if(c == ')') + return 41; + if(c == '*') + return 42; + if(c == '+') + return 43; + if(c == ',') + return 44; + if(c == '-') + return 45; + if(c == '.') + return 46; + if(c == '/') + return 47; + if(c == '0') + return 48; + if(c == '1') + return 49; + if(c == '2') + return 50; + if(c == '3') + return 51; + if(c == '4') + return 52; + if(c == '5') + return 53; + if(c == '6') + return 54; + if(c == '7') + return 55; + if(c == '8') + return 56; + if(c == '9') + return 57; + if(c == ':') + return 58; + if(c == ';') + return 59; + if(c == '<') + return 60; + if(c == '=') + return 61; + if(c == '>') + return 62; + if(c == '?') + return 63; + if(c == '@') + return 64; + if(c == 'A') + return 65; + if(c == 'B') + return 66; + if(c == 'C') + return 67; + if(c == 'D') + return 68; + if(c == 'E') + return 69; + if(c == 'F') + return 70; + if(c == 'G') + return 71; + if(c == 'H') + return 72; + if(c == 'I') + return 73; + if(c == 'J') + return 74; + if(c == 'K') + return 75; + if(c == 'L') + return 76; + if(c == 'M') + return 77; + if(c == 'N') + return 78; + if(c == 'O') + return 79; + if(c == 'P') + return 80; + if(c == 'Q') + return 81; + if(c == 'R') + return 82; + if(c == 'S') + return 83; + if(c == 'T') + return 84; + if(c == 'U') + return 85; + if(c == 'V') + return 86; + if(c == 'W') + return 87; + if(c == 'X') + return 88; + if(c == 'Y') + return 89; + if(c == 'Z') + return 90; + if(c == '[') + return 91; + if(c == '\\') + return 92; + if(c == ']') + return 93; + if(c == '^') + return 94; + if(c == '_') + return 95; + if(c == '`') + return 96; + if(c == 'a') + return 97; + if(c == 'b') + return 98; + if(c == 'c') + return 99; + if(c == 'd') + return 100; + if(c == 'e') + return 101; + if(c == 'f') + return 102; + if(c == 'g') + return 103; + if(c == 'h') + return 104; + if(c == 'i') + return 105; + if(c == 'j') + return 106; + if(c == 'k') + return 107; + if(c == 'l') + return 108; + if(c == 'm') + return 109; + if(c == 'n') + return 110; + if(c == 'o') + return 111; + if(c == 'p') + return 112; + if(c == 'q') + return 113; + if(c == 'r') + return 114; + if(c == 's') + return 115; + if(c == 't') + return 116; + if(c == 'u') + return 117; + if(c == 'v') + return 118; + if(c == 'w') + return 119; + if(c == 'x') + return 120; + if(c == 'y') + return 121; + if(c == 'z') + return 122; + if(c == '{') + return 123; + if(c == '|') + return 124; + if(c == '}') + return 125; + if(c == '~') + return 126; + return 0; +} diff --git a/src/gpu/gpu.lay b/src/gpu/gpu.lay index 4a2a039b..bdb5daee 100644 --- a/src/gpu/gpu.lay +++ b/src/gpu/gpu.lay @@ -16,8 +16,9 @@ @IncludeC gpu_core.h @IncludeC gpu_shader_extras.cgh @IncludeC gpu_common.h + +@IncludeG gpu_shader_core.gh @IncludeG gpu_shader_extras.cgh -@IncludeG gpu_shader_extras.gh @Bootstrap GPU_Bootstrap @Bootstrap GPU_BootstrapExtra diff --git a/src/gpu/gpu_dx12/gpu_dx12.lay b/src/gpu/gpu_dx12/gpu_dx12.lay index 8be4a26d..6684dfd0 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.lay +++ b/src/gpu/gpu_dx12/gpu_dx12.lay @@ -3,9 +3,11 @@ ////////////////////////////// //- Api -@IncludeC gpu_dx12.h +@IncludeC gpu_dx12_core.h + +@IncludeG gpu_dx12_shader_core.gh ////////////////////////////// //- Impl -@IncludeC gpu_dx12.c +@IncludeC gpu_dx12_core.c diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12_core.c similarity index 100% rename from src/gpu/gpu_dx12/gpu_dx12.c rename to src/gpu/gpu_dx12/gpu_dx12_core.c diff --git a/src/gpu/gpu_dx12/gpu_dx12.h b/src/gpu/gpu_dx12/gpu_dx12_core.h similarity index 100% rename from src/gpu/gpu_dx12/gpu_dx12.h rename to src/gpu/gpu_dx12/gpu_dx12_core.h diff --git a/src/gpu/gpu_dx12/gpu_dx12_shader_core.gh b/src/gpu/gpu_dx12/gpu_dx12_shader_core.gh new file mode 100644 index 00000000..f0c1c9b7 --- /dev/null +++ b/src/gpu/gpu_dx12/gpu_dx12_shader_core.gh @@ -0,0 +1,36 @@ +//////////////////////////////////////////////////////////// +//~ Debug types + +//////////////////////////////////////////////////////////// +//~ Debug globals + +// RWByteAddressBufferHandle print_buff; + +StaticAssert(MaxShaderConstants == 8); /* Slots used below assume they won't overlap user shader constants */ +ForceShaderConstant(RWByteAddressBufferHandle, GPU_D12_DebugPrintBuff, 9); + +// cbuffer GPU_D12_DebugPrintCbuff_ : register(b9) { RWByteAddressBufferHandle print_buff; } + +//////////////////////////////////////////////////////////// +//~ @hookimpl Shader printf + +/* This technique comes from MJP's article: https://therealmjp.github.io/posts/hlsl-printf/ */ +#if GPU_DEBUG + #define DebugPrintImpl_(fmt_cstr) do { \ + u32 __strlen = 0; \ + for (;;) { if (U32FromChar(fmt_cstr[__strlen]) == 0) { break; } ++__strlen; } \ + RWByteAddressBuffer __print_buff; \ + __print_buff = RWByteAddressBufferFromHandle(GPU_D12_DebugPrintBuff); \ + u32 __pos; \ + __print_buff.InterlockedAdd(0, __strlen, __pos); \ + if (__pos < countof(__print_buff)) \ + { \ + for (u32 char_idx = 0; char_idx < __strlen; ++char_idx) \ + { \ + __print_buff.Store(__pos + char_idx, U32FromChar(fmt_cstr[char_idx])); \ + } \ + } \ + } while (0) +#else + #define DebugPrintImpl_(fmt_cstr) +#endif diff --git a/src/gpu/gpu_shader_core.gh b/src/gpu/gpu_shader_core.gh new file mode 100644 index 00000000..e1f71d05 --- /dev/null +++ b/src/gpu/gpu_shader_core.gh @@ -0,0 +1,5 @@ +//////////////////////////////////////////////////////////// +//~ @hookdecl Shader printf + +/* Implemented per graphics platform layer */ +#define DebugPrint(msg) DebugPrintImpl_(msg) diff --git a/src/gpu/gpu_shader_extras.cgh b/src/gpu/gpu_shader_extras.cgh index 9b04f949..2547c107 100644 --- a/src/gpu/gpu_shader_extras.cgh +++ b/src/gpu/gpu_shader_extras.cgh @@ -7,9 +7,5 @@ #define GPU_SharedHandle(type, v) (type(v)) #endif -#define GPU_DebugPrintBufferSize Mebi(128) - -#define GPU_DirectQueueDebugPrintBuffer GPU_SharedHandle(RWByteAddressBufferHandle, 1) -#define GPU_AsyncComputeQueueDebugPrintBuffer GPU_SharedHandle(RWByteAddressBufferHandle, 2) -#define GPU_BasicPointSampler GPU_SharedHandle(SamplerStateHandle, 3) -#define GPU_BasicNoiseTexture GPU_SharedHandle(Texture3DHandle, 4) +#define GPU_BasicPointSampler GPU_SharedHandle(SamplerStateHandle, 1) +#define GPU_BasicNoiseTexture GPU_SharedHandle(Texture3DHandle, 2) diff --git a/src/gpu/gpu_shader_extras.gh b/src/gpu/gpu_shader_extras.gh deleted file mode 100644 index f9701583..00000000 --- a/src/gpu/gpu_shader_extras.gh +++ /dev/null @@ -1,229 +0,0 @@ -//////////////////////////////////////////////////////////// -//~ Shader printf - -/* This technique comes from MJP's article: - * https://therealmjp.github.io/posts/hlsl-printf/ - */ - -template -u32 U32FromChar(in T c) -{ - if(c == ' ') - return 32; - if(c == '!') - return 33; - if(c == '\"' || c == '\"') - return 34; - if(c == '#') - return 35; - if(c == '$') - return 36; - if(c == '%') - return 37; - if(c == '&') - return 38; - if(c == '\'') - return 39; - if(c == '(') - return 40; - if(c == ')') - return 41; - if(c == '*') - return 42; - if(c == '+') - return 43; - if(c == ',') - return 44; - if(c == '-') - return 45; - if(c == '.') - return 46; - if(c == '/') - return 47; - if(c == '0') - return 48; - if(c == '1') - return 49; - if(c == '2') - return 50; - if(c == '3') - return 51; - if(c == '4') - return 52; - if(c == '5') - return 53; - if(c == '6') - return 54; - if(c == '7') - return 55; - if(c == '8') - return 56; - if(c == '9') - return 57; - if(c == ':') - return 58; - if(c == ';') - return 59; - if(c == '<') - return 60; - if(c == '=') - return 61; - if(c == '>') - return 62; - if(c == '?') - return 63; - if(c == '@') - return 64; - if(c == 'A') - return 65; - if(c == 'B') - return 66; - if(c == 'C') - return 67; - if(c == 'D') - return 68; - if(c == 'E') - return 69; - if(c == 'F') - return 70; - if(c == 'G') - return 71; - if(c == 'H') - return 72; - if(c == 'I') - return 73; - if(c == 'J') - return 74; - if(c == 'K') - return 75; - if(c == 'L') - return 76; - if(c == 'M') - return 77; - if(c == 'N') - return 78; - if(c == 'O') - return 79; - if(c == 'P') - return 80; - if(c == 'Q') - return 81; - if(c == 'R') - return 82; - if(c == 'S') - return 83; - if(c == 'T') - return 84; - if(c == 'U') - return 85; - if(c == 'V') - return 86; - if(c == 'W') - return 87; - if(c == 'X') - return 88; - if(c == 'Y') - return 89; - if(c == 'Z') - return 90; - if(c == '[') - return 91; - if(c == '\\') - return 92; - if(c == ']') - return 93; - if(c == '^') - return 94; - if(c == '_') - return 95; - if(c == '`') - return 96; - if(c == 'a') - return 97; - if(c == 'b') - return 98; - if(c == 'c') - return 99; - if(c == 'd') - return 100; - if(c == 'e') - return 101; - if(c == 'f') - return 102; - if(c == 'g') - return 103; - if(c == 'h') - return 104; - if(c == 'i') - return 105; - if(c == 'j') - return 106; - if(c == 'k') - return 107; - if(c == 'l') - return 108; - if(c == 'm') - return 109; - if(c == 'n') - return 110; - if(c == 'o') - return 111; - if(c == 'p') - return 112; - if(c == 'q') - return 113; - if(c == 'r') - return 114; - if(c == 's') - return 115; - if(c == 't') - return 116; - if(c == 'u') - return 117; - if(c == 'v') - return 118; - if(c == 'w') - return 119; - if(c == 'x') - return 120; - if(c == 'y') - return 121; - if(c == 'z') - return 122; - if(c == '{') - return 123; - if(c == '|') - return 124; - if(c == '}') - return 125; - if(c == '~') - return 126; - return 0; -} - -#if GPU_DEBUG - #define DebugPrint(fmt_cstr) do { \ - u32 __strlen = 0; \ - for (;;) { if (U32FromChar(fmt_cstr[__strlen]) == 0) { break; } ++__strlen; } \ - RWByteAddressBuffer __print_buff; \ - if (IsAsyncCompute) \ - { \ - __print_buff = RWByteAddressBufferFromHandle(GPU_AsyncComputeQueueDebugPrintBuffer); \ - } \ - else \ - { \ - __print_buff = RWByteAddressBufferFromHandle(GPU_DirectQueueDebugPrintBuffer); \ - } \ - u32 __pos; \ - __print_buff.InterlockedAdd(0, __strlen, __pos); \ - if (__pos < countof(__print_buff)) \ - { \ - for (u32 char_idx = 0; char_idx < __strlen; ++char_idx) \ - { \ - __print_buff.Store(__pos + char_idx, U32FromChar(fmt_cstr[char_idx])); \ - } \ - } \ - } while (0) -#else - #define DebugPrint(...) -#endif diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index 5d8c2093..8b85c9b1 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -28,6 +28,7 @@ @IncludeC pp_vis_shaders.cgh @IncludeC pp_vis_draw.h @IncludeC pp_vis_core.h + @IncludeG pp_vis_shaders.cgh @Bootstrap V_Bootstrap @@ -38,4 +39,5 @@ @IncludeC pp_vis_widgets.c @IncludeC pp_vis_draw.c @IncludeC pp_vis_core.c + @IncludeG pp_vis_shaders.g diff --git a/src/proto/proto.lay b/src/proto/proto.lay index 877adfb7..51787ee6 100644 --- a/src/proto/proto.lay +++ b/src/proto/proto.lay @@ -26,4 +26,5 @@ //- Impl @IncludeC proto.c + @IncludeG proto_shaders.g diff --git a/src/ui/ui.lay b/src/ui/ui.lay index bec34851..763d6303 100644 --- a/src/ui/ui.lay +++ b/src/ui/ui.lay @@ -23,6 +23,7 @@ @IncludeC ui_core.h @IncludeC ui_extras.h @IncludeC ui_shaders.cgh + @IncludeG ui_shaders.cgh @Bootstrap UI_Bootstrap