Merge branch 'master' of https://github.com/KhronosGroup/SPIRV-Cross
This commit is contained in:
commit
5f42746389
@ -173,6 +173,12 @@ You can make use of the reflection interface to force the name of the struct typ
|
||||
compiler.set_name(varying_resource.base_type_id, "VertexFragmentLinkage");
|
||||
```
|
||||
|
||||
Some platform may require identical variable name for both vertex outputs and fragment inputs. (for example MacOSX)
|
||||
to rename varaible base on location, please add
|
||||
```
|
||||
--rename-interface-variable <in|out> <location> <new_variable_name>
|
||||
```
|
||||
|
||||
#### HLSL source to legacy GLSL/ESSL
|
||||
|
||||
HLSL tends to emit varying struct types to pass data between vertex and fragment.
|
||||
|
53
main.cpp
53
main.cpp
@ -417,6 +417,13 @@ struct VariableTypeRemap
|
||||
string new_variable_type;
|
||||
};
|
||||
|
||||
struct InterfaceVariableRename
|
||||
{
|
||||
StorageClass storageClass;
|
||||
uint32_t location;
|
||||
string variable_name;
|
||||
};
|
||||
|
||||
struct CLIArguments
|
||||
{
|
||||
const char *input = nullptr;
|
||||
@ -438,6 +445,7 @@ struct CLIArguments
|
||||
vector<Remap> remaps;
|
||||
vector<string> extensions;
|
||||
vector<VariableTypeRemap> variable_type_remaps;
|
||||
vector<InterfaceVariableRename> interface_variable_renames;
|
||||
string entry;
|
||||
|
||||
uint32_t iterations = 1;
|
||||
@ -463,7 +471,9 @@ static void print_help()
|
||||
"[--pls-in format input-name] [--pls-out format output-name] [--remap source_name target_name "
|
||||
"components] [--extension ext] [--entry name] [--remove-unused-variables] "
|
||||
"[--flatten-multidimensional-arrays] "
|
||||
"[--remap-variable-type <variable_name> <new_variable_type>]\n");
|
||||
"[--remap-variable-type <variable_name> <new_variable_type>] "
|
||||
"[--rename-interface-variable <in|out> <location> <new_variable_name>] "
|
||||
"\n");
|
||||
}
|
||||
|
||||
static bool remap_generic(Compiler &compiler, const vector<Resource> &resources, const Remap &remap)
|
||||
@ -550,6 +560,21 @@ static PlsFormat pls_format(const char *str)
|
||||
return PlsNone;
|
||||
}
|
||||
|
||||
void rename_interface_variable(Compiler &compiler, const vector<Resource> &resources, const InterfaceVariableRename &rename)
|
||||
{
|
||||
for (auto &v : resources)
|
||||
{
|
||||
if (!compiler.has_decoration(v.id, spv::DecorationLocation))
|
||||
continue;
|
||||
|
||||
auto loc = compiler.get_decoration(v.id, spv::DecorationLocation);
|
||||
if (loc != rename.location)
|
||||
continue;
|
||||
|
||||
compiler.set_name(v.id, rename.variable_name);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CLIArguments args;
|
||||
@ -602,6 +627,19 @@ int main(int argc, char *argv[])
|
||||
args.variable_type_remaps.push_back({ move(var_name), move(new_type) });
|
||||
});
|
||||
|
||||
cbs.add("--rename-interface-variable", [&args](CLIParser &parser) {
|
||||
StorageClass cls = StorageClassMax;
|
||||
string clsStr = parser.next_string();
|
||||
if (clsStr == "in")
|
||||
cls = StorageClassInput;
|
||||
else if (clsStr == "out")
|
||||
cls = StorageClassOutput;
|
||||
|
||||
uint32_t loc = parser.next_uint();
|
||||
string var_name = parser.next_string();
|
||||
args.interface_variable_renames.push_back({ cls, loc, move(var_name) });
|
||||
});
|
||||
|
||||
cbs.add("--pls-in", [&args](CLIParser &parser) {
|
||||
auto fmt = pls_format(parser.next_string());
|
||||
auto name = parser.next_string();
|
||||
@ -758,6 +796,19 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &rename : args.interface_variable_renames)
|
||||
{
|
||||
if (rename.storageClass == StorageClassInput)
|
||||
rename_interface_variable(*compiler, res.stage_inputs, rename);
|
||||
else if (rename.storageClass == StorageClassOutput)
|
||||
rename_interface_variable(*compiler, res.stage_outputs, rename);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "error at --rename-interface-variable <in|out> ...\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.dump_resources)
|
||||
{
|
||||
print_resources(*compiler, res);
|
||||
|
51
reference/shaders-hlsl/frag/constant-buffer-array.frag
Normal file
51
reference/shaders-hlsl/frag/constant-buffer-array.frag
Normal file
@ -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;
|
||||
}
|
45
reference/shaders-hlsl/frag/constant-buffer-array.sm51.frag
Normal file
45
reference/shaders-hlsl/frag/constant-buffer-array.sm51.frag
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
16
reference/shaders/frag/sampler-proj.frag
Normal file
16
reference/shaders/frag/sampler-proj.frag
Normal file
@ -0,0 +1,16 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(binding = 0) uniform mediump sampler2D uTex;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) in vec4 vTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
highp vec4 _19 = vTex;
|
||||
_19.z = vTex.w;
|
||||
FragColor = textureProj(uTex, _19.xyz);
|
||||
}
|
||||
|
32
shaders-hlsl/frag/constant-buffer-array.frag
Normal file
32
shaders-hlsl/frag/constant-buffer-array.frag
Normal file
@ -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;
|
||||
}
|
||||
|
32
shaders-hlsl/frag/constant-buffer-array.sm51.frag
Normal file
32
shaders-hlsl/frag/constant-buffer-array.sm51.frag
Normal file
@ -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;
|
||||
}
|
||||
|
12
shaders/frag/sampler-proj.frag
Normal file
12
shaders/frag/sampler-proj.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(location = 0) in vec4 vTex;
|
||||
layout(binding = 0) uniform sampler2D uTex;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = textureProj(uTex, vTex);
|
||||
}
|
||||
|
@ -394,9 +394,6 @@ struct SPIRExpression : IVariant
|
||||
// it is assumed that this is true almost always.
|
||||
bool immutable = false;
|
||||
|
||||
// If this expression has been used while invalidated.
|
||||
bool used_while_invalidated = false;
|
||||
|
||||
// Before use, this expression must be transposed.
|
||||
// This is needed for targets which don't support row_major layouts.
|
||||
bool need_transpose = false;
|
||||
|
@ -1194,6 +1194,7 @@ void Compiler::parse(const Instruction &instruction)
|
||||
case OpSourceExtension:
|
||||
case OpNop:
|
||||
case OpLine:
|
||||
case OpString:
|
||||
break;
|
||||
|
||||
case OpSource:
|
||||
|
@ -1327,28 +1327,28 @@ void CompilerGLSL::replace_illegal_names()
|
||||
{
|
||||
// clang-format off
|
||||
static const unordered_set<string> keywords = {
|
||||
"active", "asm", "atomic_uint", "attribute", "bool", "break",
|
||||
"bvec2", "bvec3", "bvec4", "case", "cast", "centroid", "class", "coherent", "common", "const", "continue", "default", "discard",
|
||||
"dmat2", "dmat2x2", "dmat2x3", "dmat2x4", "dmat3", "dmat3x2", "dmat3x3", "dmat3x4", "dmat4", "dmat4x2", "dmat4x3", "dmat4x4",
|
||||
"do", "double", "dvec2", "dvec3", "dvec4", "else", "enum", "extern", "external", "false", "filter", "fixed", "flat", "float",
|
||||
"for", "fvec2", "fvec3", "fvec4", "goto", "half", "highp", "hvec2", "hvec3", "hvec4", "if", "iimage1D", "iimage1DArray",
|
||||
"iimage2D", "iimage2DArray", "iimage2DMS", "iimage2DMSArray", "iimage2DRect", "iimage3D", "iimageBuffer", "iimageCube",
|
||||
"iimageCubeArray", "image1D", "image1DArray", "image2D", "image2DArray", "image2DMS", "image2DMSArray", "image2DRect",
|
||||
"image3D", "imageBuffer", "imageCube", "imageCubeArray", "in", "inline", "inout", "input", "int", "interface", "invariant",
|
||||
"isampler1D", "isampler1DArray", "isampler2D", "isampler2DArray", "isampler2DMS", "isampler2DMSArray", "isampler2DRect",
|
||||
"isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", "ivec2", "ivec3", "ivec4", "layout", "long", "lowp",
|
||||
"mat2", "mat2x2", "mat2x3", "mat2x4", "mat3", "mat3x2", "mat3x3", "mat3x4", "mat4", "mat4x2", "mat4x3", "mat4x4", "mediump",
|
||||
"namespace", "noinline", "noperspective", "out", "output", "packed", "partition", "patch", "precision", "public", "readonly",
|
||||
"resource", "restrict", "return", "row_major", "sample", "sampler1D", "sampler1DArray", "sampler1DArrayShadow",
|
||||
"sampler1DShadow", "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DMS", "sampler2DMSArray",
|
||||
"sampler2DRect", "sampler2DRectShadow", "sampler2DShadow", "sampler3D", "sampler3DRect", "samplerBuffer",
|
||||
"samplerCube", "samplerCubeArray", "samplerCubeArrayShadow", "samplerCubeShadow", "short", "sizeof", "smooth", "static",
|
||||
"struct", "subroutine", "superp", "switch", "template", "this", "true", "typedef", "uimage1D", "uimage1DArray", "uimage2D",
|
||||
"uimage2DArray", "uimage2DMS", "uimage2DMSArray", "uimage2DRect", "uimage3D", "uimageBuffer", "uimageCube",
|
||||
"uimageCubeArray", "uint", "uniform", "union", "unsigned", "usampler1D", "usampler1DArray", "usampler2D", "usampler2DArray",
|
||||
"usampler2DMS", "usampler2DMSArray", "usampler2DRect", "usampler3D", "usamplerBuffer", "usamplerCube",
|
||||
"usamplerCubeArray", "using", "uvec2", "uvec3", "uvec4", "varying", "vec2", "vec3", "vec4", "void", "volatile", "volatile",
|
||||
"while", "writeonly"
|
||||
"active", "asm", "atomic_uint", "attribute", "bool", "break",
|
||||
"bvec2", "bvec3", "bvec4", "case", "cast", "centroid", "class", "coherent", "common", "const", "continue", "default", "discard",
|
||||
"dmat2", "dmat2x2", "dmat2x3", "dmat2x4", "dmat3", "dmat3x2", "dmat3x3", "dmat3x4", "dmat4", "dmat4x2", "dmat4x3", "dmat4x4",
|
||||
"do", "double", "dvec2", "dvec3", "dvec4", "else", "enum", "extern", "external", "false", "filter", "fixed", "flat", "float",
|
||||
"for", "fvec2", "fvec3", "fvec4", "goto", "half", "highp", "hvec2", "hvec3", "hvec4", "if", "iimage1D", "iimage1DArray",
|
||||
"iimage2D", "iimage2DArray", "iimage2DMS", "iimage2DMSArray", "iimage2DRect", "iimage3D", "iimageBuffer", "iimageCube",
|
||||
"iimageCubeArray", "image1D", "image1DArray", "image2D", "image2DArray", "image2DMS", "image2DMSArray", "image2DRect",
|
||||
"image3D", "imageBuffer", "imageCube", "imageCubeArray", "in", "inline", "inout", "input", "int", "interface", "invariant",
|
||||
"isampler1D", "isampler1DArray", "isampler2D", "isampler2DArray", "isampler2DMS", "isampler2DMSArray", "isampler2DRect",
|
||||
"isampler3D", "isamplerBuffer", "isamplerCube", "isamplerCubeArray", "ivec2", "ivec3", "ivec4", "layout", "long", "lowp",
|
||||
"mat2", "mat2x2", "mat2x3", "mat2x4", "mat3", "mat3x2", "mat3x3", "mat3x4", "mat4", "mat4x2", "mat4x3", "mat4x4", "mediump",
|
||||
"namespace", "noinline", "noperspective", "out", "output", "packed", "partition", "patch", "precision", "public", "readonly",
|
||||
"resource", "restrict", "return", "row_major", "sample", "sampler1D", "sampler1DArray", "sampler1DArrayShadow",
|
||||
"sampler1DShadow", "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DMS", "sampler2DMSArray",
|
||||
"sampler2DRect", "sampler2DRectShadow", "sampler2DShadow", "sampler3D", "sampler3DRect", "samplerBuffer",
|
||||
"samplerCube", "samplerCubeArray", "samplerCubeArrayShadow", "samplerCubeShadow", "short", "sizeof", "smooth", "static",
|
||||
"struct", "subroutine", "superp", "switch", "template", "this", "true", "typedef", "uimage1D", "uimage1DArray", "uimage2D",
|
||||
"uimage2DArray", "uimage2DMS", "uimage2DMSArray", "uimage2DRect", "uimage3D", "uimageBuffer", "uimageCube",
|
||||
"uimageCubeArray", "uint", "uniform", "union", "unsigned", "usampler1D", "usampler1DArray", "usampler2D", "usampler2DArray",
|
||||
"usampler2DMS", "usampler2DMSArray", "usampler2DRect", "usampler3D", "usamplerBuffer", "usamplerCube",
|
||||
"usamplerCubeArray", "using", "uvec2", "uvec3", "uvec4", "varying", "vec2", "vec3", "vec4", "void", "volatile", "volatile",
|
||||
"while", "writeonly", "texture"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@ -1768,13 +1768,6 @@ string CompilerGLSL::to_func_call_arg(uint32_t id)
|
||||
|
||||
void CompilerGLSL::handle_invalid_expression(uint32_t id)
|
||||
{
|
||||
auto &expr = get<SPIRExpression>(id);
|
||||
|
||||
// This expression has been invalidated in the past.
|
||||
// Be careful with this expression next pass ...
|
||||
// Used for OpCompositeInsert forwarding atm.
|
||||
expr.used_while_invalidated = true;
|
||||
|
||||
// We tried to read an invalidated expression.
|
||||
// This means we need another pass at compilation, but next time, force temporary variables so that they cannot be invalidated.
|
||||
forced_temporaries.insert(id);
|
||||
@ -4477,18 +4470,13 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
auto lhs = to_expression(ops[0]);
|
||||
auto rhs = to_expression(ops[1]);
|
||||
|
||||
// It is possible with OpLoad/OpCompositeInsert/OpStore that we get <expr> = <same-expr>.
|
||||
// For this case, we don't need to invalidate anything and emit any opcode.
|
||||
if (lhs != rhs)
|
||||
{
|
||||
// Tries to optimize assignments like "<lhs> = <lhs> op expr".
|
||||
// While this is purely cosmetic, this is important for legacy ESSL where loop
|
||||
// variable increments must be in either i++ or i += const-expr.
|
||||
// Without this, we end up with i = i + 1, which is correct GLSL, but not correct GLES 2.0.
|
||||
if (!optimize_read_modify_write(lhs, rhs))
|
||||
statement(lhs, " = ", rhs, ";");
|
||||
register_write(ops[0]);
|
||||
}
|
||||
// Tries to optimize assignments like "<lhs> = <lhs> op expr".
|
||||
// While this is purely cosmetic, this is important for legacy ESSL where loop
|
||||
// variable increments must be in either i++ or i += const-expr.
|
||||
// Without this, we end up with i = i + 1, which is correct GLSL, but not correct GLES 2.0.
|
||||
if (!optimize_read_modify_write(lhs, rhs))
|
||||
statement(lhs, " = ", rhs, ";");
|
||||
register_write(ops[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4732,26 +4720,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
flush_variable_declaration(composite);
|
||||
|
||||
auto *expr = maybe_get<SPIRExpression>(id);
|
||||
if ((expr && expr->used_while_invalidated) || !should_forward(composite))
|
||||
{
|
||||
// Make a copy, then use access chain to store the variable.
|
||||
statement(declare_temporary(result_type, id), to_expression(composite), ";");
|
||||
set<SPIRExpression>(id, to_name(id), result_type, true);
|
||||
auto chain = access_chain_internal(id, elems, length, true);
|
||||
statement(chain, " = ", to_expression(obj), ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto chain = access_chain_internal(composite, elems, length, true);
|
||||
statement(chain, " = ", to_expression(obj), ";");
|
||||
set<SPIRExpression>(id, to_expression(composite), result_type, true);
|
||||
// Make a copy, then use access chain to store the variable.
|
||||
statement(declare_temporary(result_type, id), to_expression(composite), ";");
|
||||
set<SPIRExpression>(id, to_name(id), result_type, true);
|
||||
auto chain = access_chain_internal(id, elems, length, true);
|
||||
statement(chain, " = ", to_expression(obj), ";");
|
||||
|
||||
register_write(composite);
|
||||
register_read(id, composite, true);
|
||||
// Invalidate the old expression we inserted into.
|
||||
invalid_expressions.insert(composite);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -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,10 +1603,20 @@ 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
|
||||
{
|
||||
if (options.shader_model >= 51)
|
||||
space = "b"; // Constant buffers
|
||||
else
|
||||
space = "c"; // Constant buffers
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user