From 2f7848dcdaa5e90aef23b14095207c4b982120bc Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 27 Aug 2019 11:19:54 +0200 Subject: [PATCH] Deal with ldexp taking uint input. Need to value cast to int first. --- .../asm/frag/ldexp-uint-exponent.asm.frag | 11 ++++++ .../asm/frag/ldexp-uint-exponent.asm.frag | 36 +++++++++++++++++++ spirv_glsl.cpp | 22 +++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 reference/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag create mode 100644 shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag diff --git a/reference/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag b/reference/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag new file mode 100644 index 00000000..9acdd019 --- /dev/null +++ b/reference/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag @@ -0,0 +1,11 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(location = 0) out highp vec4 _GLF_color; + +void main() +{ + _GLF_color = ldexp(vec4(1.0), ivec4(uvec4(bitCount(uvec4(1u))))); +} + diff --git a/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag b/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag new file mode 100644 index 00000000..9baebc20 --- /dev/null +++ b/shaders-no-opt/asm/frag/ldexp-uint-exponent.asm.frag @@ -0,0 +1,36 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 20 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %_GLF_color + OpExecutionMode %main OriginUpperLeft + OpSource ESSL 310 + OpName %main "main" + OpName %_GLF_color "_GLF_color" + OpDecorate %_GLF_color Location 0 + OpDecorate %18 RelaxedPrecision + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %_GLF_color = OpVariable %_ptr_Output_v4float Output + %float_1 = OpConstant %float 1 + %11 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1 + %int = OpTypeInt 32 1 + %v4int = OpTypeVector %int 4 + %main = OpFunction %void None %3 + %5 = OpLabel + %18 = OpBitCount %v4uint %15 + %19 = OpExtInst %v4float %1 Ldexp %11 %18 + OpStore %_GLF_color %19 + OpReturn + OpFunctionEnd diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 51803a66..8ec8d6bb 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -5524,8 +5524,28 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, } case GLSLstd450Ldexp: - emit_binary_func_op(result_type, id, args[0], args[1], "ldexp"); + { + bool forward = should_forward(args[0]) && should_forward(args[1]); + + auto op0 = to_unpacked_expression(args[0]); + auto op1 = to_unpacked_expression(args[1]); + auto &op1_type = expression_type(args[1]); + if (op1_type.basetype != SPIRType::Int) + { + // Need a value cast here. + auto target_type = op1_type; + target_type.basetype = SPIRType::Int; + op1 = join(type_to_glsl_constructor(target_type), "(", op1, ")"); + } + + auto expr = join("ldexp(", op0, ", ", op1, ")"); + + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, args[0]); + inherit_expression_dependencies(id, args[1]); break; + } + case GLSLstd450PackSnorm4x8: emit_unary_func_op(result_type, id, args[0], "packSnorm4x8"); break;