GLSL: Assume image and sampler can be RelaxedPrecision.

When merging combined image samplers, we only looked at sampler, but DXC
emits RelaxedPrecision only for texture. Does not hurt to check for more
things.
This commit is contained in:
Hans-Kristian Arntzen 2019-08-27 17:15:19 +02:00
parent 563e994486
commit d5a65b4190
4 changed files with 150 additions and 17 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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<SPIRVariable>(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<SPIRType>(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<SPIRVariable>(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);

View File

@ -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);
};