From 26f5b6a4b40e142194dbe1d6890cff0557ebdc00 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 15 Apr 2020 14:34:28 +0100 Subject: [PATCH] Implement more rounding-related GLSL extended instructions --- .../shaders/spirv/spirv_debug_glsl450.cpp | 105 +++++++++++++++++- util/test/demos/vk/vk_shader_debug_zoo.cpp | 63 +++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp index 722984d23..f18389138 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_glsl450.cpp @@ -37,6 +37,40 @@ namespace glsl return ShaderVariable(); \ } +ShaderVariable RoundEven(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + { + float x = var.value.fv[c]; + if(!isinf(x) && !isnan(x)) + var.value.fv[c] = x - remainderf(x, 1.0f); + } + + return var; +} + +ShaderVariable Round(ThreadState &state, const rdcarray ¶ms) +{ + // for now do as the spec allows and implement this as RoundEven + return RoundEven(state, params); +} + +ShaderVariable Trunc(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + var.value.fv[c] = truncf(var.value.fv[c]); + + return var; +} + ShaderVariable FAbs(ThreadState &state, const rdcarray ¶ms) { CHECK_PARAMS(1); @@ -61,6 +95,41 @@ ShaderVariable SAbs(ThreadState &state, const rdcarray ¶ms) return var; } +ShaderVariable FSign(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + { + if(var.value.fv[c] > 0.0f) + var.value.fv[c] = 1.0f; + else if(var.value.fv[c] < 0.0f) + var.value.fv[c] = -1.0f; + } + + return var; +} + +ShaderVariable SSign(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + { + if(var.value.iv[c] > 0) + var.value.iv[c] = 1; + else if(var.value.iv[c] < 0) + var.value.iv[c] = -1; + // 0 is left alone + } + + return var; +} + ShaderVariable Floor(ThreadState &state, const rdcarray ¶ms) { CHECK_PARAMS(1); @@ -73,6 +142,30 @@ ShaderVariable Floor(ThreadState &state, const rdcarray ¶ms) return var; } +ShaderVariable Ceil(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + var.value.fv[c] = ceilf(var.value.fv[c]); + + return var; +} + +ShaderVariable Fract(ThreadState &state, const rdcarray ¶ms) +{ + CHECK_PARAMS(1); + + ShaderVariable var = state.GetSrc(params[0]); + + for(uint32_t c = 0; c < var.columns; c++) + var.value.fv[c] = var.value.fv[c] - floorf(var.value.fv[c]); + + return var; +} + ShaderVariable Pow(ThreadState &state, const rdcarray ¶ms) { CHECK_PARAMS(2); @@ -349,10 +442,20 @@ void ConfigureGLSLStd450(ExtInstDispatcher &extinst) extinst.functions.resize(extinst.names.size()); -#define EXT(func) extinst.functions[(uint32_t)GLSLstd450::func] = &glsl::func; +#define EXT(func) \ + extinst.functions[(uint32_t)GLSLstd450::func] = &glsl::func; \ + uint32_t noduplicate##func; \ + (void)noduplicate##func; + EXT(Round); + EXT(RoundEven); + EXT(Trunc); EXT(FAbs); EXT(SAbs); + EXT(FSign); + EXT(SSign); EXT(Floor); + EXT(Ceil); + EXT(Fract); EXT(Pow); EXT(FMin); EXT(UMin); diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index 2c5d81f4a..b222ee15d 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -508,6 +508,69 @@ void main() Color = vec4(push.data); break; } + case 57: + { + Color = vec4(roundEven(posone*2.5f), roundEven(posone*3.5f), roundEven(posone*4.5f), roundEven(posone*5.1f)); + break; + } + case 58: + { + Color = vec4(roundEven(negone*2.5f), roundEven(negone*3.5f), roundEven(negone*4.5f), roundEven(negone*5.1f)); + break; + } + case 59: + { + // avoid implementation-defined behaviour at half-way points + Color = vec4(round(posone*2.4f), round(posone*3.6f), round(posone*4.6f), round(posone*5.1f)); + break; + } + case 60: + { + Color = vec4(round(negone*2.6f), round(negone*3.6f), round(negone*4.6f), round(posone*5.1f)); + break; + } + case 61: + { + Color = vec4(trunc(posone*2.4f), trunc(posone*2.5f), trunc(posone*2.6f), trunc(posone*5.1f)); + break; + } + case 62: + { + Color = vec4(trunc(negone*2.4f), trunc(negone*2.5f), trunc(negone*2.6f), trunc(negone*3.1f)); + break; + } + case 63: + { + Color = vec4(fract(posone*2.4f), fract(posone*2.5f), fract(posone*2.6f), fract(posone*3.1f)); + break; + } + case 64: + { + Color = vec4(fract(negone*2.4f), fract(negone*2.5f), fract(negone*2.6f), fract(negone*3.1f)); + break; + } + case 65: + { + Color = vec4(ceil(posone*2.4f), ceil(posone*2.5f), ceil(posone*2.6f), ceil(posone*3.1f)); + break; + } + case 66: + { + Color = vec4(ceil(negone*2.4f), ceil(negone*2.5f), ceil(negone*2.6f), ceil(negone*3.1f)); + break; + } + case 67: + { + Color = vec4(sign(negone*2.4f), sign(posone*2.4f), sign(posinf), sign(neginf)); + break; + } + case 68: + { + int onei = zeroi+1; + int negi = zeroi-1; + Color = vec4(float(sign(onei*2)), float(sign(negi*2)), float(sign(0)), 1.0f); + break; + } default: break; } }