From e8d5d71cad79e465de8c00a21568c141a03c696d Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 21 Aug 2017 10:01:03 +0200 Subject: [PATCH 1/2] Add sampler buffer support to HLSL. --- .../shaders-hlsl/vert/sampler-buffers.vert | 22 +++++++++++++++++++ shaders-hlsl/vert/sampler-buffers.vert | 13 +++++++++++ spirv_hlsl.cpp | 21 +++++++++++++----- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 reference/shaders-hlsl/vert/sampler-buffers.vert create mode 100644 shaders-hlsl/vert/sampler-buffers.vert diff --git a/reference/shaders-hlsl/vert/sampler-buffers.vert b/reference/shaders-hlsl/vert/sampler-buffers.vert new file mode 100644 index 00000000..36521854 --- /dev/null +++ b/reference/shaders-hlsl/vert/sampler-buffers.vert @@ -0,0 +1,22 @@ +Buffer uFloatSampler : register(t1); +Buffer uIntSampler : register(t2); +Buffer uUintSampler : register(t3); + +static float4 gl_Position; +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = (uFloatSampler.Load(20) + asfloat(uIntSampler.Load(40))) + asfloat(uUintSampler.Load(60)); +} + +SPIRV_Cross_Output main() +{ + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/shaders-hlsl/vert/sampler-buffers.vert b/shaders-hlsl/vert/sampler-buffers.vert new file mode 100644 index 00000000..a3dd8386 --- /dev/null +++ b/shaders-hlsl/vert/sampler-buffers.vert @@ -0,0 +1,13 @@ +#version 450 + +layout(binding = 1) uniform samplerBuffer uFloatSampler; +layout(binding = 2) uniform isamplerBuffer uIntSampler; +layout(binding = 3) uniform usamplerBuffer uUintSampler; + +void main() +{ + gl_Position = + texelFetch(uFloatSampler, 20) + + intBitsToFloat(texelFetch(uIntSampler, 40)) + + uintBitsToFloat(texelFetch(uUintSampler, 60)); +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 4f30907d..3d662313 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -48,6 +48,8 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type) { auto &imagetype = get(type.image.type); const char *dim = nullptr; + uint32_t components = 4; + switch (type.image.dim) { case Dim1D: @@ -63,17 +65,23 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type) dim = "Cube"; break; case DimRect: - SPIRV_CROSS_THROW("Rectangle texture support is not yet implemented for HLSL"); // TODO + SPIRV_CROSS_THROW("Rectangle texture support is not yet implemented for HLSL."); // TODO case DimBuffer: - // Buffer/RWBuffer. - SPIRV_CROSS_THROW("Buffer/RWBuffer support is not yet implemented for HLSL"); // TODO + if (type.image.sampled == 1) + return join("Buffer<", type_to_glsl(imagetype), components, ">"); + else if (type.image.sampled == 2) + { + SPIRV_CROSS_THROW("RWBuffer is not implemented yet for HLSL."); + //return join("RWBuffer<", type_to_glsl(imagetype), components, ">"); + } + else + SPIRV_CROSS_THROW("Sampler buffers must be either sampled or unsampled. Cannot deduce in runtime."); case DimSubpassData: // This should be implemented same way as desktop GL. Fetch on a 2D texture based on int2(SV_Position). SPIRV_CROSS_THROW("Subpass data support is not yet implemented for HLSL"); // TODO default: SPIRV_CROSS_THROW("Invalid dimension."); } - uint32_t components = 4; const char *arrayed = type.image.arrayed ? "Array" : ""; return join("Texture", dim, arrayed, "<", type_to_glsl(imagetype), components, ">"); } @@ -1582,7 +1590,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i) if (op == OpImageFetch) { auto &coordtype = expression_type(coord); - coord_expr = join("int", coordtype.vecsize + 1, "(", coord_expr, ", ", to_expression(lod), ")"); + if (imgtype.image.dim != DimBuffer) + coord_expr = join("int", coordtype.vecsize + 1, "(", coord_expr, ", ", to_expression(lod), ")"); } if (op != OpImageFetch) @@ -1728,7 +1737,7 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var) { statement(image_type_hlsl_modern(type), " ", to_name(var.self), to_resource_binding(var), ";"); - if (type.basetype == SPIRType::SampledImage) + if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer) { // For combined image samplers, also emit a combined image sampler. if (type.image.depth) From e8d2c8e710787ee8f40557f30b2a898266b7e171 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 21 Aug 2017 10:26:44 +0200 Subject: [PATCH 2/2] Support samplerBuffer as function parameters in HLSL. --- reference/shaders-hlsl/vert/sampler-buffers.vert | 7 ++++++- shaders-hlsl/vert/sampler-buffers.vert | 12 ++++++++---- spirv_hlsl.cpp | 9 ++++----- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/reference/shaders-hlsl/vert/sampler-buffers.vert b/reference/shaders-hlsl/vert/sampler-buffers.vert index 36521854..a4329dbf 100644 --- a/reference/shaders-hlsl/vert/sampler-buffers.vert +++ b/reference/shaders-hlsl/vert/sampler-buffers.vert @@ -8,9 +8,14 @@ struct SPIRV_Cross_Output float4 gl_Position : SV_Position; }; +float4 sample_from_function(Buffer s0, Buffer s1, Buffer s2) +{ + return (s0.Load(20) + asfloat(s1.Load(40))) + asfloat(s2.Load(60)); +} + void vert_main() { - gl_Position = (uFloatSampler.Load(20) + asfloat(uIntSampler.Load(40))) + asfloat(uUintSampler.Load(60)); + gl_Position = sample_from_function(uFloatSampler, uIntSampler, uUintSampler); } SPIRV_Cross_Output main() diff --git a/shaders-hlsl/vert/sampler-buffers.vert b/shaders-hlsl/vert/sampler-buffers.vert index a3dd8386..dccbf778 100644 --- a/shaders-hlsl/vert/sampler-buffers.vert +++ b/shaders-hlsl/vert/sampler-buffers.vert @@ -4,10 +4,14 @@ layout(binding = 1) uniform samplerBuffer uFloatSampler; layout(binding = 2) uniform isamplerBuffer uIntSampler; layout(binding = 3) uniform usamplerBuffer uUintSampler; +vec4 sample_from_function(samplerBuffer s0, isamplerBuffer s1, usamplerBuffer s2) +{ + return texelFetch(s0, 20) + + intBitsToFloat(texelFetch(s1, 40)) + + uintBitsToFloat(texelFetch(s2, 60)); +} + void main() { - gl_Position = - texelFetch(uFloatSampler, 20) + - intBitsToFloat(texelFetch(uIntSampler, 40)) + - uintBitsToFloat(texelFetch(uUintSampler, 60)); + gl_Position = sample_from_function(uFloatSampler, uIntSampler, uUintSampler); } diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 3d662313..3fa813bb 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -1032,7 +1032,7 @@ string CompilerHLSL::to_func_call_arg(uint32_t 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) + if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer) arg_str += ", " + to_sampler_expression(id); } @@ -1080,13 +1080,12 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, uint64_t return_f // Flatten a combined sampler to two separate arguments in modern HLSL. auto &arg_type = get(arg.type); - if (options.shader_model > 30 && arg_type.basetype == SPIRType::SampledImage) + if (options.shader_model > 30 && arg_type.basetype == SPIRType::SampledImage && arg_type.image.dim != DimBuffer) { // Manufacture automatic sampler arg for SampledImage texture decl += ", "; - if (arg_type.basetype == SPIRType::SampledImage) - decl += join(arg_type.image.depth ? "SamplerComparisonState " : "SamplerState ", - to_sampler_expression(arg.id)); + decl += join(arg_type.image.depth ? "SamplerComparisonState " : "SamplerState ", + to_sampler_expression(arg.id)); } if (&arg != &func.arguments.back())