From 217a69348736ee7365d06066086f4083cc41d3ec Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 16 Apr 2020 11:21:38 +0100 Subject: [PATCH] Add support for misc math GLSL opcodes that don't have struct variants * step, smoothstep * ldexp * fma * faceforward, reflect --- .../shaders/spirv/spirv_debug_glsl450.cpp | 92 +++++++++++++++++++ renderdoc/driver/vulkan/vk_shaderdebug.cpp | 13 +++ util/test/demos/vk/vk_shader_debug_zoo.cpp | 57 ++++++++++++ 3 files changed, 162 insertions(+) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp index 8a95c00ce..44f14a967 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp @@ -407,6 +407,54 @@ ShaderVariable FMix(ThreadState &state, uint32_t, const rdcarray ¶ms) return var; } +ShaderVariable Step(ThreadState &state, uint32_t, const rdcarray ¶ms) +{ + CHECK_PARAMS(2); + + ShaderVariable edge = state.GetSrc(params[0]); + ShaderVariable x = state.GetSrc(params[1]); + + for(uint32_t c = 0; c < x.columns; c++) + x.value.fv[c] = x.value.fv[c] < edge.value.fv[c] ? 0.0f : 1.0f; + + return x; +} + +ShaderVariable SmoothStep(ThreadState &state, uint32_t, const rdcarray ¶ms) +{ + CHECK_PARAMS(3); + + ShaderVariable edge0 = state.GetSrc(params[0]); + ShaderVariable edge1 = state.GetSrc(params[1]); + ShaderVariable x = state.GetSrc(params[2]); + + for(uint32_t c = 0; c < x.columns; c++) + { + const float edge0f = edge0.value.fv[c]; + const float edge1f = edge1.value.fv[c]; + const float xf = x.value.fv[c]; + + const float t = GLSLMin(GLSLMax((xf - edge0f) / (edge1f - edge0f), 0.0f), 1.0f); + + x.value.fv[c] = t * t * (3 - 2 * t); + } + + return x; +} + +ShaderVariable Ldexp(ThreadState &state, uint32_t, const rdcarray ¶ms) +{ + CHECK_PARAMS(2); + + ShaderVariable x = state.GetSrc(params[0]); + ShaderVariable exp = state.GetSrc(params[1]); + + for(uint8_t c = 0; c < x.columns; c++) + x.value.fv[c] = ldexpf(x.value.fv[c], exp.value.iv[c]); + + return x; +} + ShaderVariable Cross(ThreadState &state, uint32_t, const rdcarray ¶ms) { CHECK_PARAMS(2); @@ -425,6 +473,44 @@ ShaderVariable Cross(ThreadState &state, uint32_t, const rdcarray ¶ms) return var; } +ShaderVariable FaceForward(ThreadState &state, uint32_t, const rdcarray ¶ms) +{ + CHECK_PARAMS(3); + + ShaderVariable N = state.GetSrc(params[0]); + ShaderVariable I = state.GetSrc(params[1]); + ShaderVariable Nref = state.GetSrc(params[1]); + + float dot = 0; + for(uint8_t c = 0; c < Nref.columns; c++) + dot += Nref.value.fv[c] * I.value.fv[c]; + + if(dot >= 0.0f) + { + for(uint8_t c = 0; c < Nref.columns; c++) + N.value.fv[c] = -N.value.fv[c]; + } + + return N; +} + +ShaderVariable Reflect(ThreadState &state, uint32_t, const rdcarray ¶ms) +{ + CHECK_PARAMS(2); + + ShaderVariable I = state.GetSrc(params[0]); + ShaderVariable N = state.GetSrc(params[1]); + + float dot = 0; + for(uint8_t c = 0; c < N.columns; c++) + dot += N.value.fv[c] * I.value.fv[c]; + + for(uint8_t c = 0; c < N.columns; c++) + N.value.fv[c] = I.value.fv[c] - 2.0f * dot * N.value.fv[c]; + + return N; +} + static float GLSLNMax(float x, float y) { const bool xnan = isnan(x); @@ -541,7 +627,12 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst) EXT(UClamp); EXT(SClamp); EXT(FMix); + EXT(Step); + EXT(SmoothStep); + EXT(Ldexp); EXT(Cross); + EXT(FaceForward); + EXT(Reflect); EXT(NMin); EXT(NMax); EXT(NClamp); @@ -572,6 +663,7 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst) GPU_EXT(Log2) GPU_EXT(Sqrt) GPU_EXT(InverseSqrt) + GPU_EXT(Fma) GPU_EXT(Length); GPU_EXT(Distance); GPU_EXT(Normalize); diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index a1f7f5d27..89c818fd6 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -1166,6 +1166,19 @@ private: rdcspv::Id zerof = editor.AddConstantImmediate(0.0f); + { + rdcspv::GLSLstd450 op = rdcspv::GLSLstd450::Fma; + + rdcspv::Id label = editor.MakeId(); + targets.push_back({(uint32_t)op, label}); + + cases.add(rdcspv::OpLabel(label)); + rdcspv::Id result = + cases.add(rdcspv::OpGLSL450(v4f32, editor.MakeId(), glsl450, op, {a, b, c})); + cases.add(rdcspv::OpStore(outVar, result)); + cases.add(rdcspv::OpBranch(breakLabel)); + } + // these ones are special { rdcspv::GLSLstd450 op = rdcspv::GLSLstd450::Length; diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index a7c31f207..c88e07ba3 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -478,6 +478,8 @@ void main() Color = fwidthCoarse(vec4(inpos, inposIncreased)); break; } +)EOSHADER" + R"EOSHADER( case 51: { Color = fwidthFine(vec4(inpos, inposIncreased)); @@ -698,6 +700,61 @@ void main() Color = refract(a, b, zerof+3.1f); break; } + case 89: + { + Color = vec4(fma(zerof+2.4f, posone*0.1f, posone*8.3f), + fma(zerof+2.4f, posone*0.0f, posone*8.3f), + fma(zerof+3.675f, posone*9.703f, posone*1.45f), + ((zerof+3.675f) * (posone*9.703f)) + posone*1.45f); + break; + } + case 90: + { + Color = vec4(step(posone*2.6f, zerof+2.4f), + step(posone*2.6f, zerof+2.5f), + step(posone*2.6f, zerof+2.6f), + step(posone*2.6f, zerof+2.7f)); + break; + } + case 91: + { + Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+1.9f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.0f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.1f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.3f)); + break; + } + case 92: + { + Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+2.4f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.5f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.6f), + smoothstep(posone*2.0f, posone*2.6f, zerof+2.8f)); + break; + } + case 93: + { + vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f); + vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f); + vec4 Nref = vec4(posone*6.4f, posone*7.5f, posone*8.3f, posone*0.9f); + Color = faceforward(N, I, Nref); + break; + } + case 94: + { + vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f); + vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f); + Color = reflect(N, I); + break; + } + case 95: + { + Color = vec4(ldexp(posone*1.4f, zeroi-3), + ldexp(posone*2.8f, zeroi+0), + ldexp(posone*5.6f, zeroi+3), + ldexp(posone*4.4f, zeroi+7)); + break; + } default: break; } }