Fix SSO for HLSL vertex shaders.
This commit is contained in:
Родитель
debe269a16
Коммит
dd604fec9a
|
@ -0,0 +1,35 @@
|
|||
#version 450
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
struct VSOut
|
||||
{
|
||||
float a;
|
||||
vec4 pos;
|
||||
};
|
||||
|
||||
struct VSOut_1
|
||||
{
|
||||
float a;
|
||||
};
|
||||
|
||||
layout(location = 0) out VSOut_1 _entryPointOutput;
|
||||
|
||||
VSOut _main()
|
||||
{
|
||||
VSOut vout;
|
||||
vout.a = 40.0;
|
||||
vout.pos = vec4(1.0);
|
||||
return vout;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
VSOut flattenTemp = _main();
|
||||
_entryPointOutput.a = flattenTemp.a;
|
||||
gl_Position = flattenTemp.pos;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 1
|
||||
; Bound: 40
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %_entryPointOutput %_entryPointOutput_pos
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %VSOut "VSOut"
|
||||
OpMemberName %VSOut 0 "a"
|
||||
OpMemberName %VSOut 1 "pos"
|
||||
OpName %_main_ "@main("
|
||||
OpName %vout "vout"
|
||||
OpName %flattenTemp "flattenTemp"
|
||||
OpName %VSOut_0 "VSOut"
|
||||
OpMemberName %VSOut_0 0 "a"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpName %_entryPointOutput_pos "@entryPointOutput_pos"
|
||||
OpDecorate %_entryPointOutput Location 0
|
||||
OpDecorate %_entryPointOutput_pos BuiltIn Position
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%VSOut = OpTypeStruct %float %v4float
|
||||
%9 = OpTypeFunction %VSOut
|
||||
%_ptr_Function_VSOut = OpTypePointer Function %VSOut
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%float_40 = OpConstant %float 40
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%int_1 = OpConstant %int 1
|
||||
%float_1 = OpConstant %float 1
|
||||
%21 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%VSOut_0 = OpTypeStruct %float
|
||||
%_ptr_Output_VSOut_0 = OpTypePointer Output %VSOut_0
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_VSOut_0 Output
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput_pos = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%flattenTemp = OpVariable %_ptr_Function_VSOut Function
|
||||
%28 = OpFunctionCall %VSOut %_main_
|
||||
OpStore %flattenTemp %28
|
||||
%32 = OpAccessChain %_ptr_Function_float %flattenTemp %int_0
|
||||
%33 = OpLoad %float %32
|
||||
%35 = OpAccessChain %_ptr_Output_float %_entryPointOutput %int_0
|
||||
OpStore %35 %33
|
||||
%38 = OpAccessChain %_ptr_Function_v4float %flattenTemp %int_1
|
||||
%39 = OpLoad %v4float %38
|
||||
OpStore %_entryPointOutput_pos %39
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_ = OpFunction %VSOut None %9
|
||||
%11 = OpLabel
|
||||
%vout = OpVariable %_ptr_Function_VSOut Function
|
||||
%18 = OpAccessChain %_ptr_Function_float %vout %int_0
|
||||
OpStore %18 %float_40
|
||||
%23 = OpAccessChain %_ptr_Function_v4float %vout %int_1
|
||||
OpStore %23 %21
|
||||
%24 = OpLoad %VSOut %vout
|
||||
OpReturnValue %24
|
||||
OpFunctionEnd
|
|
@ -1784,7 +1784,12 @@ void CompilerGLSL::fixup_image_load_store_access()
|
|||
|
||||
void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionModel model)
|
||||
{
|
||||
uint64_t emitted_builtins = 0;
|
||||
uint64_t global_builtins = 0;
|
||||
const SPIRVariable *block_var = nullptr;
|
||||
bool emitted_block = false;
|
||||
bool builtin_array = false;
|
||||
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() != TypeVariable)
|
||||
|
@ -1801,6 +1806,13 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
|
|||
if (m.builtin)
|
||||
builtins |= 1ull << m.builtin_type;
|
||||
}
|
||||
else if (var.storage == storage && !block && is_builtin_variable(var))
|
||||
{
|
||||
// While we're at it, collect all declared global builtins (HLSL mostly ...).
|
||||
auto &m = meta[var.self].decoration;
|
||||
if (m.builtin)
|
||||
global_builtins |= 1ull << m.builtin_type;
|
||||
}
|
||||
|
||||
if (!builtins)
|
||||
continue;
|
||||
|
@ -1808,42 +1820,58 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo
|
|||
if (emitted_block)
|
||||
SPIRV_CROSS_THROW("Cannot use more than one builtin I/O block.");
|
||||
|
||||
if (storage == StorageClassOutput)
|
||||
statement("out gl_PerVertex");
|
||||
else
|
||||
statement("in gl_PerVertex");
|
||||
|
||||
begin_scope();
|
||||
if (builtins & (1ull << BuiltInPosition))
|
||||
statement("vec4 gl_Position;");
|
||||
if (builtins & (1ull << BuiltInPointSize))
|
||||
statement("float gl_PointSize;");
|
||||
if (builtins & (1ull << BuiltInClipDistance))
|
||||
statement("float gl_ClipDistance[];"); // TODO: Do we need a fixed array size here?
|
||||
if (builtins & (1ull << BuiltInCullDistance))
|
||||
statement("float gl_CullDistance[];"); // TODO: Do we need a fixed array size here?
|
||||
|
||||
bool builtin_array = !type.array.empty();
|
||||
bool tessellation = model == ExecutionModelTessellationEvaluation || model == ExecutionModelTessellationControl;
|
||||
if (builtin_array)
|
||||
{
|
||||
// Make sure the array has a supported name in the code.
|
||||
if (storage == StorageClassOutput)
|
||||
set_name(var.self, "gl_out");
|
||||
else if (storage == StorageClassInput)
|
||||
set_name(var.self, "gl_in");
|
||||
|
||||
if (model == ExecutionModelTessellationControl && storage == StorageClassOutput)
|
||||
end_scope_decl(join(to_name(var.self), "[", get_entry_point().output_vertices, "]"));
|
||||
else
|
||||
end_scope_decl(join(to_name(var.self), tessellation ? "[gl_MaxPatchVertices]" : "[]"));
|
||||
}
|
||||
else
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
|
||||
emitted_builtins = builtins;
|
||||
emitted_block = true;
|
||||
builtin_array = !type.array.empty();
|
||||
block_var = &var;
|
||||
}
|
||||
|
||||
global_builtins &=
|
||||
(1ull << BuiltInPosition) |
|
||||
(1ull << BuiltInPointSize) |
|
||||
(1ull << BuiltInClipDistance) |
|
||||
(1ull << BuiltInCullDistance);
|
||||
|
||||
// Try to collect all other declared builtins.
|
||||
if (!emitted_block)
|
||||
emitted_builtins = global_builtins;
|
||||
|
||||
// Can't declare an empty interface block.
|
||||
if (!emitted_builtins)
|
||||
return;
|
||||
|
||||
if (storage == StorageClassOutput)
|
||||
statement("out gl_PerVertex");
|
||||
else
|
||||
statement("in gl_PerVertex");
|
||||
|
||||
begin_scope();
|
||||
if (emitted_builtins & (1ull << BuiltInPosition))
|
||||
statement("vec4 gl_Position;");
|
||||
if (emitted_builtins & (1ull << BuiltInPointSize))
|
||||
statement("float gl_PointSize;");
|
||||
if (emitted_builtins & (1ull << BuiltInClipDistance))
|
||||
statement("float gl_ClipDistance[];"); // TODO: Do we need a fixed array size here?
|
||||
if (emitted_builtins & (1ull << BuiltInCullDistance))
|
||||
statement("float gl_CullDistance[];"); // TODO: Do we need a fixed array size here?
|
||||
|
||||
bool tessellation = model == ExecutionModelTessellationEvaluation || model == ExecutionModelTessellationControl;
|
||||
if (builtin_array)
|
||||
{
|
||||
// Make sure the array has a supported name in the code.
|
||||
if (storage == StorageClassOutput)
|
||||
set_name(block_var->self, "gl_out");
|
||||
else if (storage == StorageClassInput)
|
||||
set_name(block_var->self, "gl_in");
|
||||
|
||||
if (model == ExecutionModelTessellationControl && storage == StorageClassOutput)
|
||||
end_scope_decl(join(to_name(block_var->self), "[", get_entry_point().output_vertices, "]"));
|
||||
else
|
||||
end_scope_decl(join(to_name(block_var->self), tessellation ? "[gl_MaxPatchVertices]" : "[]"));
|
||||
}
|
||||
else
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
}
|
||||
|
||||
void CompilerGLSL::declare_undefined_values()
|
||||
|
|
Загрузка…
Ссылка в новой задаче