HLSL: Complete support for combined image samplers in legacy.

This commit is contained in:
Hans-Kristian Arntzen 2018-11-12 09:58:27 +01:00
Родитель e8e7baf1ca
Коммит b778e16e48
8 изменённых файлов: 153 добавлений и 37 удалений

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

@ -984,11 +984,13 @@ static int main_inner(int argc, char *argv[])
hlsl_opts.point_size_compat = true;
hlsl_opts.point_coord_compat = true;
}
if (hlsl_opts.shader_model <= 30)
{
combined_image_samplers = true;
build_dummy_sampler = true;
}
hlsl->set_hlsl_options(hlsl_opts);
}

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

@ -6,29 +6,38 @@ static const int b = SPIRV_CROSS_CONSTANT_ID_1;
#define SPIRV_CROSS_CONSTANT_ID_0 1
#endif
static const int a = SPIRV_CROSS_CONSTANT_ID_0;
static const uint _21 = (uint(a) + 0u);
static const uint _26 = (uint(a) + 0u);
#ifndef SPIRV_CROSS_CONSTANT_ID_10
#define SPIRV_CROSS_CONSTANT_ID_10 1u
#endif
static const uint _22 = SPIRV_CROSS_CONSTANT_ID_10;
static const uint3 gl_WorkGroupSize = uint3(_22, 20u, 1u);
static const uint _27 = gl_WorkGroupSize.x;
static const uint _28 = (_21 + _27);
static const uint _29 = gl_WorkGroupSize.y;
static const uint _30 = (_28 + _29);
static const int _32 = (1 - a);
static const uint _27 = SPIRV_CROSS_CONSTANT_ID_10;
static const uint3 gl_WorkGroupSize = uint3(_27, 20u, 1u);
static const uint _32 = gl_WorkGroupSize.x;
static const uint _33 = (_26 + _32);
static const uint _34 = gl_WorkGroupSize.y;
static const uint _35 = (_33 + _34);
static const int _42 = (1 - a);
RWByteAddressBuffer _17 : register(u0);
RWByteAddressBuffer _23 : register(u0);
static uint3 gl_GlobalInvocationID;
struct SPIRV_Cross_Input
{
uint3 gl_GlobalInvocationID : SV_DispatchThreadID;
};
void comp_main()
{
int spec_const_array_size[b];
spec_const_array_size[0] = 10;
spec_const_array_size[1] = 40;
spec_const_array_size[a] = a;
_17.Store(_30 * 4 + 0, uint(b + spec_const_array_size[_32]));
_23.Store((_35 + gl_GlobalInvocationID.x) * 4 + 0, uint(b + spec_const_array_size[_42]));
}
[numthreads(SPIRV_CROSS_CONSTANT_ID_10, 20, 1)]
void main()
void main(SPIRV_Cross_Input stage_input)
{
gl_GlobalInvocationID = stage_input.gl_GlobalInvocationID;
comp_main();
}

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

@ -0,0 +1,22 @@
uniform sampler2D uSamp;
uniform sampler2D SPIRV_Cross_CombineduTuS;
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : COLOR0;
};
void frag_main()
{
FragColor = tex2D(uSamp, 0.5f.xx) + tex2D(SPIRV_Cross_CombineduTuS, 0.5f.xx);
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = float4(FragColor);
return stage_output;
}

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

@ -6,29 +6,38 @@ static const int b = SPIRV_CROSS_CONSTANT_ID_1;
#define SPIRV_CROSS_CONSTANT_ID_0 1
#endif
static const int a = SPIRV_CROSS_CONSTANT_ID_0;
static const uint _21 = (uint(a) + 0u);
static const uint _26 = (uint(a) + 0u);
#ifndef SPIRV_CROSS_CONSTANT_ID_10
#define SPIRV_CROSS_CONSTANT_ID_10 1u
#endif
static const uint _22 = SPIRV_CROSS_CONSTANT_ID_10;
static const uint3 gl_WorkGroupSize = uint3(_22, 20u, 1u);
static const uint _27 = gl_WorkGroupSize.x;
static const uint _28 = (_21 + _27);
static const uint _29 = gl_WorkGroupSize.y;
static const uint _30 = (_28 + _29);
static const int _32 = (1 - a);
static const uint _27 = SPIRV_CROSS_CONSTANT_ID_10;
static const uint3 gl_WorkGroupSize = uint3(_27, 20u, 1u);
static const uint _32 = gl_WorkGroupSize.x;
static const uint _33 = (_26 + _32);
static const uint _34 = gl_WorkGroupSize.y;
static const uint _35 = (_33 + _34);
static const int _42 = (1 - a);
RWByteAddressBuffer _17 : register(u0);
RWByteAddressBuffer _23 : register(u0);
static uint3 gl_GlobalInvocationID;
struct SPIRV_Cross_Input
{
uint3 gl_GlobalInvocationID : SV_DispatchThreadID;
};
void comp_main()
{
int spec_const_array_size[b];
spec_const_array_size[0] = 10;
spec_const_array_size[1] = 40;
spec_const_array_size[a] = a;
_17.Store(_30 * 4 + 0, uint(b + spec_const_array_size[_32]));
_23.Store((_35 + gl_GlobalInvocationID.x) * 4 + 0, uint(b + spec_const_array_size[_42]));
}
[numthreads(SPIRV_CROSS_CONSTANT_ID_10, 20, 1)]
void main()
void main(SPIRV_Cross_Input stage_input)
{
gl_GlobalInvocationID = stage_input.gl_GlobalInvocationID;
comp_main();
}

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

