Merge pull request #377 from KhronosGroup/fix-367

Support arrays of images in HLSL
This commit is contained in:
Hans-Kristian Arntzen 2018-01-04 13:18:49 +01:00 committed by GitHub
commit 81395b067d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 126 additions and 17 deletions

View File

@ -0,0 +1,29 @@
Texture2D<float4> uCombined[4] : register(t0);
SamplerState _uCombined_sampler[4] : register(s0);
Texture2D<float4> uTex[4] : register(t4);
SamplerState uSampler[4] : register(s8);
RWTexture2D<float4> uImage[8] : register(u12);
static float4 gl_FragCoord;
static float2 vTex;
static int vIndex;
struct SPIRV_Cross_Input
{
float2 vTex : TEXCOORD0;
nointerpolation int vIndex : TEXCOORD1;
float4 gl_FragCoord : SV_Position;
};
void frag_main()
{
uImage[vIndex][int2(gl_FragCoord.xy)] = ((uCombined[vIndex].Sample(_uCombined_sampler[vIndex], vTex) + uTex[vIndex].Sample(uSampler[vIndex], vTex)) + (uCombined[vIndex + 1].Sample(_uCombined_sampler[vIndex + 1], vTex))) + (uTex[vIndex + 1].Sample(uSampler[vIndex + 1], vTex));
}
void main(SPIRV_Cross_Input stage_input)
{
gl_FragCoord = stage_input.gl_FragCoord;
vTex = stage_input.vTex;
vIndex = stage_input.vIndex;
frag_main();
}

View File

@ -0,0 +1,43 @@
Texture2D<float4> uCombined[4] : register(t0);
SamplerState _uCombined_sampler[4] : register(s0);
Texture2D<float4> uTex[4] : register(t4);
SamplerState uSampler[4] : register(s8);
RWTexture2D<float4> uImage[8] : register(u12);
static float4 gl_FragCoord;
static float2 vTex;
static int vIndex;
struct SPIRV_Cross_Input
{
float2 vTex : TEXCOORD0;
nointerpolation int vIndex : TEXCOORD1;
float4 gl_FragCoord : SV_Position;
};
float4 sample_in_function(Texture2D<float4> samp, SamplerState _samp_sampler)
{
return samp.Sample(_samp_sampler, vTex);
}
float4 sample_in_function2(Texture2D<float4> tex, SamplerState samp)
{
return tex.Sample(samp, vTex);
}
void frag_main()
{
float4 color = uCombined[vIndex].Sample(_uCombined_sampler[vIndex], vTex);
color += uTex[vIndex].Sample(uSampler[vIndex], vTex);
color += sample_in_function(uCombined[vIndex + 1], _uCombined_sampler[vIndex + 1]);
color += sample_in_function2(uTex[vIndex + 1], uSampler[vIndex + 1]);
uImage[vIndex][int2(gl_FragCoord.xy)] = color;
}
void main(SPIRV_Cross_Input stage_input)
{
gl_FragCoord = stage_input.gl_FragCoord;
vTex = stage_input.vTex;
vIndex = stage_input.vIndex;
frag_main();
}

View File

@ -0,0 +1,28 @@
#version 450
layout(binding = 0) uniform sampler2D uCombined[4];
layout(binding = 4) uniform texture2D uTex[4];
layout(binding = 8) uniform sampler uSampler[4];
layout(binding = 12, rgba32f) uniform writeonly image2D uImage[8];
layout(location = 0) in vec2 vTex;
layout(location = 1) flat in int vIndex;
vec4 sample_in_function(sampler2D samp)
{
return texture(samp, vTex);
}
vec4 sample_in_function2(texture2D tex, sampler samp)
{
return texture(sampler2D(tex, samp), vTex);
}
void main()
{
vec4 color = texture(uCombined[vIndex], vTex);
color += texture(sampler2D(uTex[vIndex], uSampler[vIndex]), vTex);
color += sample_in_function(uCombined[vIndex + 1]);
color += sample_in_function2(uTex[vIndex + 1], uSampler[vIndex + 1]);
imageStore(uImage[vIndex], ivec2(gl_FragCoord.xy), color);
}

View File

@ -1513,7 +1513,17 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
string CompilerHLSL::to_sampler_expression(uint32_t id)
{
return join("_", to_expression(id), "_sampler");
auto expr = join("_", to_expression(id));
auto index = expr.find_first_of('[');
if (index == string::npos)
{
return expr + "_sampler";
}
else
{
// We have an expression like _ident[array], so we cannot tack on _sampler, insert it inside the string instead.
return expr.insert(index, "_sampler");
}
}
void CompilerHLSL::emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id)
@ -1529,17 +1539,13 @@ string CompilerHLSL::to_func_call_arg(uint32_t id)
return arg_str;
// Manufacture automatic sampler arg if the arg is a SampledImage texture and we're in modern HLSL.
auto *var = maybe_get<SPIRVariable>(id);
if (var)
{
auto &type = get<SPIRType>(var->basetype);
auto &type = expression_type(id);
// We don't have to consider combined image samplers here via OpSampledImage because
// those variables cannot be passed as arguments to functions.
// Only global SampledImage variables may be used as arguments.
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
arg_str += ", " + to_sampler_expression(id);
}
return arg_str;
}
@ -2334,25 +2340,28 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
case SPIRType::SampledImage:
case SPIRType::Image:
{
statement(image_type_hlsl_modern(type), " ", to_name(var.self), to_resource_binding(var), ";");
statement(image_type_hlsl_modern(type), " ", to_name(var.self), type_to_array_glsl(type),
to_resource_binding(var), ";");
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
{
// For combined image samplers, also emit a combined image sampler.
if (type.image.depth)
statement("SamplerComparisonState ", to_sampler_expression(var.self), to_resource_binding_sampler(var),
";");
statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type),
to_resource_binding_sampler(var), ";");
else
statement("SamplerState ", to_sampler_expression(var.self), to_resource_binding_sampler(var), ";");
statement("SamplerState ", to_sampler_expression(var.self), type_to_array_glsl(type),
to_resource_binding_sampler(var), ";");
}
break;
}
case SPIRType::Sampler:
if (comparison_samplers.count(var.self))
statement("SamplerComparisonState ", to_name(var.self), to_resource_binding(var), ";");
statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var),
";");
else
statement("SamplerState ", to_name(var.self), to_resource_binding(var), ";");
statement("SamplerState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";");
break;
default: