Merge pull request #543 from KhronosGroup/fix-542
Support combined image-sampler workaround for arrays as well.
This commit is contained in:
commit
a090907607
@ -0,0 +1,19 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
uniform mediump sampler2D SPIRV_Cross_CombineduTextureuSampler[4];
|
||||
uniform mediump sampler2DArray SPIRV_Cross_CombineduTextureArrayuSampler[4];
|
||||
uniform mediump samplerCube SPIRV_Cross_CombineduTextureCubeuSampler[4];
|
||||
uniform mediump sampler3D SPIRV_Cross_CombineduTexture3DuSampler[4];
|
||||
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 _95 = (vTex + (vec2(1.0) / vec2(textureSize(SPIRV_Cross_CombineduTextureuSampler[1], 0)))) + (vec2(1.0) / vec2(textureSize(SPIRV_Cross_CombineduTextureuSampler[2], 1)));
|
||||
FragColor = ((((texture(SPIRV_Cross_CombineduTextureuSampler[2], _95) + texture(SPIRV_Cross_CombineduTextureuSampler[1], _95)) + texture(SPIRV_Cross_CombineduTextureuSampler[1], _95)) + texture(SPIRV_Cross_CombineduTextureArrayuSampler[3], vTex3)) + texture(SPIRV_Cross_CombineduTextureCubeuSampler[1], vTex3)) + texture(SPIRV_Cross_CombineduTexture3DuSampler[2], vTex3);
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(set = 0, binding = 1) uniform mediump texture2D uTexture[4];
|
||||
layout(set = 0, binding = 0) uniform mediump sampler uSampler;
|
||||
layout(set = 0, binding = 4) uniform mediump texture2DArray uTextureArray[4];
|
||||
layout(set = 0, binding = 3) uniform mediump textureCube uTextureCube[4];
|
||||
layout(set = 0, binding = 2) uniform mediump texture3D uTexture3D[4];
|
||||
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 _95 = (vTex + (vec2(1.0) / vec2(textureSize(sampler2D(uTexture[1], uSampler), 0)))) + (vec2(1.0) / vec2(textureSize(sampler2D(uTexture[2], uSampler), 1)));
|
||||
FragColor = ((((texture(sampler2D(uTexture[2], uSampler), _95) + texture(sampler2D(uTexture[1], uSampler), _95)) + texture(sampler2D(uTexture[1], uSampler), _95)) + texture(sampler2DArray(uTextureArray[3], uSampler), vTex3)) + texture(samplerCube(uTextureCube[1], uSampler), vTex3)) + texture(sampler3D(uTexture3D[2], uSampler), vTex3);
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
uniform mediump sampler2D SPIRV_Cross_CombineduTextureuSampler[4];
|
||||
uniform mediump sampler2DArray SPIRV_Cross_CombineduTextureArrayuSampler[4];
|
||||
uniform mediump samplerCube SPIRV_Cross_CombineduTextureCubeuSampler[4];
|
||||
uniform mediump sampler3D SPIRV_Cross_CombineduTexture3DuSampler[4];
|
||||
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
vec4 sample_func(vec2 uv, mediump sampler2D SPIRV_Cross_CombineduTexturesamp[4])
|
||||
{
|
||||
return texture(SPIRV_Cross_CombineduTexturesamp[2], uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual(vec2 uv, mediump sampler2D SPIRV_Cross_Combinedtexsamp)
|
||||
{
|
||||
return texture(SPIRV_Cross_Combinedtexsamp, uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual_array(vec2 uv, mediump sampler2D SPIRV_Cross_Combinedtexsamp[4])
|
||||
{
|
||||
return texture(SPIRV_Cross_Combinedtexsamp[1], uv);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 off = vec2(1.0) / vec2(textureSize(SPIRV_Cross_CombineduTextureuSampler[1], 0));
|
||||
vec2 off2 = vec2(1.0) / vec2(textureSize(SPIRV_Cross_CombineduTextureuSampler[2], 1));
|
||||
highp vec2 param = (vTex + off) + off2;
|
||||
vec4 c0 = sample_func(param, SPIRV_Cross_CombineduTextureuSampler);
|
||||
highp vec2 param_1 = (vTex + off) + off2;
|
||||
vec4 c1 = sample_func_dual(param_1, SPIRV_Cross_CombineduTextureuSampler[1]);
|
||||
highp vec2 param_2 = (vTex + off) + off2;
|
||||
vec4 c2 = sample_func_dual_array(param_2, SPIRV_Cross_CombineduTextureuSampler);
|
||||
vec4 c3 = texture(SPIRV_Cross_CombineduTextureArrayuSampler[3], vTex3);
|
||||
vec4 c4 = texture(SPIRV_Cross_CombineduTextureCubeuSampler[1], vTex3);
|
||||
vec4 c5 = texture(SPIRV_Cross_CombineduTexture3DuSampler[2], vTex3);
|
||||
FragColor = ((((c0 + c1) + c2) + c3) + c4) + c5;
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(set = 0, binding = 1) uniform mediump texture2D uTexture[4];
|
||||
layout(set = 0, binding = 0) uniform mediump sampler uSampler;
|
||||
layout(set = 0, binding = 4) uniform mediump texture2DArray uTextureArray[4];
|
||||
layout(set = 0, binding = 3) uniform mediump textureCube uTextureCube[4];
|
||||
layout(set = 0, binding = 2) uniform mediump texture3D uTexture3D[4];
|
||||
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
vec4 sample_func(mediump sampler samp, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(uTexture[2], samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual(mediump sampler samp, mediump texture2D tex, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex, samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual_array(mediump sampler samp, mediump texture2D tex[4], vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex[1], samp), uv);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 off = vec2(1.0) / vec2(textureSize(sampler2D(uTexture[1], uSampler), 0));
|
||||
vec2 off2 = vec2(1.0) / vec2(textureSize(sampler2D(uTexture[2], uSampler), 1));
|
||||
highp vec2 param = (vTex + off) + off2;
|
||||
vec4 c0 = sample_func(uSampler, param);
|
||||
highp vec2 param_1 = (vTex + off) + off2;
|
||||
vec4 c1 = sample_func_dual(uSampler, uTexture[1], param_1);
|
||||
highp vec2 param_2 = (vTex + off) + off2;
|
||||
vec4 c2 = sample_func_dual_array(uSampler, uTexture, param_2);
|
||||
vec4 c3 = texture(sampler2DArray(uTextureArray[3], uSampler), vTex3);
|
||||
vec4 c4 = texture(samplerCube(uTextureCube[1], uSampler), vTex3);
|
||||
vec4 c5 = texture(sampler3D(uTexture3D[2], uSampler), vTex3);
|
||||
FragColor = ((((c0 + c1) + c2) + c3) + c4) + c5;
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 63
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %FragColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %sample_from_func_s21_4__ "sample_from_func(s21[4];"
|
||||
OpName %uSampler "uSampler"
|
||||
OpName %sample_one_from_func_s21_ "sample_one_from_func(s21;"
|
||||
OpName %uSampler_0 "uSampler"
|
||||
OpName %Registers "Registers"
|
||||
OpMemberName %Registers 0 "index"
|
||||
OpName %registers "registers"
|
||||
OpName %FragColor "FragColor"
|
||||
OpName %uSampler_1 "uSampler"
|
||||
OpMemberDecorate %Registers 0 Offset 0
|
||||
OpDecorate %Registers Block
|
||||
OpDecorate %FragColor Location 0
|
||||
OpDecorate %uSampler_1 DescriptorSet 0
|
||||
OpDecorate %uSampler_1 Binding 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%7 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_8_uint_4 = OpTypeArray %7 %uint_4
|
||||
%_ptr_UniformConstant__arr_8_uint_4 = OpTypePointer UniformConstant %_arr_8_uint_4
|
||||
%v4float = OpTypeVector %float 4
|
||||
%14 = OpTypeFunction %v4float %_ptr_UniformConstant__arr_8_uint_4
|
||||
%_ptr_UniformConstant_8 = OpTypePointer UniformConstant %7
|
||||
%19 = OpTypeFunction %v4float %_ptr_UniformConstant_8
|
||||
%int = OpTypeInt 32 1
|
||||
%Registers = OpTypeStruct %int
|
||||
%_ptr_PushConstant_Registers = OpTypePointer PushConstant %Registers
|
||||
%registers = OpVariable %_ptr_PushConstant_Registers PushConstant
|
||||
%int_0 = OpConstant %int 0
|
||||
%_ptr_PushConstant_int = OpTypePointer PushConstant %int
|
||||
%v2int = OpTypeVector %int 2
|
||||
%int_4 = OpConstant %int 4
|
||||
%35 = OpConstantComposite %v2int %int_4 %int_4
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%FragColor = OpVariable %_ptr_Output_v4float Output
|
||||
%uSampler_1 = OpVariable %_ptr_UniformConstant__arr_8_uint_4 UniformConstant
|
||||
%int_10 = OpConstant %int 10
|
||||
%53 = OpConstantComposite %v2int %int_10 %int_10
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%48 = OpAccessChain %_ptr_PushConstant_int %registers %int_0
|
||||
%49 = OpLoad %int %48
|
||||
%50 = OpAccessChain %_ptr_UniformConstant_8 %uSampler_1 %49
|
||||
%51 = OpLoad %7 %50
|
||||
%55 = OpImageFetch %v4float %51 %53 Lod %int_0
|
||||
%56 = OpFunctionCall %v4float %sample_from_func_s21_4__ %uSampler_1
|
||||
%57 = OpFAdd %v4float %55 %56
|
||||
%58 = OpAccessChain %_ptr_PushConstant_int %registers %int_0
|
||||
%59 = OpLoad %int %58
|
||||
%60 = OpAccessChain %_ptr_UniformConstant_8 %uSampler_1 %59
|
||||
%61 = OpFunctionCall %v4float %sample_one_from_func_s21_ %60
|
||||
%62 = OpFAdd %v4float %57 %61
|
||||
OpStore %FragColor %62
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%sample_from_func_s21_4__ = OpFunction %v4float None %14
|
||||
%uSampler = OpFunctionParameter %_ptr_UniformConstant__arr_8_uint_4
|
||||
%17 = OpLabel
|
||||
%29 = OpAccessChain %_ptr_PushConstant_int %registers %int_0
|
||||
%30 = OpLoad %int %29
|
||||
%31 = OpAccessChain %_ptr_UniformConstant_8 %uSampler %30
|
||||
%32 = OpLoad %7 %31
|
||||
%37 = OpImageFetch %v4float %32 %35 Lod %int_0
|
||||
OpReturnValue %37
|
||||
OpFunctionEnd
|
||||
%sample_one_from_func_s21_ = OpFunction %v4float None %19
|
||||
%uSampler_0 = OpFunctionParameter %_ptr_UniformConstant_8
|
||||
%22 = OpLabel
|
||||
%40 = OpLoad %7 %uSampler_0
|
||||
%42 = OpImageFetch %v4float %40 %35 Lod %int_0
|
||||
OpReturnValue %42
|
||||
OpFunctionEnd
|
42
shaders/vulkan/frag/separate-sampler-texture-array.vk.frag
Normal file
42
shaders/vulkan/frag/separate-sampler-texture-array.vk.frag
Normal file
@ -0,0 +1,42 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(set = 0, binding = 0) uniform mediump sampler uSampler;
|
||||
layout(set = 0, binding = 1) uniform mediump texture2D uTexture[4];
|
||||
layout(set = 0, binding = 2) uniform mediump texture3D uTexture3D[4];
|
||||
layout(set = 0, binding = 3) uniform mediump textureCube uTextureCube[4];
|
||||
layout(set = 0, binding = 4) uniform mediump texture2DArray uTextureArray[4];
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
|
||||
vec4 sample_func(mediump sampler samp, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(uTexture[2], samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual(mediump sampler samp, mediump texture2D tex, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex, samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual_array(mediump sampler samp, mediump texture2D tex[4], vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex[1], samp), uv);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 off = 1.0 / vec2(textureSize(sampler2D(uTexture[1], uSampler), 0));
|
||||
vec2 off2 = 1.0 / vec2(textureSize(sampler2D(uTexture[2], uSampler), 1));
|
||||
|
||||
vec4 c0 = sample_func(uSampler, vTex + off + off2);
|
||||
vec4 c1 = sample_func_dual(uSampler, uTexture[1], vTex + off + off2);
|
||||
vec4 c2 = sample_func_dual_array(uSampler, uTexture, vTex + off + off2);
|
||||
vec4 c3 = texture(sampler2DArray(uTextureArray[3], uSampler), vTex3);
|
||||
vec4 c4 = texture(samplerCube(uTextureCube[1], uSampler), vTex3);
|
||||
vec4 c5 = texture(sampler3D(uTexture3D[2], uSampler), vTex3);
|
||||
|
||||
FragColor = c0 + c1 + c2 + c3 + c4 + c5;
|
||||
}
|
@ -3176,12 +3176,17 @@ bool Compiler::DummySamplerForCombinedImageHandler::handle(Op opcode, const uint
|
||||
if (length < 3)
|
||||
return false;
|
||||
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
uint32_t result_type = args[0];
|
||||
auto &type = compiler.get<SPIRType>(result_type);
|
||||
bool separate_image =
|
||||
type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer;
|
||||
if (separate_image)
|
||||
SPIRV_CROSS_THROW("Attempting to use arrays or structs of separate images. This is not possible to "
|
||||
"statically remap to plain GLSL.");
|
||||
if (!separate_image)
|
||||
return true;
|
||||
|
||||
uint32_t id = args[1];
|
||||
uint32_t ptr = args[2];
|
||||
compiler.set<SPIRExpression>(id, "", result_type, true);
|
||||
compiler.register_read(id, ptr, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3233,16 +3238,23 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
||||
// but this seems ridiculously complicated for a problem which is easy to work around.
|
||||
// Checking access chains like this assumes we don't have samplers or textures inside uniform structs, but this makes no sense.
|
||||
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
uint32_t result_type = args[0];
|
||||
|
||||
auto &type = compiler.get<SPIRType>(result_type);
|
||||
bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1;
|
||||
bool separate_sampler = type.basetype == SPIRType::Sampler;
|
||||
if (separate_image)
|
||||
SPIRV_CROSS_THROW("Attempting to use arrays or structs of separate images. This is not possible to "
|
||||
"statically remap to plain GLSL.");
|
||||
if (separate_sampler)
|
||||
SPIRV_CROSS_THROW(
|
||||
"Attempting to use arrays or structs of separate samplers. This is not possible to statically "
|
||||
"remap to plain GLSL.");
|
||||
|
||||
if (separate_image)
|
||||
{
|
||||
uint32_t id = args[1];
|
||||
uint32_t ptr = args[2];
|
||||
compiler.set<SPIRExpression>(id, "", result_type, true);
|
||||
compiler.register_read(id, ptr, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3354,6 +3366,15 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
|
||||
if (old_flags.get(DecorationRelaxedPrecision))
|
||||
new_flags.set(DecorationRelaxedPrecision);
|
||||
|
||||
// Propagate the array type for the original image as well.
|
||||
auto *var = compiler.maybe_get_backing_variable(image_id);
|
||||
if (var)
|
||||
{
|
||||
auto &parent_type = compiler.get<SPIRType>(var->basetype);
|
||||
type.array = parent_type.array;
|
||||
type.array_size_literal = parent_type.array_size_literal;
|
||||
}
|
||||
|
||||
compiler.combined_image_samplers.push_back({ combined_id, image_id, sampler_id });
|
||||
}
|
||||
|
||||
|
@ -384,6 +384,8 @@ public:
|
||||
// so this can be added before compile() if desired.
|
||||
//
|
||||
// Combined image samplers originating from this set are always considered active variables.
|
||||
// Arrays of separate samplers are not supported, but arrays of separate images are supported.
|
||||
// Array of images + sampler -> Array of combined image samplers.
|
||||
void build_combined_image_samplers();
|
||||
|
||||
// Gets a remapping for the combined image samplers.
|
||||
|
@ -3609,6 +3609,14 @@ void CompilerGLSL::emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left,
|
||||
|
||||
string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_id)
|
||||
{
|
||||
// Keep track of the array indices we have used to load the image.
|
||||
// We'll need to use the same array index into the combined image sampler array.
|
||||
auto image_expr = to_expression(image_id);
|
||||
string array_expr;
|
||||
auto array_index = image_expr.find_first_of('[');
|
||||
if (array_index != string::npos)
|
||||
array_expr = image_expr.substr(array_index, string::npos);
|
||||
|
||||
auto &args = current_function->arguments;
|
||||
|
||||
// For GLSL and ESSL targets, we must enumerate all possible combinations for sampler2D(texture2D, sampler) and redirect
|
||||
@ -3641,7 +3649,7 @@ string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_
|
||||
});
|
||||
|
||||
if (itr != end(combined))
|
||||
return to_expression(itr->id);
|
||||
return to_expression(itr->id) + array_expr;
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW(
|
||||
@ -3658,7 +3666,7 @@ string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_
|
||||
});
|
||||
|
||||
if (itr != end(combined_image_samplers))
|
||||
return to_expression(itr->combined_id);
|
||||
return to_expression(itr->combined_id) + array_expr;
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("Cannot find mapping for combined sampler, was build_combined_image_samplers() used "
|
||||
@ -6157,15 +6165,6 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
{
|
||||
uint32_t image_id = combined.global_image ? combined.image_id : arg[combined.image_id];
|
||||
uint32_t sampler_id = combined.global_sampler ? combined.sampler_id : arg[combined.sampler_id];
|
||||
|
||||
auto *image = maybe_get_backing_variable(image_id);
|
||||
if (image)
|
||||
image_id = image->self;
|
||||
|
||||
auto *samp = maybe_get_backing_variable(sampler_id);
|
||||
if (samp)
|
||||
sampler_id = samp->self;
|
||||
|
||||
arglist.push_back(to_combined_image_sampler(image_id, sampler_id));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user