diff --git a/reference/opt/shaders-hlsl/frag/sampler-array.frag b/reference/opt/shaders-hlsl/frag/sampler-array.frag new file mode 100644 index 00000000..5b8e492d --- /dev/null +++ b/reference/opt/shaders-hlsl/frag/sampler-array.frag @@ -0,0 +1,29 @@ +Texture2D uCombined[4] : register(t0); +SamplerState _uCombined_sampler[4] : register(s0); +Texture2D uTex[4] : register(t4); +SamplerState uSampler[4] : register(s8); +RWTexture2D 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(); +} diff --git a/reference/shaders-hlsl/frag/sampler-array.frag b/reference/shaders-hlsl/frag/sampler-array.frag new file mode 100644 index 00000000..7fc5e3f3 --- /dev/null +++ b/reference/shaders-hlsl/frag/sampler-array.frag @@ -0,0 +1,43 @@ +Texture2D uCombined[4] : register(t0); +SamplerState _uCombined_sampler[4] : register(s0); +Texture2D uTex[4] : register(t4); +SamplerState uSampler[4] : register(s8); +RWTexture2D 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 samp, SamplerState _samp_sampler) +{ + return samp.Sample(_samp_sampler, vTex); +} + +float4 sample_in_function2(Texture2D 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(); +} diff --git a/shaders-hlsl/frag/sampler-array.frag b/shaders-hlsl/frag/sampler-array.frag new file mode 100644 index 00000000..75910ed1 --- /dev/null +++ b/shaders-hlsl/frag/sampler-array.frag @@ -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); +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 8901c86c..ecaf0397 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -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(id); - if (var) - { - auto &type = get(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); - } + // 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: