Add support for SM5.1 ConstantBuffer<T>.

This commit is contained in:
Hans-Kristian Arntzen 2017-06-30 10:34:21 +02:00
Родитель 98a17431c2
Коммит ecf56cff2b
8 изменённых файлов: 202 добавлений и 24 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -0,0 +1,45 @@
struct CBO
{
float4 a;
float4 b;
float4 c;
float4 d;
};
ConstantBuffer<CBO> cbo[2][4] : register(b4);
struct PushMe
{
float4 a;
float4 b;
float4 c;
float4 d;
};
ConstantBuffer<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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -879,9 +879,20 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
{
auto &type = get<SPIRType>(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<T> 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

Просмотреть файл

@ -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)