mirror of https://github.com/bkaradzic/bgfx
Updated spirv-cross.
This commit is contained in:
parent
e0d515c57a
commit
0790e7b3d6
|
@ -536,6 +536,7 @@ static void print_resources(const Compiler &compiler, const ShaderResources &res
|
|||
print_resources(compiler, "push", res.push_constant_buffers);
|
||||
print_resources(compiler, "counters", res.atomic_counters);
|
||||
print_resources(compiler, "acceleration structures", res.acceleration_structures);
|
||||
print_resources(compiler, "record buffers", res.shader_record_buffers);
|
||||
print_resources(compiler, spv::StorageClassInput, res.builtin_inputs);
|
||||
print_resources(compiler, spv::StorageClassOutput, res.builtin_outputs);
|
||||
}
|
||||
|
@ -612,6 +613,12 @@ struct InterfaceVariableRename
|
|||
string variable_name;
|
||||
};
|
||||
|
||||
struct HLSLVertexAttributeRemapNamed
|
||||
{
|
||||
std::string name;
|
||||
std::string semantic;
|
||||
};
|
||||
|
||||
struct CLIArguments
|
||||
{
|
||||
const char *input = nullptr;
|
||||
|
@ -653,6 +660,7 @@ struct CLIArguments
|
|||
bool msl_enable_frag_stencil_ref_builtin = true;
|
||||
uint32_t msl_enable_frag_output_mask = 0xffffffff;
|
||||
bool msl_enable_clip_distance_user_varying = true;
|
||||
bool msl_raw_buffer_tese_input = false;
|
||||
bool msl_multi_patch_workgroup = false;
|
||||
bool msl_vertex_for_tessellation = false;
|
||||
uint32_t msl_additional_fixed_sample_mask = 0xffffffff;
|
||||
|
@ -690,6 +698,7 @@ struct CLIArguments
|
|||
SmallVector<VariableTypeRemap> variable_type_remaps;
|
||||
SmallVector<InterfaceVariableRename> interface_variable_renames;
|
||||
SmallVector<HLSLVertexAttributeRemap> hlsl_attr_remap;
|
||||
SmallVector<HLSLVertexAttributeRemapNamed> hlsl_attr_remap_named;
|
||||
SmallVector<std::pair<uint32_t, uint32_t>> masked_stage_outputs;
|
||||
SmallVector<BuiltIn> masked_stage_builtins;
|
||||
string entry;
|
||||
|
@ -709,7 +718,12 @@ struct CLIArguments
|
|||
bool msl = false;
|
||||
bool hlsl = false;
|
||||
bool hlsl_compat = false;
|
||||
|
||||
bool hlsl_support_nonzero_base = false;
|
||||
bool hlsl_base_vertex_index_explicit_binding = false;
|
||||
uint32_t hlsl_base_vertex_index_register_index = 0;
|
||||
uint32_t hlsl_base_vertex_index_register_space = 0;
|
||||
|
||||
bool hlsl_force_storage_buffer_as_uav = false;
|
||||
bool hlsl_nonwritable_uav_texture_as_srv = false;
|
||||
bool hlsl_enable_16bit_types = false;
|
||||
|
@ -806,6 +820,7 @@ static void print_help_hlsl()
|
|||
"\t\tPointSize is ignored, and PointCoord returns (0.5, 0.5).\n"
|
||||
"\t[--hlsl-support-nonzero-basevertex-baseinstance]:\n\t\tSupport base vertex and base instance by emitting a special cbuffer declared as:\n"
|
||||
"\t\tcbuffer SPIRV_Cross_VertexInfo { int SPIRV_Cross_BaseVertex; int SPIRV_Cross_BaseInstance; };\n"
|
||||
"\t[--hlsl-basevertex-baseinstance-binding <register index> <register space>]:\n\t\tAssign a fixed binding to SPIRV_Cross_VertexInfo.\n"
|
||||
"\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
|
||||
"\t\tDo not emit any : register(#) bindings for specific resource types, and rely on HLSL compiler to assign something.\n"
|
||||
"\t[--hlsl-force-storage-buffer-as-uav]:\n\t\tAlways emit SSBOs as UAVs, even when marked as read-only.\n"
|
||||
|
@ -816,6 +831,8 @@ static void print_help_hlsl()
|
|||
"\t\tShader must ensure that read/write state is consistent at all call sites.\n"
|
||||
"\t[--set-hlsl-vertex-input-semantic <location> <semantic>]:\n\t\tEmits a specific vertex input semantic for a given location.\n"
|
||||
"\t\tOtherwise, TEXCOORD# is used as semantics, where # is location.\n"
|
||||
"\t[--set-hlsl-named-vertex-input-semantic <name> <semantic>]:\n\t\tEmits a specific vertex input semantic for a given name.\n"
|
||||
"\t\tOpName reflection information must be intact.\n"
|
||||
"\t[--hlsl-enable-16bit-types]:\n\t\tEnables native use of half/int16_t/uint16_t and ByteAddressBuffer interaction with these types. Requires SM 6.2.\n"
|
||||
"\t[--hlsl-flatten-matrix-vertex-input-semantics]:\n\t\tEmits matrix vertex inputs with input semantics as if they were independent vectors, e.g. TEXCOORD{2,3,4} rather than matrix form TEXCOORD2_{0,1,2}.\n"
|
||||
);
|
||||
|
@ -871,20 +888,33 @@ static void print_help_msl()
|
|||
"\t[--msl-disable-frag-stencil-ref-builtin]:\n\t\tDisable FragStencilRef output. Useful if pipeline does not enable stencil output, as pipeline creation might otherwise fail.\n"
|
||||
"\t[--msl-enable-frag-output-mask <mask>]:\n\t\tOnly selectively enable fragment outputs. Useful if pipeline does not enable fragment output for certain locations, as pipeline creation might otherwise fail.\n"
|
||||
"\t[--msl-no-clip-distance-user-varying]:\n\t\tDo not emit user varyings to emulate gl_ClipDistance in fragment shaders.\n"
|
||||
"\t[--msl-add-shader-input <index> <format> <size> <rate>]:\n\t\tSpecify the format of the shader input at <index>.\n"
|
||||
"\t\t<format> can be 'any32', 'any16', 'u16', 'u8', or 'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, "
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader. <rate> can be 'vertex', "
|
||||
"'primitive', or 'patch' to indicate a per-vertex, per-primitive, or per-patch variable.\n"
|
||||
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n"
|
||||
"\t[--msl-add-shader-output <index> <format> <size> <rate>]:\n\t\tSpecify the format of the shader output at <index>.\n"
|
||||
"\t\t<format> can be 'any32', 'any16', 'u16', 'u8', or 'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, "
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader. <rate> can be 'vertex', "
|
||||
"'primitive', or 'patch' to indicate a per-vertex, per-primitive, or per-patch variable.\n"
|
||||
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n"
|
||||
"\t[--msl-shader-input <index> <format> <size>]:\n\t\tSpecify the format of the shader input at <index>.\n"
|
||||
"\t\t<format> can be 'any32', 'any16', 'u16', 'u8', or 'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, "
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader.\n"
|
||||
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n"
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader."
|
||||
"\t\tEquivalent to --msl-add-shader-input with a rate of 'vertex'.\n"
|
||||
"\t[--msl-shader-output <index> <format> <size>]:\n\t\tSpecify the format of the shader output at <index>.\n"
|
||||
"\t\t<format> can be 'any32', 'any16', 'u16', 'u8', or 'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, "
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader.\n"
|
||||
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n"
|
||||
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader."
|
||||
"\t\tEquivalent to --msl-add-shader-output with a rate of 'vertex'.\n"
|
||||
"\t[--msl-raw-buffer-tese-input]:\n\t\tUse raw buffers for tessellation evaluation input.\n"
|
||||
"\t\tThis allows the use of nested structures and arrays.\n"
|
||||
"\t\tIn a future version of SPIRV-Cross, this will become the default.\n"
|
||||
"\t[--msl-multi-patch-workgroup]:\n\t\tUse the new style of tessellation control processing, where multiple patches are processed per workgroup.\n"
|
||||
"\t\tThis should increase throughput by ensuring all the GPU's SIMD lanes are occupied, but it is not compatible with the old style.\n"
|
||||
"\t\tIn addition, this style also passes input variables in buffers directly instead of using vertex attribute processing.\n"
|
||||
"\t\tIn a future version of SPIRV-Cross, this will become the default.\n"
|
||||
"\t\tThis should increase throughput by ensuring all the GPU's SIMD lanes are occupied, but it is not compatible with the old style.\n"
|
||||
"\t\tIn addition, this style also passes input variables in buffers directly instead of using vertex attribute processing.\n"
|
||||
"\t\tIn a future version of SPIRV-Cross, this will become the default.\n"
|
||||
"\t[--msl-vertex-for-tessellation]:\n\t\tWhen handling a vertex shader, marks it as one that will be used with a new-style tessellation control shader.\n"
|
||||
"\t\tThe vertex shader is output to MSL as a compute kernel which outputs vertices to the buffer in the order they are received, rather than in index order as with --msl-capture-output normally.\n"
|
||||
"\t\tThe vertex shader is output to MSL as a compute kernel which outputs vertices to the buffer in the order they are received, rather than in index order as with --msl-capture-output normally.\n"
|
||||
"\t[--msl-additional-fixed-sample-mask <mask>]:\n"
|
||||
"\t\tSet an additional fixed sample mask. If the shader outputs a sample mask, then the final sample mask will be a bitwise AND of the two.\n"
|
||||
"\t[--msl-arrayed-subpass-input]:\n\t\tAssume that images of dimension SubpassData have multiple layers. Layered input attachments are accessed relative to BuiltInLayer.\n"
|
||||
|
@ -1163,6 +1193,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
msl_opts.enable_frag_stencil_ref_builtin = args.msl_enable_frag_stencil_ref_builtin;
|
||||
msl_opts.enable_frag_output_mask = args.msl_enable_frag_output_mask;
|
||||
msl_opts.enable_clip_distance_user_varying = args.msl_enable_clip_distance_user_varying;
|
||||
msl_opts.raw_buffer_tese_input = args.msl_raw_buffer_tese_input;
|
||||
msl_opts.multi_patch_workgroup = args.msl_multi_patch_workgroup;
|
||||
msl_opts.vertex_for_tessellation = args.msl_vertex_for_tessellation;
|
||||
msl_opts.additional_fixed_sample_mask = args.msl_additional_fixed_sample_mask;
|
||||
|
@ -1370,6 +1401,12 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
hlsl_opts.flatten_matrix_vertex_input_semantics = args.hlsl_flatten_matrix_vertex_input_semantics;
|
||||
hlsl->set_hlsl_options(hlsl_opts);
|
||||
hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
|
||||
if (args.hlsl_base_vertex_index_explicit_binding)
|
||||
{
|
||||
hlsl->set_hlsl_aux_buffer_binding(HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE,
|
||||
args.hlsl_base_vertex_index_register_index,
|
||||
args.hlsl_base_vertex_index_register_space);
|
||||
}
|
||||
}
|
||||
|
||||
if (build_dummy_sampler)
|
||||
|
@ -1457,6 +1494,22 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||
{
|
||||
for (auto &remap : args.hlsl_attr_remap)
|
||||
static_cast<CompilerHLSL *>(compiler.get())->add_vertex_attribute_remap(remap);
|
||||
|
||||
for (auto &named_remap : args.hlsl_attr_remap_named)
|
||||
{
|
||||
auto itr = std::find_if(res.stage_inputs.begin(), res.stage_inputs.end(), [&](const Resource &input_res) {
|
||||
return input_res.name == named_remap.name;
|
||||
});
|
||||
|
||||
if (itr != res.stage_inputs.end())
|
||||
{
|
||||
HLSLVertexAttributeRemap remap = {
|
||||
compiler->get_decoration(itr->id, DecorationLocation),
|
||||
named_remap.semantic,
|
||||
};
|
||||
static_cast<CompilerHLSL *>(compiler.get())->add_vertex_attribute_remap(remap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto ret = compiler->compile();
|
||||
|
@ -1532,6 +1585,11 @@ static int main_inner(int argc, char *argv[])
|
|||
cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
|
||||
cbs.add("--hlsl-support-nonzero-basevertex-baseinstance",
|
||||
[&args](CLIParser &) { args.hlsl_support_nonzero_base = true; });
|
||||
cbs.add("--hlsl-basevertex-baseinstance-binding", [&args](CLIParser &parser) {
|
||||
args.hlsl_base_vertex_index_explicit_binding = true;
|
||||
args.hlsl_base_vertex_index_register_index = parser.next_uint();
|
||||
args.hlsl_base_vertex_index_register_space = parser.next_uint();
|
||||
});
|
||||
cbs.add("--hlsl-auto-binding", [&args](CLIParser &parser) {
|
||||
args.hlsl_binding_flags |= hlsl_resource_type_to_flag(parser.next_string());
|
||||
});
|
||||
|
@ -1591,6 +1649,56 @@ static int main_inner(int argc, char *argv[])
|
|||
[&args](CLIParser &parser) { args.msl_enable_frag_output_mask = parser.next_hex_uint(); });
|
||||
cbs.add("--msl-no-clip-distance-user-varying",
|
||||
[&args](CLIParser &) { args.msl_enable_clip_distance_user_varying = false; });
|
||||
cbs.add("--msl-add-shader-input", [&args](CLIParser &parser) {
|
||||
MSLShaderInterfaceVariable input;
|
||||
// Make sure next_uint() is called in-order.
|
||||
input.location = parser.next_uint();
|
||||
const char *format = parser.next_value_string("other");
|
||||
if (strcmp(format, "any32") == 0)
|
||||
input.format = MSL_SHADER_VARIABLE_FORMAT_ANY32;
|
||||
else if (strcmp(format, "any16") == 0)
|
||||
input.format = MSL_SHADER_VARIABLE_FORMAT_ANY16;
|
||||
else if (strcmp(format, "u16") == 0)
|
||||
input.format = MSL_SHADER_VARIABLE_FORMAT_UINT16;
|
||||
else if (strcmp(format, "u8") == 0)
|
||||
input.format = MSL_SHADER_VARIABLE_FORMAT_UINT8;
|
||||
else
|
||||
input.format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
|
||||
input.vecsize = parser.next_uint();
|
||||
const char *rate = parser.next_value_string("vertex");
|
||||
if (strcmp(rate, "primitive") == 0)
|
||||
input.rate = MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE;
|
||||
else if (strcmp(rate, "patch") == 0)
|
||||
input.rate = MSL_SHADER_VARIABLE_RATE_PER_PATCH;
|
||||
else
|
||||
input.rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX;
|
||||
args.msl_shader_inputs.push_back(input);
|
||||
});
|
||||
cbs.add("--msl-add-shader-output", [&args](CLIParser &parser) {
|
||||
MSLShaderInterfaceVariable output;
|
||||
// Make sure next_uint() is called in-order.
|
||||
output.location = parser.next_uint();
|
||||
const char *format = parser.next_value_string("other");
|
||||
if (strcmp(format, "any32") == 0)
|
||||
output.format = MSL_SHADER_VARIABLE_FORMAT_ANY32;
|
||||
else if (strcmp(format, "any16") == 0)
|
||||
output.format = MSL_SHADER_VARIABLE_FORMAT_ANY16;
|
||||
else if (strcmp(format, "u16") == 0)
|
||||
output.format = MSL_SHADER_VARIABLE_FORMAT_UINT16;
|
||||
else if (strcmp(format, "u8") == 0)
|
||||
output.format = MSL_SHADER_VARIABLE_FORMAT_UINT8;
|
||||
else
|
||||
output.format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
|
||||
output.vecsize = parser.next_uint();
|
||||
const char *rate = parser.next_value_string("vertex");
|
||||
if (strcmp(rate, "primitive") == 0)
|
||||
output.rate = MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE;
|
||||
else if (strcmp(rate, "patch") == 0)
|
||||
output.rate = MSL_SHADER_VARIABLE_RATE_PER_PATCH;
|
||||
else
|
||||
output.rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX;
|
||||
args.msl_shader_outputs.push_back(output);
|
||||
});
|
||||
cbs.add("--msl-shader-input", [&args](CLIParser &parser) {
|
||||
MSLShaderInterfaceVariable input;
|
||||
// Make sure next_uint() is called in-order.
|
||||
|
@ -1627,6 +1735,7 @@ static int main_inner(int argc, char *argv[])
|
|||
output.vecsize = parser.next_uint();
|
||||
args.msl_shader_outputs.push_back(output);
|
||||
});
|
||||
cbs.add("--msl-raw-buffer-tese-input", [&args](CLIParser &) { args.msl_raw_buffer_tese_input = true; });
|
||||
cbs.add("--msl-multi-patch-workgroup", [&args](CLIParser &) { args.msl_multi_patch_workgroup = true; });
|
||||
cbs.add("--msl-vertex-for-tessellation", [&args](CLIParser &) { args.msl_vertex_for_tessellation = true; });
|
||||
cbs.add("--msl-additional-fixed-sample-mask",
|
||||
|
@ -1661,6 +1770,12 @@ static int main_inner(int argc, char *argv[])
|
|||
remap.semantic = parser.next_string();
|
||||
args.hlsl_attr_remap.push_back(std::move(remap));
|
||||
});
|
||||
cbs.add("--set-hlsl-named-vertex-input-semantic", [&args](CLIParser &parser) {
|
||||
HLSLVertexAttributeRemapNamed remap;
|
||||
remap.name = parser.next_string();
|
||||
remap.semantic = parser.next_string();
|
||||
args.hlsl_attr_remap_named.push_back(std::move(remap));
|
||||
});
|
||||
|
||||
cbs.add("--remap", [&args](CLIParser &parser) {
|
||||
string src = parser.next_string();
|
||||
|
|
|
@ -991,6 +991,10 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<VariableID> *
|
|||
// in the future.
|
||||
res.push_constant_buffers.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
|
||||
}
|
||||
else if (type.storage == StorageClassShaderRecordBufferKHR)
|
||||
{
|
||||
res.shader_record_buffers.push_back({ var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, ssbo_instance_name) });
|
||||
}
|
||||
// Images
|
||||
else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image &&
|
||||
type.image.sampled == 2)
|
||||
|
@ -2341,6 +2345,11 @@ bool Compiler::is_tessellation_shader() const
|
|||
return is_tessellation_shader(get_execution_model());
|
||||
}
|
||||
|
||||
bool Compiler::is_tessellating_triangles() const
|
||||
{
|
||||
return get_execution_mode_bitset().get(ExecutionModeTriangles);
|
||||
}
|
||||
|
||||
void Compiler::set_remapped_variable_state(VariableID id, bool remap_enable)
|
||||
{
|
||||
get<SPIRVariable>(id).remapped_variable = remap_enable;
|
||||
|
|
|
@ -99,6 +99,8 @@ struct ShaderResources
|
|||
// but keep the vector in case this restriction is lifted in the future.
|
||||
SmallVector<Resource> push_constant_buffers;
|
||||
|
||||
SmallVector<Resource> shader_record_buffers;
|
||||
|
||||
// For Vulkan GLSL and HLSL source,
|
||||
// these correspond to separate texture2D and samplers respectively.
|
||||
SmallVector<Resource> separate_images;
|
||||
|
@ -369,6 +371,7 @@ public:
|
|||
spv::ExecutionModel get_execution_model() const;
|
||||
|
||||
bool is_tessellation_shader() const;
|
||||
bool is_tessellating_triangles() const;
|
||||
|
||||
// In SPIR-V, the compute work group size can be represented by a constant vector, in which case
|
||||
// the LocalSize execution mode is ignored.
|
||||
|
|
|
@ -194,6 +194,7 @@ struct spvc_resources_s : ScratchMemoryAllocation
|
|||
SmallVector<spvc_reflected_resource> sampled_images;
|
||||
SmallVector<spvc_reflected_resource> atomic_counters;
|
||||
SmallVector<spvc_reflected_resource> push_constant_buffers;
|
||||
SmallVector<spvc_reflected_resource> shader_record_buffers;
|
||||
SmallVector<spvc_reflected_resource> separate_images;
|
||||
SmallVector<spvc_reflected_resource> separate_samplers;
|
||||
SmallVector<spvc_reflected_resource> acceleration_structures;
|
||||
|
@ -714,6 +715,14 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
|||
case SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE:
|
||||
options->msl.ios_support_base_vertex_instance = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT:
|
||||
options->msl.raw_buffer_tese_input = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX:
|
||||
options->msl.shader_patch_input_buffer_index = value;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -1173,6 +1182,31 @@ spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spv
|
|||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *si)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInterfaceVariable input;
|
||||
input.location = si->location;
|
||||
input.format = static_cast<MSLShaderVariableFormat>(si->format);
|
||||
input.builtin = static_cast<spv::BuiltIn>(si->builtin);
|
||||
input.vecsize = si->vecsize;
|
||||
input.rate = static_cast<MSLShaderVariableRate>(si->rate);
|
||||
msl.add_msl_shader_input(input);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)si;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, const spvc_msl_shader_interface_var *so)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
|
@ -1197,6 +1231,31 @@ spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, const sp
|
|||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *so)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
if (compiler->backend != SPVC_BACKEND_MSL)
|
||||
{
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
|
||||
MSLShaderInterfaceVariable output;
|
||||
output.location = so->location;
|
||||
output.format = static_cast<MSLShaderVariableFormat>(so->format);
|
||||
output.builtin = static_cast<spv::BuiltIn>(so->builtin);
|
||||
output.vecsize = so->vecsize;
|
||||
output.rate = static_cast<MSLShaderVariableRate>(so->rate);
|
||||
msl.add_msl_shader_output(output);
|
||||
return SPVC_SUCCESS;
|
||||
#else
|
||||
(void)so;
|
||||
compiler->context->report_error("MSL function used on a non-MSL backend.");
|
||||
return SPVC_ERROR_INVALID_ARGUMENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding)
|
||||
{
|
||||
|
@ -1684,6 +1743,8 @@ bool spvc_resources_s::copy_resources(const ShaderResources &resources)
|
|||
return false;
|
||||
if (!copy_resources(push_constant_buffers, resources.push_constant_buffers))
|
||||
return false;
|
||||
if (!copy_resources(shader_record_buffers, resources.shader_record_buffers))
|
||||
return false;
|
||||
if (!copy_resources(separate_images, resources.separate_images))
|
||||
return false;
|
||||
if (!copy_resources(separate_samplers, resources.separate_samplers))
|
||||
|
@ -1837,6 +1898,10 @@ spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources,
|
|||
list = &resources->acceleration_structures;
|
||||
break;
|
||||
|
||||
case SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER:
|
||||
list = &resources->shader_record_buffers;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2580,6 +2645,20 @@ void spvc_msl_shader_input_init(spvc_msl_shader_input *input)
|
|||
spvc_msl_shader_interface_var_init(input);
|
||||
}
|
||||
|
||||
void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
MSLShaderInterfaceVariable var_default;
|
||||
var->location = var_default.location;
|
||||
var->format = static_cast<spvc_msl_shader_variable_format>(var_default.format);
|
||||
var->builtin = static_cast<SpvBuiltIn>(var_default.builtin);
|
||||
var->vecsize = var_default.vecsize;
|
||||
var->rate = static_cast<spvc_msl_shader_variable_rate>(var_default.rate);
|
||||
#else
|
||||
memset(var, 0, sizeof(*var));
|
||||
#endif
|
||||
}
|
||||
|
||||
void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding)
|
||||
{
|
||||
#if SPIRV_CROSS_C_API_MSL
|
||||
|
|
|
@ -40,7 +40,7 @@ extern "C" {
|
|||
/* Bumped if ABI or API breaks backwards compatibility. */
|
||||
#define SPVC_C_API_VERSION_MAJOR 0
|
||||
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
|
||||
#define SPVC_C_API_VERSION_MINOR 49
|
||||
#define SPVC_C_API_VERSION_MINOR 51
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
|
@ -225,6 +225,7 @@ typedef enum spvc_resource_type
|
|||
SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS = 11,
|
||||
SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12,
|
||||
SPVC_RESOURCE_TYPE_RAY_QUERY = 13,
|
||||
SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14,
|
||||
SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff
|
||||
} spvc_resource_type;
|
||||
|
||||
|
@ -335,7 +336,7 @@ typedef struct spvc_msl_vertex_attribute
|
|||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var_2. */
|
||||
typedef struct spvc_msl_shader_interface_var
|
||||
{
|
||||
unsigned location;
|
||||
|
@ -346,13 +347,39 @@ typedef struct spvc_msl_shader_interface_var
|
|||
|
||||
/*
|
||||
* Initializes the shader input struct.
|
||||
* Deprecated. Use spvc_msl_shader_interface_var_init_2().
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var);
|
||||
/*
|
||||
* Deprecated. Use spvc_msl_shader_interface_var_init().
|
||||
* Deprecated. Use spvc_msl_shader_interface_var_init_2().
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_input_init(spvc_msl_shader_input *input);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef enum spvc_msl_shader_variable_rate
|
||||
{
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0,
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1,
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2,
|
||||
|
||||
SPVC_MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff,
|
||||
} spvc_msl_shader_variable_rate;
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_shader_interface_var_2
|
||||
{
|
||||
unsigned location;
|
||||
spvc_msl_shader_variable_format format;
|
||||
SpvBuiltIn builtin;
|
||||
unsigned vecsize;
|
||||
spvc_msl_shader_variable_rate rate;
|
||||
} spvc_msl_shader_interface_var_2;
|
||||
|
||||
/*
|
||||
* Initializes the shader interface variable struct.
|
||||
*/
|
||||
SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var);
|
||||
|
||||
/* Maps to C++ API. */
|
||||
typedef struct spvc_msl_resource_binding
|
||||
{
|
||||
|
@ -689,6 +716,9 @@ typedef enum spvc_compiler_option
|
|||
|
||||
SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS = 78 | SPVC_COMPILER_OPTION_COMMON_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT = 79 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX = 80 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
|
@ -795,10 +825,16 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler
|
|||
const spvc_msl_vertex_attribute *attrs);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler,
|
||||
const spvc_msl_resource_binding *binding);
|
||||
/* Deprecated; use spvc_compiler_msl_add_shader_input_2(). */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var *input);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var_2 *input);
|
||||
/* Deprecated; use spvc_compiler_msl_add_shader_output_2(). */
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var *output);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler,
|
||||
const spvc_msl_shader_interface_var_2 *output);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set);
|
||||
SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address);
|
||||
|
||||
|
|
|
@ -748,6 +748,8 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
|||
case BuiltInSubgroupLeMask:
|
||||
case BuiltInSubgroupGtMask:
|
||||
case BuiltInSubgroupGeMask:
|
||||
case BuiltInBaseVertex:
|
||||
case BuiltInBaseInstance:
|
||||
// Handled specially.
|
||||
break;
|
||||
|
||||
|
@ -1032,8 +1034,6 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
Bitset builtins = active_input_builtins;
|
||||
builtins.merge_or(active_output_builtins);
|
||||
|
||||
bool need_base_vertex_info = false;
|
||||
|
||||
std::unordered_map<uint32_t, ID> builtin_to_initializer;
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
|
||||
if (!is_builtin_variable(var) || var.storage != StorageClassOutput || !var.initializer)
|
||||
|
@ -1087,7 +1087,13 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
case BuiltInInstanceIndex:
|
||||
type = "int";
|
||||
if (hlsl_options.support_nonzero_base_vertex_base_instance)
|
||||
need_base_vertex_info = true;
|
||||
base_vertex_info.used = true;
|
||||
break;
|
||||
|
||||
case BuiltInBaseVertex:
|
||||
case BuiltInBaseInstance:
|
||||
type = "int";
|
||||
base_vertex_info.used = true;
|
||||
break;
|
||||
|
||||
case BuiltInInstanceId:
|
||||
|
@ -1187,9 +1193,17 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
}
|
||||
});
|
||||
|
||||
if (need_base_vertex_info)
|
||||
if (base_vertex_info.used)
|
||||
{
|
||||
statement("cbuffer SPIRV_Cross_VertexInfo");
|
||||
string binding_info;
|
||||
if (base_vertex_info.explicit_binding)
|
||||
{
|
||||
binding_info = join(" : register(b", base_vertex_info.register_index);
|
||||
if (base_vertex_info.register_space)
|
||||
binding_info += join(", space", base_vertex_info.register_space);
|
||||
binding_info += ")";
|
||||
}
|
||||
statement("cbuffer SPIRV_Cross_VertexInfo", binding_info);
|
||||
begin_scope();
|
||||
statement("int SPIRV_Cross_BaseVertex;");
|
||||
statement("int SPIRV_Cross_BaseInstance;");
|
||||
|
@ -1198,6 +1212,30 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space)
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
{
|
||||
base_vertex_info.explicit_binding = true;
|
||||
base_vertex_info.register_space = register_space;
|
||||
base_vertex_info.register_index = register_index;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding)
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
base_vertex_info.explicit_binding = false;
|
||||
}
|
||||
|
||||
bool CompilerHLSL::is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
return base_vertex_info.used;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_composite_constants()
|
||||
{
|
||||
// HLSL cannot declare structs or arrays inline, so we must move them out to
|
||||
|
@ -2612,6 +2650,14 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||
statement(builtin, " = int(stage_input.", builtin, ");");
|
||||
break;
|
||||
|
||||
case BuiltInBaseVertex:
|
||||
statement(builtin, " = SPIRV_Cross_BaseVertex;");
|
||||
break;
|
||||
|
||||
case BuiltInBaseInstance:
|
||||
statement(builtin, " = SPIRV_Cross_BaseInstance;");
|
||||
break;
|
||||
|
||||
case BuiltInInstanceId:
|
||||
// D3D semantics are uint, but shader wants int.
|
||||
statement(builtin, " = int(stage_input.", builtin, ");");
|
||||
|
|
|
@ -98,6 +98,11 @@ struct HLSLResourceBinding
|
|||
} cbv, uav, srv, sampler;
|
||||
};
|
||||
|
||||
enum HLSLAuxBinding
|
||||
{
|
||||
HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0
|
||||
};
|
||||
|
||||
class CompilerHLSL : public CompilerGLSL
|
||||
{
|
||||
public:
|
||||
|
@ -211,6 +216,11 @@ public:
|
|||
// Controls which storage buffer bindings will be forced to be declared as UAVs.
|
||||
void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding);
|
||||
|
||||
// By default, these magic buffers are not assigned a specific binding.
|
||||
void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space);
|
||||
void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding);
|
||||
bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const;
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
|
||||
|
@ -373,6 +383,14 @@ private:
|
|||
|
||||
std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t register_index = 0;
|
||||
uint32_t register_space = 0;
|
||||
bool explicit_binding = false;
|
||||
bool used = false;
|
||||
} base_vertex_info;
|
||||
|
||||
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL.
|
||||
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,17 @@ enum MSLShaderVariableFormat
|
|||
MSL_SHADER_VARIABLE_FORMAT_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
// Indicates the rate at which a variable changes value, one of: per-vertex,
|
||||
// per-primitive, or per-patch.
|
||||
enum MSLShaderVariableRate
|
||||
{
|
||||
MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0,
|
||||
MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1,
|
||||
MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2,
|
||||
|
||||
MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff,
|
||||
};
|
||||
|
||||
// Defines MSL characteristics of a shader interface variable at a particular location.
|
||||
// After compilation, it is possible to query whether or not this location was used.
|
||||
// If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader,
|
||||
|
@ -69,6 +80,7 @@ struct MSLShaderInterfaceVariable
|
|||
MSLShaderVariableFormat format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
|
||||
spv::BuiltIn builtin = spv::BuiltInMax;
|
||||
uint32_t vecsize = 0;
|
||||
MSLShaderVariableRate rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX;
|
||||
};
|
||||
|
||||
// Matches the binding index of a MSL resource for a binding within a descriptor set.
|
||||
|
@ -306,6 +318,7 @@ public:
|
|||
uint32_t dynamic_offsets_buffer_index = 23;
|
||||
uint32_t shader_input_buffer_index = 22;
|
||||
uint32_t shader_index_buffer_index = 21;
|
||||
uint32_t shader_patch_input_buffer_index = 20;
|
||||
uint32_t shader_input_wg_index = 0;
|
||||
uint32_t device_index = 0;
|
||||
uint32_t enable_frag_output_mask = 0xffffffff;
|
||||
|
@ -387,6 +400,11 @@ public:
|
|||
// builtins are processed, but should result in more efficient usage of the GPU.
|
||||
bool multi_patch_workgroup = false;
|
||||
|
||||
// Use storage buffers instead of vertex-style attributes for tessellation evaluation
|
||||
// input. This may require conversion of inputs in the generated post-tessellation
|
||||
// vertex shader, but allows the use of nested arrays.
|
||||
bool raw_buffer_tese_input = false;
|
||||
|
||||
// If set, a vertex shader will be compiled as part of a tessellation pipeline.
|
||||
// It will be translated as a compute kernel, so it can use the global invocation ID
|
||||
// to index the output buffer.
|
||||
|
@ -504,6 +522,11 @@ public:
|
|||
return !buffers_requiring_array_length.empty();
|
||||
}
|
||||
|
||||
bool buffer_requires_array_length(VariableID id) const
|
||||
{
|
||||
return buffers_requiring_array_length.count(id) != 0;
|
||||
}
|
||||
|
||||
// Provide feedback to calling API to allow it to pass a buffer
|
||||
// containing the view mask for the current multiview subpass.
|
||||
bool needs_view_mask_buffer() const
|
||||
|
@ -815,6 +838,9 @@ protected:
|
|||
std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, uint32_t physical_type_id,
|
||||
bool is_packed) override;
|
||||
|
||||
bool is_tesc_shader() const;
|
||||
bool is_tese_shader() const;
|
||||
|
||||
void preprocess_op_codes();
|
||||
void localize_global_variables();
|
||||
void extract_global_variables_from_functions();
|
||||
|
@ -871,6 +897,7 @@ protected:
|
|||
const std::string &var_chain_qual,
|
||||
uint32_t &location, uint32_t &var_mbr_idx);
|
||||
void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var);
|
||||
void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var);
|
||||
|
||||
void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id);
|
||||
|
||||
|
@ -953,7 +980,7 @@ protected:
|
|||
bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const;
|
||||
std::string get_argument_address_space(const SPIRVariable &argument);
|
||||
std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false);
|
||||
const char *to_restrict(uint32_t id, bool space = true);
|
||||
const char *to_restrict(uint32_t id, bool space);
|
||||
SPIRType &get_stage_in_struct_type();
|
||||
SPIRType &get_stage_out_struct_type();
|
||||
SPIRType &get_patch_stage_in_struct_type();
|
||||
|
@ -1058,6 +1085,8 @@ protected:
|
|||
VariableID patch_stage_out_var_id = 0;
|
||||
VariableID stage_in_ptr_var_id = 0;
|
||||
VariableID stage_out_ptr_var_id = 0;
|
||||
VariableID tess_level_inner_var_id = 0;
|
||||
VariableID tess_level_outer_var_id = 0;
|
||||
VariableID stage_out_masked_builtin_type_id = 0;
|
||||
|
||||
// Handle HLSL-style 0-based vertex/instance index.
|
||||
|
@ -1096,6 +1125,7 @@ protected:
|
|||
std::string input_wg_var_name = "gl_in";
|
||||
std::string input_buffer_var_name = "spvIn";
|
||||
std::string output_buffer_var_name = "spvOut";
|
||||
std::string patch_input_buffer_var_name = "spvPatchIn";
|
||||
std::string patch_output_buffer_var_name = "spvPatchOut";
|
||||
std::string tess_factor_buffer_var_name = "spvTessLevel";
|
||||
std::string index_buffer_var_name = "spvIndices";
|
||||
|
|
Loading…
Reference in New Issue