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 9aa45065..c390218d 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;