@ -0,0 +1,32 @@
uniform sampler2D uSamp;
uniform sampler2D SPIRV_Cross_CombineduTuS;
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : COLOR0;
};
float4 samp(sampler2D uSamp_1)
{
return tex2D(uSamp_1, 0.5f.xx);
}
float4 samp_1(sampler2D SPIRV_Cross_CombinedTS)
{
return tex2D(SPIRV_Cross_CombinedTS, 0.5f.xx);
}
void frag_main()
{
FragColor = samp(uSamp) + samp_1(SPIRV_Cross_CombineduTuS);
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = float4(FragColor);
return stage_output;
}

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

@ -12,6 +12,8 @@ layout(set = 1, binding = 0) writeonly buffer SSBO
void main()
{
int spec_const_array_size[b];
spec_const_array_size[0] = 10;
spec_const_array_size[1] = 40;
spec_const_array_size[a] = a;
v[a + gl_WorkGroupSize.x + gl_WorkGroupSize.y] = b + spec_const_array_size[1 - a];
v[a + gl_WorkGroupSize.x + gl_WorkGroupSize.y + gl_GlobalInvocationID.x] = b + spec_const_array_size[1 - a];
}

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

@ -0,0 +1,21 @@
#version 450
layout(location = 0) out vec4 FragColor;
layout(binding = 0) uniform sampler2D uSamp;
layout(binding = 1) uniform texture2D uT;
layout(binding = 2) uniform sampler uS;
vec4 samp(sampler2D uSamp)
{
return texture(uSamp, vec2(0.5));
}
vec4 samp(texture2D T, sampler S)
{
return texture(sampler2D(T, S), vec2(0.5));
}
void main()
{
FragColor = samp(uSamp) + samp(uT, uS);
}

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

@ -2076,28 +2076,34 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
decl += to_name(func.self);
decl += "(";
vector<string> arglist;
if (!type.array.empty())
{
// Fake array returns by writing to an out array instead.
decl += "out ";
decl += type_to_glsl(type);
decl += " ";
decl += "SPIRV_Cross_return_value";
decl += type_to_array_glsl(type);
if (!func.arguments.empty())
decl += ", ";
string out_argument;
out_argument += "out ";
out_argument += type_to_glsl(type);
out_argument += " ";
out_argument += "SPIRV_Cross_return_value";
out_argument += type_to_array_glsl(type);
arglist.push_back(move(out_argument));
}
for (auto &arg : func.arguments)
{
// Do not pass in separate images or samplers if we're remapping
// to combined image samplers.
if (skip_argument(arg.id))
continue;
// Might change the variable name if it already exists in this function.
// SPIRV OpName doesn't have any semantic effect, so it's valid for an implementation
// to use same name for variables.
// Since we want to make the GLSL debuggable and somewhat sane, use fallback names for variables which are duplicates.
add_local_variable_name(arg.id);
decl += argument_decl(arg);
arglist.push_back(argument_decl(arg));
// Flatten a combined sampler to two separate arguments in modern HLSL.
auto &arg_type = get<SPIRType>(arg.type);
@ -2105,20 +2111,33 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
arg_type.image.dim != DimBuffer)
{
// Manufacture automatic sampler arg for SampledImage texture
decl += ", ";
decl += join(image_is_comparison(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ",
to_sampler_expression(arg.id), type_to_array_glsl(arg_type));
arglist.push_back(join(image_is_comparison(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ",
to_sampler_expression(arg.id), type_to_array_glsl(arg_type)));
}
if (&arg != &func.arguments.back())
decl += ", ";
// Hold a pointer to the parameter so we can invalidate the readonly field if needed.
auto *var = maybe_get<SPIRVariable>(arg.id);
if (var)
var->parameter = &arg;
}
for (auto &arg : func.shadow_arguments)
{
// Might change the variable name if it already exists in this function.
// SPIRV OpName doesn't have any semantic effect, so it's valid for an implementation
// to use same name for variables.
// Since we want to make the GLSL debuggable and somewhat sane, use fallback names for variables which are duplicates.
add_local_variable_name(arg.id);
arglist.push_back(argument_decl(arg));
// Hold a pointer to the parameter so we can invalidate the readonly field if needed.
auto *var = maybe_get<SPIRVariable>(arg.id);
if (var)
var->parameter = &arg;
}
decl += merge(arglist);
decl += ")";
statement(decl);
}