[SPIR-V] Make interpolators an array to fix Adreno linkage
This commit is contained in:
parent
b3edc56576
commit
b41bb35a20
|
@ -75,9 +75,6 @@ SpirvShaderTranslator::Features::Features(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string SpirvShaderTranslator::kInterpolatorNamePrefix =
|
|
||||||
"xe_interpolator_";
|
|
||||||
|
|
||||||
SpirvShaderTranslator::SpirvShaderTranslator(const Features& features)
|
SpirvShaderTranslator::SpirvShaderTranslator(const Features& features)
|
||||||
: features_(features) {}
|
: features_(features) {}
|
||||||
|
|
||||||
|
@ -164,6 +161,8 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
type_float2_ = builder_->makeVectorType(type_float_, 2);
|
type_float2_ = builder_->makeVectorType(type_float_, 2);
|
||||||
type_float3_ = builder_->makeVectorType(type_float_, 3);
|
type_float3_ = builder_->makeVectorType(type_float_, 3);
|
||||||
type_float4_ = builder_->makeVectorType(type_float_, 4);
|
type_float4_ = builder_->makeVectorType(type_float_, 4);
|
||||||
|
type_interpolators_ = builder_->makeArrayType(
|
||||||
|
type_float4_, builder_->makeUintConstant(xenos::kMaxInterpolators), 0);
|
||||||
|
|
||||||
const_int_0_ = builder_->makeIntConstant(0);
|
const_int_0_ = builder_->makeIntConstant(0);
|
||||||
id_vector_temp_.clear();
|
id_vector_temp_.clear();
|
||||||
|
@ -1069,17 +1068,15 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderBeforeMain() {
|
||||||
main_interface_.push_back(input_vertex_index_);
|
main_interface_.push_back(input_vertex_index_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Xenia-specific outputs.
|
// Create the interpolator output.
|
||||||
// TODO(Triang3l): Change to an interpolator array.
|
input_output_interpolators_ =
|
||||||
for (uint32_t i = 0; i < xenos::kMaxInterpolators; ++i) {
|
builder_->createVariable(spv::NoPrecision, spv::StorageClassOutput,
|
||||||
spv::Id interpolator = builder_->createVariable(
|
type_interpolators_, "xe_out_interpolators");
|
||||||
spv::NoPrecision, spv::StorageClassOutput, type_float4_,
|
builder_->addDecoration(input_output_interpolators_, spv::DecorationLocation,
|
||||||
(kInterpolatorNamePrefix + std::to_string(i)).c_str());
|
0);
|
||||||
input_output_interpolators_[i] = interpolator;
|
builder_->addDecoration(input_output_interpolators_,
|
||||||
builder_->addDecoration(interpolator, spv::DecorationLocation, int(i));
|
spv::DecorationInvariant);
|
||||||
builder_->addDecoration(interpolator, spv::DecorationInvariant);
|
main_interface_.push_back(input_output_interpolators_);
|
||||||
main_interface_.push_back(interpolator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the gl_PerVertex output for used system outputs.
|
// Create the gl_PerVertex output for used system outputs.
|
||||||
std::vector<spv::Id> struct_per_vertex_members;
|
std::vector<spv::Id> struct_per_vertex_members;
|
||||||
|
@ -1108,7 +1105,12 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() {
|
||||||
|
|
||||||
// Zero the interpolators.
|
// Zero the interpolators.
|
||||||
for (uint32_t i = 0; i < xenos::kMaxInterpolators; ++i) {
|
for (uint32_t i = 0; i < xenos::kMaxInterpolators; ++i) {
|
||||||
builder_->createStore(const_float4_0_, input_output_interpolators_[i]);
|
id_vector_temp_.clear();
|
||||||
|
id_vector_temp_.push_back(builder_->makeIntConstant(int(i)));
|
||||||
|
builder_->createStore(const_float4_0_,
|
||||||
|
builder_->createAccessChain(
|
||||||
|
spv::StorageClassOutput,
|
||||||
|
input_output_interpolators_, id_vector_temp_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the vertex index or the tessellation parameters.
|
// Load the vertex index or the tessellation parameters.
|
||||||
|
@ -1282,17 +1284,13 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpirvShaderTranslator::StartFragmentShaderBeforeMain() {
|
void SpirvShaderTranslator::StartFragmentShaderBeforeMain() {
|
||||||
// Interpolator inputs.
|
// Interpolator input.
|
||||||
uint32_t interpolator_count =
|
input_output_interpolators_ =
|
||||||
std::min(xenos::kMaxInterpolators, register_count());
|
builder_->createVariable(spv::NoPrecision, spv::StorageClassInput,
|
||||||
for (uint32_t i = 0; i < interpolator_count; ++i) {
|
type_interpolators_, "xe_in_interpolators");
|
||||||
spv::Id interpolator = builder_->createVariable(
|
builder_->addDecoration(input_output_interpolators_, spv::DecorationLocation,
|
||||||
spv::NoPrecision, spv::StorageClassInput, type_float4_,
|
0);
|
||||||
(kInterpolatorNamePrefix + std::to_string(i)).c_str());
|
main_interface_.push_back(input_output_interpolators_);
|
||||||
input_output_interpolators_[i] = interpolator;
|
|
||||||
builder_->addDecoration(interpolator, spv::DecorationLocation, int(i));
|
|
||||||
main_interface_.push_back(interpolator);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool param_gen_needed = GetPsParamGenInterpolator() != UINT32_MAX;
|
bool param_gen_needed = GetPsParamGenInterpolator() != UINT32_MAX;
|
||||||
|
|
||||||
|
@ -1360,7 +1358,10 @@ void SpirvShaderTranslator::StartFragmentShaderInMain() {
|
||||||
// Register array element.
|
// Register array element.
|
||||||
id_vector_temp_.push_back(builder_->makeIntConstant(int(i)));
|
id_vector_temp_.push_back(builder_->makeIntConstant(int(i)));
|
||||||
builder_->createStore(
|
builder_->createStore(
|
||||||
builder_->createLoad(input_output_interpolators_[i], spv::NoPrecision),
|
builder_->createLoad(builder_->createAccessChain(
|
||||||
|
spv::StorageClassInput,
|
||||||
|
input_output_interpolators_, id_vector_temp_),
|
||||||
|
spv::NoPrecision),
|
||||||
builder_->createAccessChain(spv::StorageClassFunction,
|
builder_->createAccessChain(spv::StorageClassFunction,
|
||||||
var_main_registers_, id_vector_temp_));
|
var_main_registers_, id_vector_temp_));
|
||||||
}
|
}
|
||||||
|
@ -1837,7 +1838,12 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result,
|
||||||
} break;
|
} break;
|
||||||
case InstructionStorageTarget::kInterpolator:
|
case InstructionStorageTarget::kInterpolator:
|
||||||
assert_true(is_vertex_shader());
|
assert_true(is_vertex_shader());
|
||||||
target_pointer = input_output_interpolators_[result.storage_index];
|
id_vector_temp_util_.clear();
|
||||||
|
id_vector_temp_util_.push_back(
|
||||||
|
builder_->makeIntConstant(int(result.storage_index)));
|
||||||
|
target_pointer = builder_->createAccessChain(spv::StorageClassOutput,
|
||||||
|
input_output_interpolators_,
|
||||||
|
id_vector_temp_util_);
|
||||||
break;
|
break;
|
||||||
case InstructionStorageTarget::kPosition:
|
case InstructionStorageTarget::kPosition:
|
||||||
assert_true(is_vertex_shader());
|
assert_true(is_vertex_shader());
|
||||||
|
|
|
@ -529,6 +529,8 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
spv::Id type_float_vectors_[4];
|
spv::Id type_float_vectors_[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
spv::Id type_interpolators_;
|
||||||
|
|
||||||
spv::Id const_int_0_;
|
spv::Id const_int_0_;
|
||||||
spv::Id const_int4_0_;
|
spv::Id const_int4_0_;
|
||||||
spv::Id const_uint_0_;
|
spv::Id const_uint_0_;
|
||||||
|
@ -589,11 +591,12 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
// PS, only when needed - bool.
|
// PS, only when needed - bool.
|
||||||
spv::Id input_front_facing_;
|
spv::Id input_front_facing_;
|
||||||
|
|
||||||
// In vertex or tessellation evaluation shaders - outputs, always
|
// VS output or PS input, only when needed - type_interpolators_.
|
||||||
// xenos::kMaxInterpolators.
|
// The Qualcomm Adreno driver has strict requirements for stage linkage - if
|
||||||
// In pixel shaders - inputs, min(xenos::kMaxInterpolators, register_count()).
|
// this is an array in one stage, it must be an array in the other (in case of
|
||||||
spv::Id input_output_interpolators_[xenos::kMaxInterpolators];
|
// Xenia, including geometry shaders); it must not be an array in one and just
|
||||||
static const std::string kInterpolatorNamePrefix;
|
// elements in consecutive locations in another.
|
||||||
|
spv::Id input_output_interpolators_;
|
||||||
|
|
||||||
enum OutputPerVertexMember : unsigned int {
|
enum OutputPerVertexMember : unsigned int {
|
||||||
kOutputPerVertexMemberPosition,
|
kOutputPerVertexMemberPosition,
|
||||||
|
|
Loading…
Reference in New Issue