Merge pull request #417 from msiglreith/root_constants_overwrite
hlsl: Support custom root constant layout
This commit is contained in:
Коммит
ed6b7755cd
|
@ -1040,7 +1040,8 @@ uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, uint64_t flags,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing)
|
bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing,
|
||||||
|
uint32_t start_offset, uint32_t end_offset)
|
||||||
{
|
{
|
||||||
// This is very tricky and error prone, but try to be exhaustive and correct here.
|
// This is very tricky and error prone, but try to be exhaustive and correct here.
|
||||||
// SPIR-V doesn't directly say if we're using std430 or std140.
|
// SPIR-V doesn't directly say if we're using std430 or std140.
|
||||||
|
@ -1079,6 +1080,10 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||||
uint32_t alignment = max(packed_alignment, pad_alignment);
|
uint32_t alignment = max(packed_alignment, pad_alignment);
|
||||||
offset = (offset + alignment - 1) & ~(alignment - 1);
|
offset = (offset + alignment - 1) & ~(alignment - 1);
|
||||||
|
|
||||||
|
// Field is not in the specified range anymore and we can ignore any further fields.
|
||||||
|
if (offset >= end_offset)
|
||||||
|
break;
|
||||||
|
|
||||||
// The next member following a struct member is aligned to the base alignment of the struct that came before.
|
// The next member following a struct member is aligned to the base alignment of the struct that came before.
|
||||||
// GL 4.5 spec, 7.6.2.2.
|
// GL 4.5 spec, 7.6.2.2.
|
||||||
if (memb_type.basetype == SPIRType::Struct)
|
if (memb_type.basetype == SPIRType::Struct)
|
||||||
|
@ -1086,6 +1091,9 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||||
else
|
else
|
||||||
pad_alignment = 1;
|
pad_alignment = 1;
|
||||||
|
|
||||||
|
// Only care about packing if we are in the given range
|
||||||
|
if (offset >= start_offset)
|
||||||
|
{
|
||||||
// We only care about offsets in std140, std430, etc ...
|
// We only care about offsets in std140, std430, etc ...
|
||||||
// For EnhancedLayout variants, we have the flexibility to choose our own offsets.
|
// For EnhancedLayout variants, we have the flexibility to choose our own offsets.
|
||||||
if (!packing_has_flexible_offset(packing))
|
if (!packing_has_flexible_offset(packing))
|
||||||
|
@ -1096,8 +1104,8 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify array stride rules.
|
// Verify array stride rules.
|
||||||
if (!memb_type.array.empty() &&
|
if (!memb_type.array.empty() && type_to_packed_array_stride(memb_type, member_flags, packing) !=
|
||||||
type_to_packed_array_stride(memb_type, member_flags, packing) != type_struct_member_array_stride(type, i))
|
type_struct_member_array_stride(type, i))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Verify that sub-structs also follow packing rules.
|
// Verify that sub-structs also follow packing rules.
|
||||||
|
@ -1106,6 +1114,7 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||||
|
|
||||||
if (!memb_type.member_types.empty() && !buffer_is_packing_standard(memb_type, substruct_packing))
|
if (!memb_type.member_types.empty() && !buffer_is_packing_standard(memb_type, substruct_packing))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Bump size.
|
// Bump size.
|
||||||
offset += packed_size;
|
offset += packed_size;
|
||||||
|
@ -7066,7 +7075,7 @@ string CompilerGLSL::variable_decl(const SPIRType &type, const string &name, uin
|
||||||
// Emit a structure member. Subclasses may override to modify output,
|
// Emit a structure member. Subclasses may override to modify output,
|
||||||
// or to dynamically add a padding member if needed.
|
// or to dynamically add a padding member if needed.
|
||||||
void CompilerGLSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
void CompilerGLSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||||
const string &qualifier)
|
const string &qualifier, uint32_t)
|
||||||
{
|
{
|
||||||
auto &membertype = get<SPIRType>(member_type_id);
|
auto &membertype = get<SPIRType>(member_type_id);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define SPIRV_CROSS_GLSL_HPP
|
#define SPIRV_CROSS_GLSL_HPP
|
||||||
|
|
||||||
#include "spirv_cross.hpp"
|
#include "spirv_cross.hpp"
|
||||||
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
@ -202,7 +203,7 @@ protected:
|
||||||
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
||||||
virtual std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage);
|
virtual std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage);
|
||||||
virtual void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
virtual void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||||
const std::string &qualifier = "");
|
const std::string &qualifier = "", uint32_t base_offset = 0);
|
||||||
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);
|
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);
|
||||||
virtual std::string constant_expression(const SPIRConstant &c);
|
virtual std::string constant_expression(const SPIRConstant &c);
|
||||||
std::string constant_op_expression(const SPIRConstantOp &cop);
|
std::string constant_op_expression(const SPIRConstantOp &cop);
|
||||||
|
@ -424,7 +425,8 @@ protected:
|
||||||
std::string to_combined_image_sampler(uint32_t image_id, uint32_t samp_id);
|
std::string to_combined_image_sampler(uint32_t image_id, uint32_t samp_id);
|
||||||
virtual bool skip_argument(uint32_t id) const;
|
virtual bool skip_argument(uint32_t id) const;
|
||||||
|
|
||||||
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing);
|
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing, uint32_t start_offset = 0,
|
||||||
|
uint32_t end_offset = std::numeric_limits<uint32_t>::max());
|
||||||
uint32_t type_to_packed_base_size(const SPIRType &type, BufferPackingStandard packing);
|
uint32_t type_to_packed_base_size(const SPIRType &type, BufferPackingStandard packing);
|
||||||
uint32_t type_to_packed_alignment(const SPIRType &type, uint64_t flags, BufferPackingStandard packing);
|
uint32_t type_to_packed_alignment(const SPIRType &type, uint64_t flags, BufferPackingStandard packing);
|
||||||
uint32_t type_to_packed_array_stride(const SPIRType &type, uint64_t flags, BufferPackingStandard packing);
|
uint32_t type_to_packed_array_stride(const SPIRType &type, uint64_t flags, BufferPackingStandard packing);
|
||||||
|
|
102
spirv_hlsl.cpp
102
spirv_hlsl.cpp
|
@ -779,7 +779,8 @@ std::string CompilerHLSL::builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClas
|
||||||
case BuiltInNumWorkgroups:
|
case BuiltInNumWorkgroups:
|
||||||
{
|
{
|
||||||
if (!num_workgroups_builtin)
|
if (!num_workgroups_builtin)
|
||||||
SPIRV_CROSS_THROW("NumWorkgroups builtin is used, but remap_num_workgroups_builtin() was not called. Cannot emit code for this builtin.");
|
SPIRV_CROSS_THROW("NumWorkgroups builtin is used, but remap_num_workgroups_builtin() was not called. "
|
||||||
|
"Cannot emit code for this builtin.");
|
||||||
|
|
||||||
auto &var = get<SPIRVariable>(num_workgroups_builtin);
|
auto &var = get<SPIRVariable>(num_workgroups_builtin);
|
||||||
auto &type = get<SPIRType>(var.basetype);
|
auto &type = get<SPIRType>(var.basetype);
|
||||||
|
@ -1459,7 +1460,7 @@ string CompilerHLSL::layout_for_member(const SPIRType &type, uint32_t index)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||||
const string &qualifier)
|
const string &qualifier, uint32_t base_offset)
|
||||||
{
|
{
|
||||||
auto &membertype = get<SPIRType>(member_type_id);
|
auto &membertype = get<SPIRType>(member_type_id);
|
||||||
|
|
||||||
|
@ -1475,9 +1476,12 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type
|
||||||
qualifiers = to_interpolation_qualifiers(memberflags);
|
qualifiers = to_interpolation_qualifiers(memberflags);
|
||||||
|
|
||||||
string packing_offset;
|
string packing_offset;
|
||||||
if (has_decoration(type.self, DecorationCPacked) && has_member_decoration(type.self, index, DecorationOffset))
|
bool is_push_constant = type.storage == StorageClassPushConstant;
|
||||||
|
|
||||||
|
if ((has_decoration(type.self, DecorationCPacked) || is_push_constant) &&
|
||||||
|
has_member_decoration(type.self, index, DecorationOffset))
|
||||||
{
|
{
|
||||||
uint32_t offset = memb[index].offset;
|
uint32_t offset = memb[index].offset - base_offset;
|
||||||
if (offset & 3)
|
if (offset & 3)
|
||||||
SPIRV_CROSS_THROW("Cannot pack on tighter bounds than 4 bytes in HLSL.");
|
SPIRV_CROSS_THROW("Cannot pack on tighter bounds than 4 bytes in HLSL.");
|
||||||
|
|
||||||
|
@ -1557,7 +1561,58 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
|
||||||
|
|
||||||
void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
|
void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
|
||||||
{
|
{
|
||||||
|
if (root_constants_layout.empty())
|
||||||
|
{
|
||||||
emit_buffer_block(var);
|
emit_buffer_block(var);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto &layout : root_constants_layout)
|
||||||
|
{
|
||||||
|
auto &type = get<SPIRType>(var.basetype);
|
||||||
|
|
||||||
|
if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset, layout.start, layout.end))
|
||||||
|
set_decoration(type.self, DecorationCPacked);
|
||||||
|
else
|
||||||
|
SPIRV_CROSS_THROW(
|
||||||
|
"root constant cbuffer cannot be expressed with either HLSL packing layout or packoffset.");
|
||||||
|
|
||||||
|
flattened_structs.insert(var.self);
|
||||||
|
type.member_name_cache.clear();
|
||||||
|
add_resource_name(var.self);
|
||||||
|
auto &memb = meta[type.self].members;
|
||||||
|
|
||||||
|
statement("cbuffer SPIRV_CROSS_RootConstant_", to_name(var.self),
|
||||||
|
to_resource_register('b', layout.binding, layout.space));
|
||||||
|
begin_scope();
|
||||||
|
|
||||||
|
// Index of the next field in the generated root constant constant buffer
|
||||||
|
auto constant_index = 0u;
|
||||||
|
|
||||||
|
// Iterate over all member of the push constant and check which of the fields
|
||||||
|
// fit into the given root constant layout.
|
||||||
|
for (auto i = 0u; i < memb.size(); i++)
|
||||||
|
{
|
||||||
|
const auto offset = memb[i].offset;
|
||||||
|
if (layout.start <= offset && offset < layout.end)
|
||||||
|
{
|
||||||
|
const auto &member = type.member_types[i];
|
||||||
|
|
||||||
|
add_member_name(type, constant_index);
|
||||||
|
auto backup_name = get_member_name(type.self, i);
|
||||||
|
auto member_name = to_member_name(type, i);
|
||||||
|
set_member_name(type.self, constant_index,
|
||||||
|
sanitize_underscores(join(to_name(type.self), "_", member_name)));
|
||||||
|
emit_struct_member(type, member, i, "", layout.start);
|
||||||
|
set_member_name(type.self, constant_index, backup_name);
|
||||||
|
|
||||||
|
constant_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_scope_decl();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string CompilerHLSL::to_sampler_expression(uint32_t id)
|
string CompilerHLSL::to_sampler_expression(uint32_t id)
|
||||||
|
@ -2316,24 +2371,24 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
|
||||||
if (!has_decoration(var.self, DecorationBinding))
|
if (!has_decoration(var.self, DecorationBinding))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
auto &type = get<SPIRType>(var.basetype);
|
const auto &type = get<SPIRType>(var.basetype);
|
||||||
const char *space = nullptr;
|
char space = '\0';
|
||||||
|
|
||||||
switch (type.basetype)
|
switch (type.basetype)
|
||||||
{
|
{
|
||||||
case SPIRType::SampledImage:
|
case SPIRType::SampledImage:
|
||||||
space = "t"; // SRV
|
space = 't'; // SRV
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPIRType::Image:
|
case SPIRType::Image:
|
||||||
if (type.image.sampled == 2)
|
if (type.image.sampled == 2)
|
||||||
space = "u"; // UAV
|
space = 'u'; // UAV
|
||||||
else
|
else
|
||||||
space = "t"; // SRV
|
space = 't'; // SRV
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPIRType::Sampler:
|
case SPIRType::Sampler:
|
||||||
space = "s";
|
space = 's';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPIRType::Struct:
|
case SPIRType::Struct:
|
||||||
|
@ -2345,15 +2400,15 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
|
||||||
{
|
{
|
||||||
uint64_t flags = get_buffer_block_flags(var);
|
uint64_t flags = get_buffer_block_flags(var);
|
||||||
bool is_readonly = (flags & (1ull << DecorationNonWritable)) != 0;
|
bool is_readonly = (flags & (1ull << DecorationNonWritable)) != 0;
|
||||||
space = is_readonly ? "t" : "u"; // UAV
|
space = is_readonly ? 't' : 'u'; // UAV
|
||||||
}
|
}
|
||||||
else if (has_decoration(type.self, DecorationBlock))
|
else if (has_decoration(type.self, DecorationBlock))
|
||||||
space = "b"; // Constant buffers
|
space = 'b'; // Constant buffers
|
||||||
}
|
}
|
||||||
else if (storage == StorageClassPushConstant)
|
else if (storage == StorageClassPushConstant)
|
||||||
space = "b"; // Constant buffers
|
space = 'b'; // Constant buffers
|
||||||
else if (storage == StorageClassStorageBuffer)
|
else if (storage == StorageClassStorageBuffer)
|
||||||
space = "u"; // UAV
|
space = 'u'; // UAV
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2364,12 +2419,8 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
|
||||||
if (!space)
|
if (!space)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// shader model 5.1 supports space
|
return to_resource_register(space, get_decoration(var.self, DecorationBinding),
|
||||||
if (options.shader_model >= 51)
|
get_decoration(var.self, DecorationDescriptorSet));
|
||||||
return join(" : register(", space, get_decoration(var.self, DecorationBinding), ", space",
|
|
||||||
get_decoration(var.self, DecorationDescriptorSet), ")");
|
|
||||||
else
|
|
||||||
return join(" : register(", space, get_decoration(var.self, DecorationBinding), ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var)
|
string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var)
|
||||||
|
@ -2378,11 +2429,16 @@ string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var)
|
||||||
if (!has_decoration(var.self, DecorationBinding))
|
if (!has_decoration(var.self, DecorationBinding))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
return to_resource_register('s', get_decoration(var.self, DecorationBinding),
|
||||||
|
get_decoration(var.self, DecorationDescriptorSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
string CompilerHLSL::to_resource_register(char space, uint32_t binding, uint32_t space_set)
|
||||||
|
{
|
||||||
if (options.shader_model >= 51)
|
if (options.shader_model >= 51)
|
||||||
return join(" : register(s", get_decoration(var.self, DecorationBinding), ", space",
|
return join(" : register(", space, binding, ", space", space_set, ")");
|
||||||
get_decoration(var.self, DecorationDescriptorSet), ")");
|
|
||||||
else
|
else
|
||||||
return join(" : register(s", get_decoration(var.self, DecorationBinding), ")");
|
return join(" : register(", space, binding, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
|
void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
|
||||||
|
|
|
@ -29,6 +29,18 @@ struct HLSLVertexAttributeRemap
|
||||||
uint32_t location;
|
uint32_t location;
|
||||||
std::string semantic;
|
std::string semantic;
|
||||||
};
|
};
|
||||||
|
// Specifying a root constant (d3d12) or push constant range (vulkan).
|
||||||
|
//
|
||||||
|
// `start` and `end` denotes the range of the root constant in bytes.
|
||||||
|
// Both values need to be multiple of 4.
|
||||||
|
struct RootConstants
|
||||||
|
{
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
|
|
||||||
|
uint32_t binding;
|
||||||
|
uint32_t space;
|
||||||
|
};
|
||||||
|
|
||||||
class CompilerHLSL : public CompilerGLSL
|
class CompilerHLSL : public CompilerGLSL
|
||||||
{
|
{
|
||||||
|
@ -61,6 +73,15 @@ public:
|
||||||
options = opts;
|
options = opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optionally specify a custom root constant layout.
|
||||||
|
//
|
||||||
|
// Push constants ranges will be split up according to the
|
||||||
|
// layout specified.
|
||||||
|
void set_root_constant_layouts(std::vector<RootConstants> layout)
|
||||||
|
{
|
||||||
|
root_constants_layout = std::move(layout);
|
||||||
|
}
|
||||||
|
|
||||||
// Compiles and remaps vertex attributes at specific locations to a fixed semantic.
|
// Compiles and remaps vertex attributes at specific locations to a fixed semantic.
|
||||||
// The default is TEXCOORD# where # denotes location.
|
// The default is TEXCOORD# where # denotes location.
|
||||||
// Matrices are unrolled to vectors with notation ${SEMANTIC}_#, where # denotes row.
|
// Matrices are unrolled to vectors with notation ${SEMANTIC}_#, where # denotes row.
|
||||||
|
@ -113,6 +134,7 @@ private:
|
||||||
std::string to_sampler_expression(uint32_t id);
|
std::string to_sampler_expression(uint32_t id);
|
||||||
std::string to_resource_binding(const SPIRVariable &var);
|
std::string to_resource_binding(const SPIRVariable &var);
|
||||||
std::string to_resource_binding_sampler(const SPIRVariable &var);
|
std::string to_resource_binding_sampler(const SPIRVariable &var);
|
||||||
|
std::string to_resource_register(char space, uint32_t binding, uint32_t set);
|
||||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||||
void emit_access_chain(const Instruction &instruction);
|
void emit_access_chain(const Instruction &instruction);
|
||||||
void emit_load(const Instruction &instruction);
|
void emit_load(const Instruction &instruction);
|
||||||
|
@ -121,8 +143,8 @@ private:
|
||||||
void emit_store(const Instruction &instruction);
|
void emit_store(const Instruction &instruction);
|
||||||
void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op);
|
void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op);
|
||||||
|
|
||||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
|
||||||
const std::string &qualifier) override;
|
uint32_t base_offset = 0) override;
|
||||||
|
|
||||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
||||||
|
|
||||||
|
@ -173,6 +195,10 @@ private:
|
||||||
std::string to_semantic(uint32_t vertex_location);
|
std::string to_semantic(uint32_t vertex_location);
|
||||||
|
|
||||||
uint32_t num_workgroups_builtin = 0;
|
uint32_t num_workgroups_builtin = 0;
|
||||||
|
|
||||||
|
// Custom root constant layout, which should be emitted
|
||||||
|
// when translating push constant ranges.
|
||||||
|
std::vector<RootConstants> root_constants_layout;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2394,7 +2394,7 @@ void CompilerMSL::emit_fixup()
|
||||||
|
|
||||||
// Emit a structure member, padding and packing to maintain the correct memeber alignments.
|
// Emit a structure member, padding and packing to maintain the correct memeber alignments.
|
||||||
void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||||
const string &qualifier)
|
const string &qualifier, uint32_t)
|
||||||
{
|
{
|
||||||
auto &membertype = get<SPIRType>(member_type_id);
|
auto &membertype = get<SPIRType>(member_type_id);
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ protected:
|
||||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||||
void emit_fixup() override;
|
void emit_fixup() override;
|
||||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||||
const std::string &qualifier = "") override;
|
const std::string &qualifier = "", uint32_t base_offset = 0) override;
|
||||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||||
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче