diff --git a/reference/shaders-hlsl/frag/constant-buffer-array.frag b/reference/shaders-hlsl/frag/constant-buffer-array.frag new file mode 100644 index 00000000..cd391d4d --- /dev/null +++ b/reference/shaders-hlsl/frag/constant-buffer-array.frag @@ -0,0 +1,51 @@ +struct _CBO +{ + float4 a; + float4 b; + float4 c; + float4 d; +}; + +cbuffer CBO : register(c4) +{ + _CBO cbo[2][4]; +}; +struct _PushMe +{ + float4 a; + float4 b; + float4 c; + float4 d; +}; + +cbuffer PushMe +{ + _PushMe push; +}; + +static float4 FragColor; + +struct SPIRV_Cross_Output +{ + float4 FragColor : SV_Target0; +}; + +void frag_main() +{ + FragColor = cbo[1][2].a; + FragColor += cbo[1][2].b; + FragColor += cbo[1][2].c; + FragColor += cbo[1][2].d; + FragColor += push.a; + FragColor += push.b; + FragColor += push.c; + FragColor += push.d; +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor = FragColor; + return stage_output; +} diff --git a/reference/shaders-hlsl/frag/constant-buffer-array.sm51.frag b/reference/shaders-hlsl/frag/constant-buffer-array.sm51.frag new file mode 100644 index 00000000..f3daa9e2 --- /dev/null +++ b/reference/shaders-hlsl/frag/constant-buffer-array.sm51.frag @@ -0,0 +1,45 @@ +struct CBO +{ + float4 a; + float4 b; + float4 c; + float4 d; +}; + +ConstantBuffer cbo[2][4] : register(b4); +struct PushMe +{ + float4 a; + float4 b; + float4 c; + float4 d; +}; + +ConstantBuffer push; + +static float4 FragColor; + +struct SPIRV_Cross_Output +{ + float4 FragColor : SV_Target0; +}; + +void frag_main() +{ + FragColor = cbo[1][2].a; + FragColor += cbo[1][2].b; + FragColor += cbo[1][2].c; + FragColor += cbo[1][2].d; + FragColor += push.a; + FragColor += push.b; + FragColor += push.c; + FragColor += push.d; +} + +SPIRV_Cross_Output main() +{ + frag_main(); + SPIRV_Cross_Output stage_output; + stage_output.FragColor = FragColor; + return stage_output; +} diff --git a/reference/shaders-hlsl/frag/resources.frag b/reference/shaders-hlsl/frag/resources.frag index e6b88cd4..b5b8f601 100644 --- a/reference/shaders-hlsl/frag/resources.frag +++ b/reference/shaders-hlsl/frag/resources.frag @@ -7,15 +7,6 @@ cbuffer CBuffer : register(c3) { _CBuffer cbuf; }; -struct _UAV0 -{ - float4 a; -}; - -cbuffer UAV0 : register(u1) -{ - _UAV0 uav0; -}; struct _PushMe { float4 d; @@ -47,7 +38,7 @@ void frag_main() { float4 c0 = uSampledImage.Sample(_uSampledImage_sampler, vTex); float4 c1 = uTexture.Sample(uSampler, vTex); - float4 c2 = (cbuf.a + uav0.a) + registers.d; + float4 c2 = cbuf.a + registers.d; FragColor = (c0 + c1) + c2; } diff --git a/shaders-hlsl/frag/constant-buffer-array.frag b/shaders-hlsl/frag/constant-buffer-array.frag new file mode 100644 index 00000000..d60002a0 --- /dev/null +++ b/shaders-hlsl/frag/constant-buffer-array.frag @@ -0,0 +1,32 @@ +#version 450 + +layout(std140, binding = 4) uniform CBO +{ + vec4 a; + vec4 b; + vec4 c; + vec4 d; +} cbo[2][4]; + +layout(std430, push_constant) uniform PushMe +{ + vec4 a; + vec4 b; + vec4 c; + vec4 d; +} push; + +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = cbo[1][2].a; + FragColor += cbo[1][2].b; + FragColor += cbo[1][2].c; + FragColor += cbo[1][2].d; + FragColor += push.a; + FragColor += push.b; + FragColor += push.c; + FragColor += push.d; +} + diff --git a/shaders-hlsl/frag/constant-buffer-array.sm51.frag b/shaders-hlsl/frag/constant-buffer-array.sm51.frag new file mode 100644 index 00000000..d60002a0 --- /dev/null +++ b/shaders-hlsl/frag/constant-buffer-array.sm51.frag @@ -0,0 +1,32 @@ +#version 450 + +layout(std140, binding = 4) uniform CBO +{ + vec4 a; + vec4 b; + vec4 c; + vec4 d; +} cbo[2][4]; + +layout(std430, push_constant) uniform PushMe +{ + vec4 a; + vec4 b; + vec4 c; + vec4 d; +} push; + +layout(location = 0) out vec4 FragColor; + +void main() +{ + FragColor = cbo[1][2].a; + FragColor += cbo[1][2].b; + FragColor += cbo[1][2].c; + FragColor += cbo[1][2].d; + FragColor += push.a; + FragColor += push.b; + FragColor += push.c; + FragColor += push.d; +} + diff --git a/shaders-hlsl/frag/resources.frag b/shaders-hlsl/frag/resources.frag index ea2548c5..16178bfd 100644 --- a/shaders-hlsl/frag/resources.frag +++ b/shaders-hlsl/frag/resources.frag @@ -1,11 +1,6 @@ #version 310 es precision mediump float; -layout(binding = 1, std430) readonly buffer UAV0 -{ - vec4 a; -} uav0; - layout(binding = 3, std140) uniform CBuffer { vec4 a; @@ -27,6 +22,6 @@ void main() { vec4 c0 = texture(uSampledImage, vTex); vec4 c1 = texture(sampler2D(uTexture, uSampler), vTex); - vec4 c2 = cbuf.a + uav0.a + registers.d; + vec4 c2 = cbuf.a + registers.d; FragColor = c0 + c1 + c2; } diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 584d95dd..2948bbf5 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -879,9 +879,20 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) { auto &type = get(var.basetype); + bool is_uav = has_decoration(type.self, DecorationBufferBlock); + if (is_uav) + SPIRV_CROSS_THROW("Buffer is SSBO (UAV). This is currently unsupported."); + add_resource_name(type.self); - statement("struct _", to_name(type.self)); + string struct_name; + if (options.shader_model >= 51) + struct_name = to_name(type.self); + else + struct_name = join("_", to_name(type.self)); + + // First, declare the struct of the UBO. + statement("struct ", struct_name); begin_scope(); type.member_name_cache.clear(); @@ -896,11 +907,17 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) end_scope_decl(); statement(""); - // TODO: UAV? - statement("cbuffer ", to_name(type.self), to_resource_binding(var)); - begin_scope(); - statement("_", to_name(type.self), " ", to_name(var.self), ";"); - end_scope_decl(); + if (options.shader_model >= 51) // SM 5.1 uses ConstantBuffer instead of cbuffer. + { + statement("ConstantBuffer<", struct_name, "> ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";"); + } + else + { + statement("cbuffer ", to_name(type.self), to_resource_binding(var)); + begin_scope(); + statement(struct_name, " ", to_name(var.self), type_to_array_glsl(type), ";"); + end_scope_decl(); + } } void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var) @@ -1586,7 +1603,12 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var) if (has_decoration(type.self, DecorationBufferBlock)) space = "u"; // UAV else if (has_decoration(type.self, DecorationBlock)) - space = "c"; // Constant buffers + { + if (options.shader_model >= 51) + space = "b"; // Constant buffers + else + space = "c"; // Constant buffers + } } else if (storage == StorageClassPushConstant) space = "c"; // Constant buffers diff --git a/test_shaders.py b/test_shaders.py index ce7a7e4c..80d7b284 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -102,6 +102,14 @@ def validate_shader_hlsl(shader): if (not force_no_external_validation) and os.path.exists('fxc'): subprocess.check_call(['fxc', shader]) +def shader_to_sm(shader): + if '.sm51.' in shader: + return '51' + elif '.sm20.' in shader: + return '20' + else: + return '50' + def cross_compile_hlsl(shader): spirv_f, spirv_path = tempfile.mkstemp() hlsl_f, hlsl_path = tempfile.mkstemp(suffix = os.path.basename(shader)) @@ -109,7 +117,9 @@ def cross_compile_hlsl(shader): os.close(hlsl_f) subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader]) spirv_cross_path = './spirv-cross' - subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', '50']) + + sm = shader_to_sm(shader) + subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', sm]) subprocess.check_call(['spirv-val', spirv_path]) validate_shader_hlsl(hlsl_path)