spirv: Add fragdepth and implement image query
This commit is contained in:
parent
1f83824a8a
commit
5da79d4798
|
@ -31,6 +31,8 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) {
|
||||||
return arg.U32();
|
return arg.U32();
|
||||||
} else if constexpr (std::is_same_v<ArgType, u64>) {
|
} else if constexpr (std::is_same_v<ArgType, u64>) {
|
||||||
return arg.U64();
|
return arg.U64();
|
||||||
|
} else if constexpr (std::is_same_v<ArgType, bool>) {
|
||||||
|
return arg.U1();
|
||||||
} else if constexpr (std::is_same_v<ArgType, IR::Attribute>) {
|
} else if constexpr (std::is_same_v<ArgType, IR::Attribute>) {
|
||||||
return arg.Attribute();
|
return arg.Attribute();
|
||||||
} else if constexpr (std::is_same_v<ArgType, IR::ScalarReg>) {
|
} else if constexpr (std::is_same_v<ArgType, IR::ScalarReg>) {
|
||||||
|
|
|
@ -31,6 +31,8 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
||||||
return ctx.frag_color[index];
|
return ctx.frag_color[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case IR::Attribute::Depth:
|
||||||
|
return ctx.frag_depth;
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Read attribute {}", attr);
|
throw NotImplementedException("Read attribute {}", attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,30 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id of
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips) {
|
||||||
const IR::Value& skip_mips_val) {
|
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||||
|
const Id image = ctx.OpLoad(texture.image_type, texture.id);
|
||||||
|
const auto type = ctx.info.images[handle & 0xFFFF].type;
|
||||||
|
const Id zero = ctx.u32_zero_value;
|
||||||
|
const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }};
|
||||||
|
const bool uses_lod{type != AmdGpu::ImageType::Color2DMsaa && type != AmdGpu::ImageType::Buffer};
|
||||||
|
const auto query{[&](Id type) {
|
||||||
|
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
|
||||||
|
: ctx.OpImageQuerySize(type, image);
|
||||||
|
}};
|
||||||
|
switch (type) {
|
||||||
|
case AmdGpu::ImageType::Color1D:
|
||||||
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
|
||||||
|
case AmdGpu::ImageType::Color1DArray:
|
||||||
|
case AmdGpu::ImageType::Color2D:
|
||||||
|
case AmdGpu::ImageType::Cube:
|
||||||
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips());
|
||||||
|
case AmdGpu::ImageType::Color2DArray:
|
||||||
|
case AmdGpu::ImageType::Color3D:
|
||||||
|
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[3]), mips());
|
||||||
|
default:
|
||||||
throw NotImplementedException("SPIR-V Instruction");
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
|
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
|
||||||
|
|
|
@ -348,8 +348,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
|
||||||
const IR::Value& offset, const IR::Value& offset2, Id dref);
|
const IR::Value& offset, const IR::Value& offset2, Id dref);
|
||||||
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod,
|
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id offset, Id lod,
|
||||||
Id ms);
|
Id ms);
|
||||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips);
|
||||||
const IR::Value& skip_mips);
|
|
||||||
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
|
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
|
||||||
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||||
Id derivatives, const IR::Value& offset, Id lod_clamp);
|
Id derivatives, const IR::Value& offset, Id lod_clamp);
|
||||||
|
|
|
@ -187,6 +187,7 @@ void EmitContext::DefineInputs(const Info& info) {
|
||||||
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
|
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
|
||||||
}
|
}
|
||||||
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
||||||
|
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
||||||
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
||||||
for (const auto& input : info.ps_inputs) {
|
for (const auto& input : info.ps_inputs) {
|
||||||
const u32 semantic = input.param_index;
|
const u32 semantic = input.param_index;
|
||||||
|
|
|
@ -160,6 +160,7 @@ public:
|
||||||
Id base_vertex{};
|
Id base_vertex{};
|
||||||
Id frag_coord{};
|
Id frag_coord{};
|
||||||
Id front_facing{};
|
Id front_facing{};
|
||||||
|
Id frag_depth{};
|
||||||
std::array<Id, 8> frag_color{};
|
std::array<Id, 8> frag_color{};
|
||||||
std::array<u32, 8> frag_num_comp{};
|
std::array<u32, 8> frag_num_comp{};
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ void Translator::S_MOV_B64(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::S_OR_B64(NegateMode negate, const GcnInst& inst) {
|
void Translator::S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst) {
|
||||||
const auto get_src = [&](const InstOperand& operand) {
|
const auto get_src = [&](const InstOperand& operand) {
|
||||||
switch (operand.field) {
|
switch (operand.field) {
|
||||||
case OperandField::ExecLo:
|
case OperandField::ExecLo:
|
||||||
|
@ -123,7 +123,7 @@ void Translator::S_OR_B64(NegateMode negate, const GcnInst& inst) {
|
||||||
if (negate == NegateMode::Src1) {
|
if (negate == NegateMode::Src1) {
|
||||||
src1 = ir.LogicalNot(src1);
|
src1 = ir.LogicalNot(src1);
|
||||||
}
|
}
|
||||||
IR::U1 result = ir.LogicalOr(src0, src1);
|
IR::U1 result = is_xor ? ir.LogicalXor(src0, src1) : ir.LogicalOr(src0, src1);
|
||||||
if (negate == NegateMode::Result) {
|
if (negate == NegateMode::Result) {
|
||||||
result = ir.LogicalNot(result);
|
result = ir.LogicalNot(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::V_CMP_NLT_F32:
|
case Opcode::V_CMP_NLT_F32:
|
||||||
translator.V_CMP_F32(ConditionOp::GE, false, inst);
|
translator.V_CMP_F32(ConditionOp::GE, false, inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::V_CMP_NGT_F32:
|
||||||
|
translator.V_CMP_F32(ConditionOp::LE, false, inst);
|
||||||
|
break;
|
||||||
case Opcode::S_CMP_LT_U32:
|
case Opcode::S_CMP_LT_U32:
|
||||||
translator.S_CMP(ConditionOp::LT, false, inst);
|
translator.S_CMP(ConditionOp::LT, false, inst);
|
||||||
break;
|
break;
|
||||||
|
@ -473,7 +476,7 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
translator.S_AND_B64(NegateMode::Src1, inst);
|
translator.S_AND_B64(NegateMode::Src1, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::S_ORN2_B64:
|
case Opcode::S_ORN2_B64:
|
||||||
translator.S_OR_B64(NegateMode::Src1, inst);
|
translator.S_OR_B64(NegateMode::Src1, false, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::V_SIN_F32:
|
case Opcode::V_SIN_F32:
|
||||||
translator.V_SIN_F32(inst);
|
translator.V_SIN_F32(inst);
|
||||||
|
@ -612,10 +615,13 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
translator.V_CMP_U32(ConditionOp::TRU, false, true, inst);
|
translator.V_CMP_U32(ConditionOp::TRU, false, true, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::S_OR_B64:
|
case Opcode::S_OR_B64:
|
||||||
translator.S_OR_B64(NegateMode::None, inst);
|
translator.S_OR_B64(NegateMode::None, false, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::S_NOR_B64:
|
case Opcode::S_NOR_B64:
|
||||||
translator.S_OR_B64(NegateMode::Result, inst);
|
translator.S_OR_B64(NegateMode::Result, false, inst);
|
||||||
|
break;
|
||||||
|
case Opcode::S_XOR_B64:
|
||||||
|
translator.S_OR_B64(NegateMode::None, true, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::S_AND_B64:
|
case Opcode::S_AND_B64:
|
||||||
translator.S_AND_B64(NegateMode::None, inst);
|
translator.S_AND_B64(NegateMode::None, inst);
|
||||||
|
@ -739,6 +745,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::V_RCP_IFLAG_F32:
|
case Opcode::V_RCP_IFLAG_F32:
|
||||||
translator.V_RCP_F32(inst);
|
translator.V_RCP_F32(inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::IMAGE_GET_RESINFO:
|
||||||
|
translator.IMAGE_GET_RESINFO(inst);
|
||||||
|
break;
|
||||||
case Opcode::S_TTRACEDATA:
|
case Opcode::S_TTRACEDATA:
|
||||||
LOG_WARNING(Render_Vulkan, "S_TTRACEDATA instruction!");
|
LOG_WARNING(Render_Vulkan, "S_TTRACEDATA instruction!");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
|
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
|
||||||
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
||||||
void S_MOV_B64(const GcnInst& inst);
|
void S_MOV_B64(const GcnInst& inst);
|
||||||
void S_OR_B64(NegateMode negate, const GcnInst& inst);
|
void S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst);
|
||||||
void S_AND_B64(NegateMode negate, const GcnInst& inst);
|
void S_AND_B64(NegateMode negate, const GcnInst& inst);
|
||||||
void S_ADD_I32(const GcnInst& inst);
|
void S_ADD_I32(const GcnInst& inst);
|
||||||
void S_AND_B32(const GcnInst& inst);
|
void S_AND_B32(const GcnInst& inst);
|
||||||
|
|
|
@ -6,14 +6,13 @@
|
||||||
namespace Shader::Gcn {
|
namespace Shader::Gcn {
|
||||||
|
|
||||||
void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {
|
void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {
|
||||||
IR::VectorReg dst_reg{inst.src[1].code};
|
IR::VectorReg dst_reg{inst.dst[0].code};
|
||||||
const IR::ScalarReg tsharp_reg{inst.src[2].code};
|
const IR::ScalarReg tsharp_reg{inst.src[2].code};
|
||||||
const auto flags = ImageResFlags(inst.control.mimg.dmask);
|
const auto flags = ImageResFlags(inst.control.mimg.dmask);
|
||||||
|
const bool has_mips = flags.test(ImageResComponent::MipCount);
|
||||||
const IR::U32 lod = ir.GetVectorReg(IR::VectorReg(inst.src[0].code));
|
const IR::U32 lod = ir.GetVectorReg(IR::VectorReg(inst.src[0].code));
|
||||||
const IR::Value tsharp =
|
const IR::Value tsharp = ir.GetScalarReg(tsharp_reg);
|
||||||
ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1),
|
const IR::Value size = ir.ImageQueryDimension(tsharp, lod, ir.Imm1(has_mips));
|
||||||
ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3));
|
|
||||||
const IR::Value size = ir.ImageQueryDimension(tsharp, lod, ir.Imm1(false));
|
|
||||||
|
|
||||||
if (flags.test(ImageResComponent::Width)) {
|
if (flags.test(ImageResComponent::Width)) {
|
||||||
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 0)});
|
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 0)});
|
||||||
|
@ -24,7 +23,7 @@ void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {
|
||||||
if (flags.test(ImageResComponent::Depth)) {
|
if (flags.test(ImageResComponent::Depth)) {
|
||||||
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 2)});
|
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 2)});
|
||||||
}
|
}
|
||||||
if (flags.test(ImageResComponent::MipCount)) {
|
if (has_mips) {
|
||||||
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 3)});
|
ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 3)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue