diff --git a/reference/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag b/reference/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag new file mode 100644 index 00000000..5fa822b3 --- /dev/null +++ b/reference/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag @@ -0,0 +1,28 @@ +#version 310 es +precision mediump float; +precision highp int; + +struct PSInput +{ + highp vec4 color; + highp vec2 uv; +}; + +uniform mediump sampler2D SPIRV_Cross_CombinedtexSamp; + +layout(location = 0) in highp vec4 in_var_COLOR; +layout(location = 1) in highp vec2 in_var_TEXCOORD0; +layout(location = 0) out highp vec4 out_var_SV_TARGET; + +highp vec4 src_PSMain(PSInput _input) +{ + vec4 a = _input.color * texture(SPIRV_Cross_CombinedtexSamp, _input.uv); + return a; +} + +void main() +{ + PSInput param_var_input = PSInput(in_var_COLOR, in_var_TEXCOORD0); + out_var_SV_TARGET = src_PSMain(param_var_input); +} + diff --git a/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag b/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag new file mode 100644 index 00000000..dda2f027 --- /dev/null +++ b/shaders-no-opt/asm/frag/combined-image-sampler-dxc-min16float.asm.frag @@ -0,0 +1,95 @@ +; SPIR-V +; Version: 1.0 +; Generator: Google spiregg; 0 +; Bound: 48 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %PSMain "main" %in_var_COLOR %in_var_TEXCOORD0 %out_var_SV_TARGET + OpExecutionMode %PSMain OriginUpperLeft + ; Not actually ESSL, but makes testing easier. + OpSource ESSL 310 + OpName %type_2d_image "type.2d.image" + OpName %tex "tex" + OpName %type_sampler "type.sampler" + OpName %Samp "Samp" + OpName %in_var_COLOR "in.var.COLOR" + OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0" + OpName %out_var_SV_TARGET "out.var.SV_TARGET" + OpName %PSMain "PSMain" + OpName %PSInput "PSInput" + OpMemberName %PSInput 0 "color" + OpMemberName %PSInput 1 "uv" + OpName %param_var_input "param.var.input" + OpName %src_PSMain "src.PSMain" + OpName %input "input" + OpName %bb_entry "bb.entry" + OpName %a "a" + OpName %type_sampled_image "type.sampled.image" + OpDecorate %in_var_COLOR Location 0 + OpDecorate %in_var_TEXCOORD0 Location 1 + OpDecorate %out_var_SV_TARGET Location 0 + OpDecorate %tex DescriptorSet 0 + OpDecorate %tex Binding 0 + OpDecorate %Samp DescriptorSet 0 + OpDecorate %Samp Binding 1 + OpDecorate %tex RelaxedPrecision + OpDecorate %a RelaxedPrecision + OpDecorate %38 RelaxedPrecision + OpDecorate %45 RelaxedPrecision + OpDecorate %47 RelaxedPrecision + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %int_1 = OpConstant %int 1 + %float = OpTypeFloat 32 +%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image +%type_sampler = OpTypeSampler +%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %21 = OpTypeFunction %void + %PSInput = OpTypeStruct %v4float %v2float +%_ptr_Function_PSInput = OpTypePointer Function %PSInput + %31 = OpTypeFunction %v4float %_ptr_Function_PSInput +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Function_v2float = OpTypePointer Function %v2float +%type_sampled_image = OpTypeSampledImage %type_2d_image + %tex = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant + %Samp = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant +%in_var_COLOR = OpVariable %_ptr_Input_v4float Input +%in_var_TEXCOORD0 = OpVariable %_ptr_Input_v2float Input +%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output + %PSMain = OpFunction %void None %21 + %22 = OpLabel +%param_var_input = OpVariable %_ptr_Function_PSInput Function + %26 = OpLoad %v4float %in_var_COLOR + %27 = OpLoad %v2float %in_var_TEXCOORD0 + %28 = OpCompositeConstruct %PSInput %26 %27 + OpStore %param_var_input %28 + %29 = OpFunctionCall %v4float %src_PSMain %param_var_input + OpStore %out_var_SV_TARGET %29 + OpReturn + OpFunctionEnd + %src_PSMain = OpFunction %v4float None %31 + %input = OpFunctionParameter %_ptr_Function_PSInput + %bb_entry = OpLabel + %a = OpVariable %_ptr_Function_v4float Function + %36 = OpAccessChain %_ptr_Function_v4float %input %int_0 + %37 = OpLoad %v4float %36 + %38 = OpLoad %type_2d_image %tex + %39 = OpLoad %type_sampler %Samp + %41 = OpAccessChain %_ptr_Function_v2float %input %int_1 + %42 = OpLoad %v2float %41 + %44 = OpSampledImage %type_sampled_image %38 %39 + %45 = OpImageSampleImplicitLod %v4float %44 %42 None + %46 = OpFMul %v4float %37 %45 + OpStore %a %46 + %47 = OpLoad %v4float %a + OpReturnValue %47 + OpFunctionEnd + diff --git a/spirv_cross.cpp b/spirv_cross.cpp index c8a6e5c8..78bdba54 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -2144,15 +2144,15 @@ bool Compiler::CombinedImageSamplerHandler::end_function_scope(const uint32_t *a if (s) sampler_id = s->self; - register_combined_image_sampler(caller, image_id, sampler_id, param.depth); + register_combined_image_sampler(caller, 0, image_id, sampler_id, param.depth); } } return true; } -void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIRFunction &caller, uint32_t image_id, - uint32_t sampler_id, bool depth) +void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIRFunction &caller, uint32_t combined_module_id, + uint32_t image_id, uint32_t sampler_id, bool depth) { // We now have a texture ID and a sampler ID which will either be found as a global // or a parameter in our own function. If both are global, they will not need a parameter, @@ -2212,12 +2212,15 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR // Build new variable. compiler.set(combined_id, ptr_type_id, StorageClassFunction, 0); - // Inherit RelaxedPrecision (and potentially other useful flags if deemed relevant). - auto &new_flags = compiler.ir.meta[combined_id].decoration.decoration_flags; - auto &old_flags = compiler.ir.meta[sampler_id].decoration.decoration_flags; - new_flags.reset(); - if (old_flags.get(DecorationRelaxedPrecision)) - new_flags.set(DecorationRelaxedPrecision); + // Inherit RelaxedPrecision. + // If any of OpSampledImage, underlying image or sampler are marked, inherit the decoration. + bool relaxed_precision = + compiler.has_decoration(sampler_id, DecorationRelaxedPrecision) || + compiler.has_decoration(image_id, DecorationRelaxedPrecision) || + (combined_module_id && compiler.has_decoration(combined_module_id, DecorationRelaxedPrecision)); + + if (relaxed_precision) + compiler.set_decoration(combined_id, DecorationRelaxedPrecision); param.id = combined_id; @@ -2424,8 +2427,10 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar if (sampler) sampler_id = sampler->self; + uint32_t combined_id = args[1]; + auto &combined_type = compiler.get(args[0]); - register_combined_image_sampler(callee, image_id, sampler_id, combined_type.image.depth); + register_combined_image_sampler(callee, combined_id, image_id, sampler_id, combined_type.image.depth); } } @@ -2444,6 +2449,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar if (itr == end(compiler.combined_image_samplers)) { uint32_t sampled_type; + uint32_t combined_module_id; if (is_fetch) { // Have to invent the sampled image type. @@ -2453,10 +2459,12 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar type.self = sampled_type; type.basetype = SPIRType::SampledImage; type.image.depth = false; + combined_module_id = 0; } else { sampled_type = args[0]; + combined_module_id = args[1]; } auto id = compiler.ir.increase_bound_by(2); @@ -2476,12 +2484,14 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar compiler.set(combined_id, type_id, StorageClassUniformConstant, 0); // Inherit RelaxedPrecision (and potentially other useful flags if deemed relevant). - auto &new_flags = compiler.ir.meta[combined_id].decoration.decoration_flags; - // Fetch inherits precision from the image, not sampler (there is no sampler). - auto &old_flags = compiler.ir.meta[is_fetch ? image_id : sampler_id].decoration.decoration_flags; - new_flags.reset(); - if (old_flags.get(DecorationRelaxedPrecision)) - new_flags.set(DecorationRelaxedPrecision); + // If any of OpSampledImage, underlying image or sampler are marked, inherit the decoration. + bool relaxed_precision = + (sampler_id && compiler.has_decoration(sampler_id, DecorationRelaxedPrecision)) || + (image_id && compiler.has_decoration(image_id, DecorationRelaxedPrecision)) || + (combined_module_id && compiler.has_decoration(combined_module_id, DecorationRelaxedPrecision)); + + if (relaxed_precision) + compiler.set_decoration(combined_id, DecorationRelaxedPrecision); // Propagate the array type for the original image as well. auto *var = compiler.maybe_get_backing_variable(image_id); diff --git a/spirv_cross.hpp b/spirv_cross.hpp index 73de7a5d..e94b53ae 100644 --- a/spirv_cross.hpp +++ b/spirv_cross.hpp @@ -772,7 +772,7 @@ protected: uint32_t remap_parameter(uint32_t id); void push_remap_parameters(const SPIRFunction &func, const uint32_t *args, uint32_t length); void pop_remap_parameters(); - void register_combined_image_sampler(SPIRFunction &caller, uint32_t texture_id, uint32_t sampler_id, + void register_combined_image_sampler(SPIRFunction &caller, uint32_t combined_id, uint32_t texture_id, uint32_t sampler_id, bool depth); };