SPIR-V: Use gl_VertexIndex rather than gl_VertexID
Rewrite bits of LoadFromOperand/StoreToResult
This commit is contained in:
parent
72d83591e5
commit
a547c79b51
|
@ -278,22 +278,23 @@ void SpirvShaderTranslator::StartTranslation() {
|
||||||
b.addDecoration(pos_, spv::Decoration::DecorationBuiltIn,
|
b.addDecoration(pos_, spv::Decoration::DecorationBuiltIn,
|
||||||
spv::BuiltIn::BuiltInPosition);
|
spv::BuiltIn::BuiltInPosition);
|
||||||
|
|
||||||
vertex_id_ = b.createVariable(spv::StorageClass::StorageClassInput,
|
vertex_idx_ = b.createVariable(spv::StorageClass::StorageClassInput,
|
||||||
int_type_, "gl_VertexId");
|
int_type_, "gl_VertexIndex");
|
||||||
b.addDecoration(vertex_id_, spv::Decoration::DecorationBuiltIn,
|
b.addDecoration(vertex_idx_, spv::Decoration::DecorationBuiltIn,
|
||||||
spv::BuiltIn::BuiltInVertexId);
|
spv::BuiltIn::BuiltInVertexIndex);
|
||||||
|
|
||||||
interface_ids_.push_back(interpolators_);
|
interface_ids_.push_back(interpolators_);
|
||||||
interface_ids_.push_back(pos_);
|
interface_ids_.push_back(pos_);
|
||||||
interface_ids_.push_back(vertex_id_);
|
interface_ids_.push_back(vertex_idx_);
|
||||||
|
|
||||||
auto vertex_id = b.createLoad(vertex_id_);
|
auto vertex_idx = b.createLoad(vertex_idx_);
|
||||||
vertex_id = b.createUnaryOp(spv::Op::OpConvertSToF, float_type_, vertex_id);
|
vertex_idx =
|
||||||
|
b.createUnaryOp(spv::Op::OpConvertSToF, float_type_, vertex_idx);
|
||||||
auto r0_ptr = b.createAccessChain(spv::StorageClass::StorageClassFunction,
|
auto r0_ptr = b.createAccessChain(spv::StorageClass::StorageClassFunction,
|
||||||
registers_ptr_,
|
registers_ptr_,
|
||||||
std::vector<Id>({b.makeUintConstant(0)}));
|
std::vector<Id>({b.makeUintConstant(0)}));
|
||||||
auto r0 = b.createLoad(r0_ptr);
|
auto r0 = b.createLoad(r0_ptr);
|
||||||
r0 = b.createCompositeInsert(vertex_id, r0, vec4_float_type_,
|
r0 = b.createCompositeInsert(vertex_idx, r0, vec4_float_type_,
|
||||||
std::vector<uint32_t>({0}));
|
std::vector<uint32_t>({0}));
|
||||||
b.createStore(r0, r0_ptr);
|
b.createStore(r0, r0_ptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -857,7 +858,7 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
const ParsedVertexFetchInstruction& instr) {
|
const ParsedVertexFetchInstruction& instr) {
|
||||||
auto& b = *builder_;
|
auto& b = *builder_;
|
||||||
assert_true(is_vertex_shader());
|
assert_true(is_vertex_shader());
|
||||||
assert_not_zero(vertex_id_);
|
assert_not_zero(vertex_idx_);
|
||||||
|
|
||||||
// Close the open predicated block if this instr isn't predicated or the
|
// Close the open predicated block if this instr isn't predicated or the
|
||||||
// conditions do not match.
|
// conditions do not match.
|
||||||
|
@ -889,10 +890,9 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
// Operand 0 is the index
|
// Operand 0 is the index
|
||||||
// Operand 1 is the binding
|
// Operand 1 is the binding
|
||||||
// TODO: Indexed fetch
|
// TODO: Indexed fetch
|
||||||
auto vertex_id = LoadFromOperand(instr.operands[0]);
|
auto vertex_idx = LoadFromOperand(instr.operands[0]);
|
||||||
vertex_id = b.createCompositeExtract(vertex_id, float_type_, 0);
|
vertex_idx = b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, vertex_idx);
|
||||||
vertex_id = b.createUnaryOp(spv::Op::OpConvertFToS, int_type_, vertex_id);
|
auto shader_vertex_idx = b.createLoad(vertex_idx_);
|
||||||
auto shader_vertex_id = b.createLoad(vertex_id_);
|
|
||||||
|
|
||||||
// Skip loading if it's an indexed fetch.
|
// Skip loading if it's an indexed fetch.
|
||||||
auto vertex_ptr = vertex_binding_map_[instr.operands[1].storage_index]
|
auto vertex_ptr = vertex_binding_map_[instr.operands[1].storage_index]
|
||||||
|
@ -1716,6 +1716,7 @@ void SpirvShaderTranslator::ProcessVectorAluInstruction(
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_not_zero(dest);
|
assert_not_zero(dest);
|
||||||
|
assert_true(b.getTypeId(dest) == vec4_float_type_);
|
||||||
if (dest) {
|
if (dest) {
|
||||||
b.createStore(dest, pv_);
|
b.createStore(dest, pv_);
|
||||||
StoreToResult(dest, instr.result);
|
StoreToResult(dest, instr.result);
|
||||||
|
@ -1741,9 +1742,13 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction(
|
||||||
auto src = LoadFromOperand(instr.operands[i]);
|
auto src = LoadFromOperand(instr.operands[i]);
|
||||||
|
|
||||||
// Pull components out of the vector operands and use them as sources.
|
// Pull components out of the vector operands and use them as sources.
|
||||||
|
if (instr.operands[i].component_count > 1) {
|
||||||
for (int j = 0; j < instr.operands[i].component_count; j++) {
|
for (int j = 0; j < instr.operands[i].component_count; j++) {
|
||||||
sources[x++] = b.createCompositeExtract(src, float_type_, j);
|
sources[x++] = b.createCompositeExtract(src, float_type_, j);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sources[x++] = src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the open predicated block if this instr isn't predicated or the
|
// Close the open predicated block if this instr isn't predicated or the
|
||||||
|
@ -2006,15 +2011,17 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction(
|
||||||
dest = CreateGlslStd450InstructionCall(spv::NoPrecision, float_type_,
|
dest = CreateGlslStd450InstructionCall(spv::NoPrecision, float_type_,
|
||||||
spv::GLSLstd450::kInverseSqrt,
|
spv::GLSLstd450::kInverseSqrt,
|
||||||
{sources[0]});
|
{sources[0]});
|
||||||
auto c = b.createUnaryOp(spv::Op::OpIsInf, bool_type_, dest);
|
auto c1 = b.createUnaryOp(spv::Op::OpIsInf, bool_type_, dest);
|
||||||
|
auto c2 = b.createUnaryOp(spv::Op::OpIsNan, bool_type_, dest);
|
||||||
|
auto c = b.createBinOp(spv::Op::OpLogicalOr, bool_type_, c1, c2);
|
||||||
dest = b.createTriOp(spv::Op::OpSelect, float_type_, c,
|
dest = b.createTriOp(spv::Op::OpSelect, float_type_, c,
|
||||||
b.makeFloatConstant(0.f), dest);
|
b.makeFloatConstant(0.f), dest);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AluScalarOpcode::kRsq: {
|
case AluScalarOpcode::kRsq: {
|
||||||
// dest = src0 != 0.0 ? inversesqrt(src0) : 0.0;
|
// dest = src0 > 0.0 ? inversesqrt(src0) : 0.0;
|
||||||
auto c = b.createBinOp(spv::Op::OpFOrdEqual, bool_type_, sources[0],
|
auto c = b.createBinOp(spv::Op::OpFOrdLessThanEqual, bool_type_,
|
||||||
b.makeFloatConstant(0.f));
|
sources[0], b.makeFloatConstant(0.f));
|
||||||
auto d = CreateGlslStd450InstructionCall(spv::NoPrecision, float_type_,
|
auto d = CreateGlslStd450InstructionCall(spv::NoPrecision, float_type_,
|
||||||
spv::GLSLstd450::kInverseSqrt,
|
spv::GLSLstd450::kInverseSqrt,
|
||||||
{sources[0]});
|
{sources[0]});
|
||||||
|
@ -2179,6 +2186,7 @@ void SpirvShaderTranslator::ProcessScalarAluInstruction(
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_not_zero(dest);
|
assert_not_zero(dest);
|
||||||
|
assert_true(b.getTypeId(dest) == float_type_);
|
||||||
if (dest) {
|
if (dest) {
|
||||||
b.createStore(dest, ps_);
|
b.createStore(dest, ps_);
|
||||||
StoreToResult(dest, instr.result);
|
StoreToResult(dest, instr.result);
|
||||||
|
@ -2272,6 +2280,35 @@ Id SpirvShaderTranslator::LoadFromOperand(const InstructionOperand& op) {
|
||||||
auto storage_value = b.createLoad(storage_pointer);
|
auto storage_value = b.createLoad(storage_pointer);
|
||||||
assert_true(b.getTypeId(storage_value) == vec4_float_type_);
|
assert_true(b.getTypeId(storage_value) == vec4_float_type_);
|
||||||
|
|
||||||
|
if (op.component_count == 1) {
|
||||||
|
// Don't bother handling constant 0/1 fetches, as they're invalid in scalar
|
||||||
|
// opcodes.
|
||||||
|
uint32_t index = 0;
|
||||||
|
switch (op.components[0]) {
|
||||||
|
case SwizzleSource::kX:
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
case SwizzleSource::kY:
|
||||||
|
index = 1;
|
||||||
|
break;
|
||||||
|
case SwizzleSource::kZ:
|
||||||
|
index = 2;
|
||||||
|
break;
|
||||||
|
case SwizzleSource::kW:
|
||||||
|
index = 3;
|
||||||
|
break;
|
||||||
|
case SwizzleSource::k0:
|
||||||
|
assert_always();
|
||||||
|
break;
|
||||||
|
case SwizzleSource::k1:
|
||||||
|
assert_always();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage_value = b.createCompositeExtract(storage_value, float_type_, index);
|
||||||
|
storage_type = float_type_;
|
||||||
|
}
|
||||||
|
|
||||||
if (op.is_absolute_value) {
|
if (op.is_absolute_value) {
|
||||||
storage_value = CreateGlslStd450InstructionCall(
|
storage_value = CreateGlslStd450InstructionCall(
|
||||||
spv::NoPrecision, storage_type, GLSLstd450::kFAbs, {storage_value});
|
spv::NoPrecision, storage_type, GLSLstd450::kFAbs, {storage_value});
|
||||||
|
@ -2282,7 +2319,7 @@ Id SpirvShaderTranslator::LoadFromOperand(const InstructionOperand& op) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// swizzle
|
// swizzle
|
||||||
if (!op.is_standard_swizzle()) {
|
if (op.component_count > 1 && !op.is_standard_swizzle()) {
|
||||||
std::vector<uint32_t> operands;
|
std::vector<uint32_t> operands;
|
||||||
operands.push_back(storage_value);
|
operands.push_back(storage_value);
|
||||||
operands.push_back(b.makeCompositeConstant(
|
operands.push_back(b.makeCompositeConstant(
|
||||||
|
@ -2427,42 +2464,25 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id,
|
||||||
b.createAccessChain(storage_class, storage_pointer, storage_offsets);
|
b.createAccessChain(storage_class, storage_pointer, storage_offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool source_is_scalar = b.isScalar(source_value_id);
|
||||||
|
bool storage_is_scalar = b.isScalarType(b.getDerefTypeId(storage_pointer));
|
||||||
|
spv::Id source_type = b.getTypeId(source_value_id);
|
||||||
|
|
||||||
// Only load from storage if we need it later.
|
// Only load from storage if we need it later.
|
||||||
Id storage_value = 0;
|
Id storage_value = 0;
|
||||||
if (!result.has_all_writes()) {
|
if ((source_is_scalar && !storage_is_scalar) || !result.has_all_writes()) {
|
||||||
storage_value = b.createLoad(storage_pointer);
|
storage_value = b.createLoad(storage_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp the input value.
|
// Clamp the input value.
|
||||||
if (result.is_clamped) {
|
if (result.is_clamped) {
|
||||||
source_value_id = CreateGlslStd450InstructionCall(
|
source_value_id = CreateGlslStd450InstructionCall(
|
||||||
spv::NoPrecision, b.getTypeId(source_value_id),
|
spv::NoPrecision, source_type, spv::GLSLstd450::kFClamp,
|
||||||
spv::GLSLstd450::kFClamp,
|
|
||||||
{source_value_id, b.makeFloatConstant(0.0), b.makeFloatConstant(1.0)});
|
{source_value_id, b.makeFloatConstant(0.0), b.makeFloatConstant(1.0)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to the appropriate type, if needed.
|
|
||||||
if (b.getTypeId(source_value_id) != storage_type) {
|
|
||||||
std::vector<Id> constituents;
|
|
||||||
auto n_el = b.getNumComponents(source_value_id);
|
|
||||||
auto n_dst = b.getNumTypeComponents(storage_type);
|
|
||||||
|
|
||||||
if (n_el != 1) {
|
|
||||||
std::vector<uint32_t> channels;
|
|
||||||
for (int i = 0; i < n_dst; i++) {
|
|
||||||
channels.push_back(i % n_el);
|
|
||||||
}
|
|
||||||
|
|
||||||
source_value_id = b.createRvalueSwizzle(spv::NoPrecision, storage_type,
|
|
||||||
source_value_id, channels);
|
|
||||||
} else {
|
|
||||||
source_value_id =
|
|
||||||
b.smearScalar(spv::NoPrecision, source_value_id, storage_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// swizzle
|
// swizzle
|
||||||
if (!result.is_standard_swizzle()) {
|
if (!result.is_standard_swizzle() && !source_is_scalar) {
|
||||||
std::vector<uint32_t> operands;
|
std::vector<uint32_t> operands;
|
||||||
operands.push_back(source_value_id);
|
operands.push_back(source_value_id);
|
||||||
operands.push_back(b.makeCompositeConstant(
|
operands.push_back(b.makeCompositeConstant(
|
||||||
|
@ -2471,6 +2491,7 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id,
|
||||||
|
|
||||||
// Components start from left and are duplicated rightwards
|
// Components start from left and are duplicated rightwards
|
||||||
// e.g. count = 1, xxxx / count = 2, xyyy ...
|
// e.g. count = 1, xxxx / count = 2, xyyy ...
|
||||||
|
uint32_t source_components = b.getNumComponents(source_value_id);
|
||||||
for (int i = 0; i < b.getNumTypeComponents(storage_type); i++) {
|
for (int i = 0; i < b.getNumTypeComponents(storage_type); i++) {
|
||||||
if (!result.write_mask[i]) {
|
if (!result.write_mask[i]) {
|
||||||
// Undefined / don't care.
|
// Undefined / don't care.
|
||||||
|
@ -2493,10 +2514,10 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id,
|
||||||
operands.push_back(3);
|
operands.push_back(3);
|
||||||
break;
|
break;
|
||||||
case SwizzleSource::k0:
|
case SwizzleSource::k0:
|
||||||
operands.push_back(4);
|
operands.push_back(source_components + 0);
|
||||||
break;
|
break;
|
||||||
case SwizzleSource::k1:
|
case SwizzleSource::k1:
|
||||||
operands.push_back(5);
|
operands.push_back(source_components + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2506,7 +2527,7 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
// write mask
|
// write mask
|
||||||
if (!result.has_all_writes()) {
|
if (!result.has_all_writes() && !source_is_scalar) {
|
||||||
std::vector<uint32_t> operands;
|
std::vector<uint32_t> operands;
|
||||||
operands.push_back(source_value_id);
|
operands.push_back(source_value_id);
|
||||||
operands.push_back(storage_value);
|
operands.push_back(storage_value);
|
||||||
|
@ -2518,6 +2539,24 @@ void SpirvShaderTranslator::StoreToResult(Id source_value_id,
|
||||||
|
|
||||||
source_value_id =
|
source_value_id =
|
||||||
b.createOp(spv::Op::OpVectorShuffle, storage_type, operands);
|
b.createOp(spv::Op::OpVectorShuffle, storage_type, operands);
|
||||||
|
} else if (source_is_scalar && !storage_is_scalar) {
|
||||||
|
assert_true(result.num_writes() >= 1);
|
||||||
|
|
||||||
|
if (result.has_all_writes()) {
|
||||||
|
source_value_id =
|
||||||
|
b.smearScalar(spv::NoPrecision, source_value_id, storage_type);
|
||||||
|
} else {
|
||||||
|
// Find first enabled component
|
||||||
|
uint32_t index = 0;
|
||||||
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
|
if (result.write_mask[i]) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
source_value_id = b.createCompositeInsert(source_value_id, storage_value,
|
||||||
|
storage_type, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform store into the pointer.
|
// Perform store into the pointer.
|
||||||
|
|
|
@ -135,7 +135,7 @@ class SpirvShaderTranslator : public ShaderTranslator {
|
||||||
spv::Id pos_ = 0;
|
spv::Id pos_ = 0;
|
||||||
spv::Id push_consts_ = 0;
|
spv::Id push_consts_ = 0;
|
||||||
spv::Id interpolators_ = 0;
|
spv::Id interpolators_ = 0;
|
||||||
spv::Id vertex_id_ = 0;
|
spv::Id vertex_idx_ = 0;
|
||||||
spv::Id frag_outputs_ = 0, frag_depth_ = 0;
|
spv::Id frag_outputs_ = 0, frag_depth_ = 0;
|
||||||
spv::Id samplers_ = 0;
|
spv::Id samplers_ = 0;
|
||||||
spv::Id tex_[4] = {0}; // Images {1D, 2D, 3D, Cube}
|
spv::Id tex_[4] = {0}; // Images {1D, 2D, 3D, Cube}
|
||||||
|
|
Loading…
Reference in New Issue