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