Make use of explicit locations in HLSL.
This commit is contained in:
Родитель
2ebe1a87a1
Коммит
61c31c6054
|
@ -0,0 +1,31 @@
|
||||||
|
static float4 RT0;
|
||||||
|
static float4 RT1;
|
||||||
|
static float4 RT2;
|
||||||
|
static float4 RT3;
|
||||||
|
|
||||||
|
struct SPIRV_Cross_Output
|
||||||
|
{
|
||||||
|
float4 RT0 : COLOR0;
|
||||||
|
float4 RT1 : COLOR1;
|
||||||
|
float4 RT2 : COLOR2;
|
||||||
|
float4 RT3 : COLOR3;
|
||||||
|
};
|
||||||
|
|
||||||
|
void frag_main()
|
||||||
|
{
|
||||||
|
RT0 = float4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
RT1 = float4(2.0f, 2.0f, 2.0f, 2.0f);
|
||||||
|
RT2 = float4(3.0f, 3.0f, 3.0f, 3.0f);
|
||||||
|
RT3 = float4(4.0f, 4.0f, 4.0f, 4.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIRV_Cross_Output main()
|
||||||
|
{
|
||||||
|
frag_main();
|
||||||
|
SPIRV_Cross_Output stage_output;
|
||||||
|
stage_output.RT0 = RT0;
|
||||||
|
stage_output.RT1 = RT1;
|
||||||
|
stage_output.RT2 = RT2;
|
||||||
|
stage_output.RT3 = RT3;
|
||||||
|
return stage_output;
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ struct SPIRV_Cross_Input
|
||||||
struct SPIRV_Cross_Output
|
struct SPIRV_Cross_Output
|
||||||
{
|
{
|
||||||
float4 gl_Position : POSITION;
|
float4 gl_Position : POSITION;
|
||||||
float3 vNormal : TEXCOORD2;
|
float3 vNormal : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void vert_main()
|
void vert_main()
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
float3 a;
|
||||||
|
float3 b;
|
||||||
|
float3 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform float4 gl_HalfPixel;
|
||||||
|
|
||||||
|
static float4 gl_Position;
|
||||||
|
static float4 Input2;
|
||||||
|
static float4 Input4;
|
||||||
|
static float4 Input0;
|
||||||
|
static float vLocation0;
|
||||||
|
static float vLocation1;
|
||||||
|
static float vLocation2[2];
|
||||||
|
static Foo vLocation4;
|
||||||
|
static float vLocation7;
|
||||||
|
|
||||||
|
struct SPIRV_Cross_Input
|
||||||
|
{
|
||||||
|
float4 Input2 : TEXCOORD2;
|
||||||
|
float4 Input4 : TEXCOORD4;
|
||||||
|
float4 Input0 : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SPIRV_Cross_Output
|
||||||
|
{
|
||||||
|
float4 gl_Position : POSITION;
|
||||||
|
float vLocation0 : TEXCOORD0;
|
||||||
|
float vLocation1 : TEXCOORD1;
|
||||||
|
float vLocation2[2] : TEXCOORD2;
|
||||||
|
Foo vLocation4 : TEXCOORD4;
|
||||||
|
float vLocation7 : TEXCOORD7;
|
||||||
|
};
|
||||||
|
|
||||||
|
void vert_main()
|
||||||
|
{
|
||||||
|
gl_Position = ((float4(1.0f, 1.0f, 1.0f, 1.0f) + Input2) + Input4) + Input0;
|
||||||
|
vLocation0 = 0.0f;
|
||||||
|
vLocation1 = 1.0f;
|
||||||
|
vLocation2[0] = 2.0f;
|
||||||
|
vLocation2[1] = 2.0f;
|
||||||
|
Foo foo;
|
||||||
|
foo.a = float3(1.0f, 1.0f, 1.0f);
|
||||||
|
foo.b = float3(1.0f, 1.0f, 1.0f);
|
||||||
|
foo.c = float3(1.0f, 1.0f, 1.0f);
|
||||||
|
vLocation4 = foo;
|
||||||
|
vLocation7 = 7.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||||
|
{
|
||||||
|
Input2 = stage_input.Input2;
|
||||||
|
Input4 = stage_input.Input4;
|
||||||
|
Input0 = stage_input.Input0;
|
||||||
|
vert_main();
|
||||||
|
SPIRV_Cross_Output stage_output;
|
||||||
|
stage_output.gl_Position = gl_Position;
|
||||||
|
stage_output.vLocation0 = vLocation0;
|
||||||
|
stage_output.vLocation1 = vLocation1;
|
||||||
|
stage_output.vLocation2 = vLocation2;
|
||||||
|
stage_output.vLocation4 = vLocation4;
|
||||||
|
stage_output.vLocation7 = vLocation7;
|
||||||
|
stage_output.gl_Position.x = stage_output.gl_Position.x - gl_HalfPixel.x * stage_output.gl_Position.w;
|
||||||
|
stage_output.gl_Position.y = stage_output.gl_Position.y + gl_HalfPixel.y * stage_output.gl_Position.w;
|
||||||
|
return stage_output;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 310 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 RT0;
|
||||||
|
layout(location = 1) out vec4 RT1;
|
||||||
|
layout(location = 2) out vec4 RT2;
|
||||||
|
layout(location = 3) out vec4 RT3;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
RT0 = vec4(1.0);
|
||||||
|
RT1 = vec4(2.0);
|
||||||
|
RT2 = vec4(3.0);
|
||||||
|
RT3 = vec4(4.0);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#version 310 es
|
||||||
|
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
vec3 b;
|
||||||
|
vec3 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 2) in vec4 Input2;
|
||||||
|
layout(location = 4) in vec4 Input4;
|
||||||
|
in vec4 Input0;
|
||||||
|
|
||||||
|
layout(location = 0) out float vLocation0;
|
||||||
|
layout(location = 1) out float vLocation1;
|
||||||
|
out float vLocation2[2];
|
||||||
|
out Foo vLocation4;
|
||||||
|
out float vLocation7;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(1.0) + Input2 + Input4 + Input0;
|
||||||
|
vLocation0 = 0.0;
|
||||||
|
vLocation1 = 1.0;
|
||||||
|
vLocation2[0] = 2.0;
|
||||||
|
vLocation2[1] = 2.0;
|
||||||
|
Foo foo;
|
||||||
|
foo.a = vec3(1.0);
|
||||||
|
foo.b = vec3(1.0);
|
||||||
|
foo.c = vec3(1.0);
|
||||||
|
vLocation4 = foo;
|
||||||
|
vLocation7 = 7.0;
|
||||||
|
}
|
|
@ -136,7 +136,7 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Compiler::to_name(uint32_t id, bool allow_alias)
|
string Compiler::to_name(uint32_t id, bool allow_alias) const
|
||||||
{
|
{
|
||||||
if (allow_alias && ids.at(id).get_type() == TypeType)
|
if (allow_alias && ids.at(id).get_type() == TypeType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -411,7 +411,7 @@ protected:
|
||||||
std::unordered_set<uint32_t> selection_merge_targets;
|
std::unordered_set<uint32_t> selection_merge_targets;
|
||||||
std::unordered_set<uint32_t> multiselect_merge_targets;
|
std::unordered_set<uint32_t> multiselect_merge_targets;
|
||||||
|
|
||||||
virtual std::string to_name(uint32_t id, bool allow_alias = true);
|
virtual std::string to_name(uint32_t id, bool allow_alias = true) const;
|
||||||
bool is_builtin_variable(const SPIRVariable &var) const;
|
bool is_builtin_variable(const SPIRVariable &var) const;
|
||||||
bool is_hidden_variable(const SPIRVariable &var, bool include_builtins = false) const;
|
bool is_hidden_variable(const SPIRVariable &var, bool include_builtins = false) const;
|
||||||
bool is_immutable(uint32_t id) const;
|
bool is_immutable(uint32_t id) const;
|
||||||
|
|
161
spirv_hlsl.cpp
161
spirv_hlsl.cpp
|
@ -22,39 +22,6 @@ using namespace spv;
|
||||||
using namespace spirv_cross;
|
using namespace spirv_cross;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct VariableComparator
|
|
||||||
{
|
|
||||||
VariableComparator(const CompilerHLSL &compiler_)
|
|
||||||
: compiler(compiler_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(SPIRVariable *var1, SPIRVariable *var2)
|
|
||||||
{
|
|
||||||
if (compiler.get_decoration_mask(var1->self) & compiler.get_decoration_mask(var2->self) &
|
|
||||||
(1ull << DecorationLocation))
|
|
||||||
return compiler.get_decoration(var1->self, DecorationLocation) <
|
|
||||||
compiler.get_decoration(var2->self, DecorationLocation);
|
|
||||||
|
|
||||||
auto &name1 = compiler.get_name(var1->self);
|
|
||||||
auto &name2 = compiler.get_name(var2->self);
|
|
||||||
|
|
||||||
if (name1.empty() && name2.empty())
|
|
||||||
return var1->self < var2->self;
|
|
||||||
if (name1.empty())
|
|
||||||
return true;
|
|
||||||
else if (name2.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return name1.compare(name2) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CompilerHLSL &compiler;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
string CompilerHLSL::type_to_glsl(const SPIRType &type)
|
string CompilerHLSL::type_to_glsl(const SPIRType &type)
|
||||||
{
|
{
|
||||||
// Ignore the pointer type since GLSL doesn't have pointers.
|
// Ignore the pointer type since GLSL doesn't have pointers.
|
||||||
|
@ -163,21 +130,8 @@ void CompilerHLSL::emit_header()
|
||||||
|
|
||||||
void CompilerHLSL::emit_interface_block_globally(const SPIRVariable &var)
|
void CompilerHLSL::emit_interface_block_globally(const SPIRVariable &var)
|
||||||
{
|
{
|
||||||
auto &execution = get_entry_point();
|
|
||||||
|
|
||||||
add_resource_name(var.self);
|
add_resource_name(var.self);
|
||||||
|
statement("static ", variable_decl(var), ";");
|
||||||
if (execution.model == ExecutionModelVertex && var.storage == StorageClassInput && is_builtin_variable(var))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (execution.model == ExecutionModelVertex && var.storage == StorageClassOutput && is_builtin_variable(var))
|
|
||||||
{
|
|
||||||
statement("static float4 gl_Position;");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
statement("static ", variable_decl(var), ";");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CompilerHLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
|
const char *CompilerHLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
|
||||||
|
@ -249,12 +203,37 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, uint32_t &binding_number)
|
uint32_t CompilerHLSL::type_to_consumed_locations(const SPIRType &type) const
|
||||||
|
{
|
||||||
|
// TODO: Need to verify correctness.
|
||||||
|
uint32_t elements = 0;
|
||||||
|
|
||||||
|
if (type.basetype == SPIRType::Struct)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||||
|
elements += type_to_consumed_locations(get<SPIRType>(type.member_types[i]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t array_multiplier = 1;
|
||||||
|
for (uint32_t i = 0; i < uint32_t(type.array.size()); i++)
|
||||||
|
{
|
||||||
|
if (type.array_size_literal[i])
|
||||||
|
array_multiplier *= type.array[i];
|
||||||
|
else
|
||||||
|
array_multiplier *= get<SPIRConstant>(type.array[i]).scalar();
|
||||||
|
}
|
||||||
|
elements += array_multiplier * type.columns;
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unordered_set<uint32_t> &active_locations)
|
||||||
{
|
{
|
||||||
auto &execution = get_entry_point();
|
auto &execution = get_entry_point();
|
||||||
auto &type = get<SPIRType>(var.basetype);
|
auto &type = get<SPIRType>(var.basetype);
|
||||||
|
|
||||||
string binding = "TEXCOORD";
|
string binding;
|
||||||
bool use_binding_number = true;
|
bool use_binding_number = true;
|
||||||
bool legacy = options.shader_model <= 30;
|
bool legacy = options.shader_model <= 30;
|
||||||
if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput)
|
if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput)
|
||||||
|
@ -263,27 +242,52 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, uint3
|
||||||
use_binding_number = false;
|
use_binding_number = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto get_vacant_location = [&]() -> uint32_t {
|
||||||
|
for (uint32_t i = 0; i < 64; i++)
|
||||||
|
if (!active_locations.count(i))
|
||||||
|
return i;
|
||||||
|
SPIRV_CROSS_THROW("All locations from 0 to 63 are exhausted.");
|
||||||
|
};
|
||||||
|
|
||||||
auto &m = meta[var.self].decoration;
|
auto &m = meta[var.self].decoration;
|
||||||
|
auto name = to_name(var.self);
|
||||||
if (use_binding_number)
|
if (use_binding_number)
|
||||||
{
|
{
|
||||||
|
uint32_t binding_number;
|
||||||
|
|
||||||
|
// If an explicit location exists, use it with TEXCOORD[N] semantic.
|
||||||
|
// Otherwise, pick a vacant location.
|
||||||
|
if (m.decoration_flags & (1ull << DecorationLocation))
|
||||||
|
binding_number = m.location;
|
||||||
|
else
|
||||||
|
binding_number = get_vacant_location();
|
||||||
|
|
||||||
if (type.columns > 1)
|
if (type.columns > 1)
|
||||||
{
|
{
|
||||||
|
if (!type.array.empty())
|
||||||
|
SPIRV_CROSS_THROW("Arrays of matrices used as input/output. This is not supported.");
|
||||||
|
|
||||||
|
// Unroll matrices.
|
||||||
for (uint32_t i = 0; i < type.columns; i++)
|
for (uint32_t i = 0; i < type.columns; i++)
|
||||||
{
|
{
|
||||||
SPIRType newtype = type;
|
SPIRType newtype = type;
|
||||||
newtype.columns = 1;
|
newtype.columns = 1;
|
||||||
statement(variable_decl(newtype, join(m.alias, "_", i)), " : ", binding, binding_number++, ";");
|
statement(variable_decl(newtype, join(name, "_", i)), " : TEXCOORD", binding_number, ";");
|
||||||
|
active_locations.insert(binding_number++);
|
||||||
}
|
}
|
||||||
--binding_number;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
statement(variable_decl(type, m.alias), " : ", binding, binding_number, ";");
|
{
|
||||||
|
statement(variable_decl(type, name), " : TEXCOORD", binding_number, ";");
|
||||||
|
|
||||||
|
// Structs and arrays should consume more locations.
|
||||||
|
uint32_t consumed_locations = type_to_consumed_locations(type);
|
||||||
|
for (uint32_t i = 0; i < consumed_locations; i++)
|
||||||
|
active_locations.insert(binding_number + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
statement(variable_decl(type, m.alias), " : ", binding, ";");
|
statement(variable_decl(type, name), " : ", binding, ";");
|
||||||
|
|
||||||
if (use_binding_number)
|
|
||||||
binding_number++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_builtin_variables()
|
void CompilerHLSL::emit_builtin_variables()
|
||||||
|
@ -423,7 +427,8 @@ void CompilerHLSL::emit_resources()
|
||||||
statement("");
|
statement("");
|
||||||
emitted = false;
|
emitted = false;
|
||||||
|
|
||||||
uint32_t binding_number = 0;
|
unordered_set<uint32_t> active_inputs;
|
||||||
|
unordered_set<uint32_t> active_outputs;
|
||||||
vector<SPIRVariable *> input_variables;
|
vector<SPIRVariable *> input_variables;
|
||||||
vector<SPIRVariable *> output_variables;
|
vector<SPIRVariable *> output_variables;
|
||||||
for (auto &id : ids)
|
for (auto &id : ids)
|
||||||
|
@ -445,17 +450,49 @@ void CompilerHLSL::emit_resources()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto variable_compare = [&](const SPIRVariable *a, const SPIRVariable *b) -> bool {
|
||||||
|
// Sort input and output variables based on, from more robust to less robust:
|
||||||
|
// - Location
|
||||||
|
// - Variable has a location
|
||||||
|
// - Name comparison
|
||||||
|
// - Variable has a name
|
||||||
|
// - Fallback: ID
|
||||||
|
bool has_location_a = (get_decoration_mask(a->self) & (1ull << DecorationLocation)) != 0;
|
||||||
|
bool has_location_b = (get_decoration_mask(b->self) & (1ull << DecorationLocation)) != 0;
|
||||||
|
|
||||||
|
if (has_location_a && has_location_b)
|
||||||
|
{
|
||||||
|
return get_decoration(a->self, DecorationLocation) <
|
||||||
|
get_decoration(b->self, DecorationLocation);
|
||||||
|
}
|
||||||
|
else if (has_location_a && !has_location_b)
|
||||||
|
return true;
|
||||||
|
else if (!has_location_a && has_location_b)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto &name1 = to_name(a->self);
|
||||||
|
const auto &name2 = to_name(b->self);
|
||||||
|
|
||||||
|
if (name1.empty() && name2.empty())
|
||||||
|
return a->self < b->self;
|
||||||
|
else if (name1.empty())
|
||||||
|
return true;
|
||||||
|
else if (name2.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return name1.compare(name2) < 0;
|
||||||
|
};
|
||||||
|
|
||||||
if (!input_variables.empty() || active_input_builtins)
|
if (!input_variables.empty() || active_input_builtins)
|
||||||
{
|
{
|
||||||
require_input = true;
|
require_input = true;
|
||||||
statement("struct SPIRV_Cross_Input");
|
statement("struct SPIRV_Cross_Input");
|
||||||
|
|
||||||
begin_scope();
|
begin_scope();
|
||||||
// FIXME: Use locations properly if they exist.
|
sort(input_variables.begin(), input_variables.end(), variable_compare);
|
||||||
sort(input_variables.begin(), input_variables.end(), VariableComparator(*this));
|
|
||||||
emit_builtin_inputs_in_struct();
|
emit_builtin_inputs_in_struct();
|
||||||
for (auto var : input_variables)
|
for (auto var : input_variables)
|
||||||
emit_interface_block_in_struct(*var, binding_number);
|
emit_interface_block_in_struct(*var, active_inputs);
|
||||||
end_scope_decl();
|
end_scope_decl();
|
||||||
statement("");
|
statement("");
|
||||||
}
|
}
|
||||||
|
@ -469,10 +506,10 @@ void CompilerHLSL::emit_resources()
|
||||||
|
|
||||||
begin_scope();
|
begin_scope();
|
||||||
// FIXME: Use locations properly if they exist.
|
// FIXME: Use locations properly if they exist.
|
||||||
sort(output_variables.begin(), output_variables.end(), VariableComparator(*this));
|
sort(output_variables.begin(), output_variables.end(), variable_compare);
|
||||||
emit_builtin_outputs_in_struct();
|
emit_builtin_outputs_in_struct();
|
||||||
for (auto var : output_variables)
|
for (auto var : output_variables)
|
||||||
emit_interface_block_in_struct(*var, binding_number);
|
emit_interface_block_in_struct(*var, active_outputs);
|
||||||
end_scope_decl();
|
end_scope_decl();
|
||||||
statement("");
|
statement("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ private:
|
||||||
void emit_header() override;
|
void emit_header() override;
|
||||||
void emit_resources();
|
void emit_resources();
|
||||||
void emit_interface_block_globally(const SPIRVariable &type);
|
void emit_interface_block_globally(const SPIRVariable &type);
|
||||||
void emit_interface_block_in_struct(const SPIRVariable &type, uint32_t &binding_number);
|
void emit_interface_block_in_struct(const SPIRVariable &type, std::unordered_set<uint32_t> &active_locations);
|
||||||
void emit_builtin_inputs_in_struct();
|
void emit_builtin_inputs_in_struct();
|
||||||
void emit_builtin_outputs_in_struct();
|
void emit_builtin_outputs_in_struct();
|
||||||
void emit_texture_op(const Instruction &i) override;
|
void emit_texture_op(const Instruction &i) override;
|
||||||
|
@ -76,6 +76,8 @@ private:
|
||||||
void emit_builtin_variables();
|
void emit_builtin_variables();
|
||||||
bool require_output = false;
|
bool require_output = false;
|
||||||
bool require_input = false;
|
bool require_input = false;
|
||||||
|
|
||||||
|
uint32_t type_to_consumed_locations(const SPIRType &type) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1794,7 +1794,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
|
||||||
|
|
||||||
// If we're currently in the entry point function, and the object
|
// If we're currently in the entry point function, and the object
|
||||||
// has a qualified name, use it, otherwise use the standard name.
|
// has a qualified name, use it, otherwise use the standard name.
|
||||||
string CompilerMSL::to_name(uint32_t id, bool allow_alias)
|
string CompilerMSL::to_name(uint32_t id, bool allow_alias) const
|
||||||
{
|
{
|
||||||
if (current_function && (current_function->self == entry_point))
|
if (current_function && (current_function->self == entry_point))
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,7 +136,7 @@ protected:
|
||||||
std::string constant_expression(const SPIRConstant &c) override;
|
std::string constant_expression(const SPIRConstant &c) override;
|
||||||
size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const override;
|
size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const override;
|
||||||
std::string to_func_call_arg(uint32_t id) override;
|
std::string to_func_call_arg(uint32_t id) override;
|
||||||
std::string to_name(uint32_t id, bool allow_alias = true) override;
|
std::string to_name(uint32_t id, bool allow_alias = true) const override;
|
||||||
std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
|
||||||
bool has_array_offsets, bool has_offset, bool has_grad, bool has_lod,
|
bool has_array_offsets, bool has_offset, bool has_grad, bool has_lod,
|
||||||
bool has_dref) override;
|
bool has_dref) override;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче