Build combined dummy samplers for Query functions without sampler as well.
Deal with various query functions which require dummy sampler. In SPIR-V, separate images are used, but GLSL (even Vulkan GLSL) requires combined sampler images ...
This commit is contained in:
Родитель
d93807a625
Коммит
40bbf6be7a
|
@ -0,0 +1,9 @@
|
|||
#version 450
|
||||
|
||||
uniform sampler2D SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler;
|
||||
uniform sampler2DMS SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform texture2D uSampler2D;
|
||||
layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS;
|
||||
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#version 450
|
||||
|
||||
uniform sampler2D SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler;
|
||||
uniform sampler2DMS SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 b = textureSize(SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler, 0);
|
||||
ivec2 c = textureSize(SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler);
|
||||
int l1 = textureQueryLevels(SPIRV_Cross_CombineduSampler2DSPIRV_Cross_DummySampler);
|
||||
int s0 = textureSamples(SPIRV_Cross_CombineduSampler2DMSSPIRV_Cross_DummySampler);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform texture2D uSampler2D;
|
||||
layout(set = 0, binding = 0) uniform texture2DMS uSampler2DMS;
|
||||
layout(set = 0, binding = 0) uniform sampler SPIRV_Cross_DummySampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 b = textureSize(sampler2D(uSampler2D, SPIRV_Cross_DummySampler), 0);
|
||||
ivec2 c = textureSize(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
|
||||
int l1 = textureQueryLevels(sampler2D(uSampler2D, SPIRV_Cross_DummySampler));
|
||||
int s0 = textureSamples(sampler2DMS(uSampler2DMS, SPIRV_Cross_DummySampler));
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 36
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpCapability ImageQuery
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %b "b"
|
||||
OpName %uSampler2D "uSampler2D"
|
||||
OpName %c "c"
|
||||
OpName %uSampler2DMS "uSampler2DMS"
|
||||
OpName %l1 "l1"
|
||||
OpName %s0 "s0"
|
||||
OpDecorate %uSampler2D DescriptorSet 0
|
||||
OpDecorate %uSampler2D Binding 0
|
||||
OpDecorate %uSampler2DMS DescriptorSet 0
|
||||
OpDecorate %uSampler2DMS Binding 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%v2int = OpTypeVector %int 2
|
||||
%_ptr_Function_v2int = OpTypePointer Function %v2int
|
||||
%float = OpTypeFloat 32
|
||||
%11 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %11
|
||||
%uSampler2D = OpVariable %_ptr_UniformConstant_12 UniformConstant
|
||||
%int_0 = OpConstant %int 0
|
||||
%20 = OpTypeImage %float 2D 0 0 1 1 Unknown
|
||||
%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %20
|
||||
%uSampler2DMS = OpVariable %_ptr_UniformConstant_21 UniformConstant
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%b = OpVariable %_ptr_Function_v2int Function
|
||||
%c = OpVariable %_ptr_Function_v2int Function
|
||||
%l1 = OpVariable %_ptr_Function_int Function
|
||||
%s0 = OpVariable %_ptr_Function_int Function
|
||||
%15 = OpLoad %11 %uSampler2D
|
||||
%18 = OpImageQuerySizeLod %v2int %15 %int_0
|
||||
OpStore %b %18
|
||||
%24 = OpLoad %20 %uSampler2DMS
|
||||
%26 = OpImageQuerySize %v2int %24
|
||||
OpStore %c %26
|
||||
%29 = OpLoad %11 %uSampler2D
|
||||
%31 = OpImageQueryLevels %int %29
|
||||
OpStore %l1 %31
|
||||
%33 = OpLoad %20 %uSampler2DMS
|
||||
%35 = OpImageQuerySamples %int %33
|
||||
OpStore %s0 %35
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -3157,8 +3157,12 @@ bool Compiler::DummySamplerForCombinedImageHandler::handle(Op opcode, const uint
|
|||
}
|
||||
|
||||
case OpImageFetch:
|
||||
case OpImageQuerySizeLod:
|
||||
case OpImageQuerySize:
|
||||
case OpImageQueryLevels:
|
||||
case OpImageQuerySamples:
|
||||
{
|
||||
// If we are fetching from a plain OpTypeImage, we must pre-combine with our dummy sampler.
|
||||
// If we are fetching or querying LOD from a plain OpTypeImage, we must pre-combine with our dummy sampler.
|
||||
auto *var = compiler.maybe_get_backing_variable(args[2]);
|
||||
if (var)
|
||||
{
|
||||
|
@ -3259,8 +3263,12 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
|||
}
|
||||
|
||||
case OpImageFetch:
|
||||
case OpImageQuerySizeLod:
|
||||
case OpImageQuerySize:
|
||||
case OpImageQueryLevels:
|
||||
case OpImageQuerySamples:
|
||||
{
|
||||
// If we are fetching from a plain OpTypeImage, we must pre-combine with our dummy sampler.
|
||||
// If we are fetching from a plain OpTypeImage or querying LOD, we must pre-combine with our dummy sampler.
|
||||
auto *var = compiler.maybe_get_backing_variable(args[2]);
|
||||
if (!var)
|
||||
return true;
|
||||
|
@ -3288,9 +3296,6 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
|||
return true;
|
||||
}
|
||||
|
||||
if (length < 4)
|
||||
return false;
|
||||
|
||||
// Registers sampler2D calls used in case they are parameters so
|
||||
// that their callees know which combined image samplers to propagate down the call stack.
|
||||
if (!functions.empty())
|
||||
|
@ -3337,6 +3342,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
|||
type = compiler.expression_type(args[2]);
|
||||
type.self = sampled_type;
|
||||
type.basetype = SPIRType::SampledImage;
|
||||
type.image.depth = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3909,40 +3909,47 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||
return is_legacy() ? legacy_tex_op(fname, imgtype, lod) : fname;
|
||||
}
|
||||
|
||||
std::string CompilerGLSL::convert_separate_image_to_combined(uint32_t id)
|
||||
{
|
||||
auto &imgtype = expression_type(id);
|
||||
auto *var = maybe_get_backing_variable(id);
|
||||
|
||||
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler.
|
||||
if (var)
|
||||
{
|
||||
auto &type = get<SPIRType>(var->basetype);
|
||||
if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
|
||||
{
|
||||
if (!dummy_sampler_id)
|
||||
SPIRV_CROSS_THROW(
|
||||
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
|
||||
|
||||
if (options.vulkan_semantics)
|
||||
{
|
||||
auto sampled_type = imgtype;
|
||||
sampled_type.basetype = SPIRType::SampledImage;
|
||||
return join(type_to_glsl(sampled_type), "(", to_expression(id), ", ",
|
||||
to_expression(dummy_sampler_id), ")");
|
||||
}
|
||||
else
|
||||
return to_combined_image_sampler(id, dummy_sampler_id);
|
||||
}
|
||||
}
|
||||
|
||||
return to_expression(id);
|
||||
}
|
||||
|
||||
// Returns the function args for a texture sampling function for the specified image and sampling characteristics.
|
||||
string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool, bool is_proj,
|
||||
uint32_t coord, uint32_t coord_components, uint32_t dref, uint32_t grad_x,
|
||||
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
|
||||
uint32_t comp, uint32_t sample, bool *p_forward)
|
||||
{
|
||||
string farg_str = to_expression(img);
|
||||
|
||||
string farg_str;
|
||||
if (is_fetch)
|
||||
{
|
||||
auto *var = maybe_get_backing_variable(img);
|
||||
|
||||
// If we are fetching from a plain OpTypeImage, we must combine with a dummy sampler.
|
||||
if (var)
|
||||
{
|
||||
auto &type = get<SPIRType>(var->basetype);
|
||||
if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
|
||||
{
|
||||
if (!dummy_sampler_id)
|
||||
SPIRV_CROSS_THROW(
|
||||
"Cannot find dummy sampler ID. Was build_dummy_sampler_for_combined_images() called?");
|
||||
|
||||
if (options.vulkan_semantics)
|
||||
{
|
||||
auto sampled_type = imgtype;
|
||||
sampled_type.basetype = SPIRType::SampledImage;
|
||||
farg_str = join(type_to_glsl(sampled_type), "(", to_expression(img), ", ",
|
||||
to_expression(dummy_sampler_id), ")");
|
||||
}
|
||||
else
|
||||
farg_str = to_combined_image_sampler(img, dummy_sampler_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
farg_str = convert_separate_image_to_combined(img);
|
||||
else
|
||||
farg_str = to_expression(img);
|
||||
|
||||
bool swizz_func = backend.swizzle_is_function;
|
||||
auto swizzle = [swizz_func](uint32_t comps, uint32_t in_comps) -> const char * {
|
||||
|
@ -7234,7 +7241,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
if (options.es)
|
||||
SPIRV_CROSS_THROW("textureQueryLevels not supported in ES profile.");
|
||||
|
||||
auto expr = join("textureQueryLevels(", to_expression(ops[2]), ")");
|
||||
auto expr = join("textureQueryLevels(", convert_separate_image_to_combined(ops[2]), ")");
|
||||
auto &restype = get<SPIRType>(ops[0]);
|
||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||
emit_op(result_type, id, expr, true);
|
||||
|
@ -7251,7 +7258,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
if (type.image.sampled == 2)
|
||||
expr = join("imageSamples(", to_expression(ops[2]), ")");
|
||||
else
|
||||
expr = join("textureSamples(", to_expression(ops[2]), ")");
|
||||
expr = join("textureSamples(", convert_separate_image_to_combined(ops[2]), ")");
|
||||
|
||||
auto &restype = get<SPIRType>(ops[0]);
|
||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||
|
@ -7272,7 +7279,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
uint32_t result_type = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
|
||||
auto expr = join("textureSize(", to_expression(ops[2]), ", ", bitcast_expression(SPIRType::Int, ops[3]), ")");
|
||||
auto expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ", ", bitcast_expression(SPIRType::Int, ops[3]), ")");
|
||||
auto &restype = get<SPIRType>(ops[0]);
|
||||
expr = bitcast_expression(restype, SPIRType::Int, expr);
|
||||
emit_op(result_type, id, expr, true);
|
||||
|
@ -7490,7 +7497,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||
else
|
||||
{
|
||||
// This path is hit for samplerBuffers and multisampled images which do not have LOD.
|
||||
expr = join("textureSize(", to_expression(ops[2]), ")");
|
||||
expr = join("textureSize(", convert_separate_image_to_combined(ops[2]), ")");
|
||||
}
|
||||
|
||||
auto &restype = get<SPIRType>(ops[0]);
|
||||
|
|
|
@ -556,6 +556,8 @@ protected:
|
|||
std::string convert_float_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||
std::string convert_double_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||
|
||||
std::string convert_separate_image_to_combined(uint32_t id);
|
||||
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче