renderer: handle disabled clipping (#2146)

Co-authored-by: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com>
This commit is contained in:
Vladislav Mikhalin 2025-01-18 09:20:38 +03:00 committed by GitHub
parent a5440e0e43
commit 7b8177f48e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 149 additions and 35 deletions

View file

@ -24,10 +24,48 @@ void ConvertDepthMode(EmitContext& ctx) {
ctx.OpStore(ctx.output_position, vector);
}
void ConvertPositionToClipSpace(EmitContext& ctx) {
const Id type{ctx.F32[1]};
Id position{ctx.OpLoad(ctx.F32[4], ctx.output_position)};
const Id x{ctx.OpCompositeExtract(type, position, 0u)};
const Id y{ctx.OpCompositeExtract(type, position, 1u)};
const Id z{ctx.OpCompositeExtract(type, position, 2u)};
const Id w{ctx.OpCompositeExtract(type, position, 3u)};
const Id xoffset_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type),
ctx.push_data_block,
ctx.ConstU32(PushData::XOffsetIndex))};
const Id xoffset{ctx.OpLoad(type, xoffset_ptr)};
const Id yoffset_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type),
ctx.push_data_block,
ctx.ConstU32(PushData::YOffsetIndex))};
const Id yoffset{ctx.OpLoad(type, yoffset_ptr)};
const Id xscale_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type),
ctx.push_data_block,
ctx.ConstU32(PushData::XScaleIndex))};
const Id xscale{ctx.OpLoad(type, xscale_ptr)};
const Id yscale_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type),
ctx.push_data_block,
ctx.ConstU32(PushData::YScaleIndex))};
const Id yscale{ctx.OpLoad(type, yscale_ptr)};
const Id vport_w =
ctx.Constant(type, float(std::min<u32>(ctx.profile.max_viewport_width / 2, 8_KB)));
const Id wnd_x = ctx.OpFAdd(type, ctx.OpFMul(type, x, xscale), xoffset);
const Id ndc_x = ctx.OpFSub(type, ctx.OpFDiv(type, wnd_x, vport_w), ctx.Constant(type, 1.f));
const Id vport_h =
ctx.Constant(type, float(std::min<u32>(ctx.profile.max_viewport_height / 2, 8_KB)));
const Id wnd_y = ctx.OpFAdd(type, ctx.OpFMul(type, y, yscale), yoffset);
const Id ndc_y = ctx.OpFSub(type, ctx.OpFDiv(type, wnd_y, vport_h), ctx.Constant(type, 1.f));
const Id vector{ctx.OpCompositeConstruct(ctx.F32[4], std::array<Id, 4>({ndc_x, ndc_y, z, w}))};
ctx.OpStore(ctx.output_position, vector);
}
void EmitEpilogue(EmitContext& ctx) {
if (ctx.stage == Stage::Vertex && ctx.runtime_info.vs_info.emulate_depth_negative_one_to_one) {
ConvertDepthMode(ctx);
}
if (ctx.stage == Stage::Vertex && ctx.runtime_info.vs_info.clip_disable) {
ConvertPositionToClipSpace(ctx);
}
}
void EmitDiscard(EmitContext& ctx) {

View file

@ -568,25 +568,34 @@ void EmitContext::DefineOutputs() {
void EmitContext::DefinePushDataBlock() {
// Create push constants block for instance steps rates
const Id struct_type{Name(
TypeStruct(U32[1], U32[1], U32[4], U32[4], U32[4], U32[4], U32[4], U32[4]), "AuxData")};
const Id struct_type{Name(TypeStruct(U32[1], U32[1], U32[4], U32[4], U32[4], U32[4], U32[4],
U32[4], F32[1], F32[1], F32[1], F32[1]),
"AuxData")};
Decorate(struct_type, spv::Decoration::Block);
MemberName(struct_type, 0, "sr0");
MemberName(struct_type, 1, "sr1");
MemberName(struct_type, 2, "buf_offsets0");
MemberName(struct_type, 3, "buf_offsets1");
MemberName(struct_type, 4, "ud_regs0");
MemberName(struct_type, 5, "ud_regs1");
MemberName(struct_type, 6, "ud_regs2");
MemberName(struct_type, 7, "ud_regs3");
MemberName(struct_type, Shader::PushData::BufOffsetIndex + 0, "buf_offsets0");
MemberName(struct_type, Shader::PushData::BufOffsetIndex + 1, "buf_offsets1");
MemberName(struct_type, Shader::PushData::UdRegsIndex + 0, "ud_regs0");
MemberName(struct_type, Shader::PushData::UdRegsIndex + 1, "ud_regs1");
MemberName(struct_type, Shader::PushData::UdRegsIndex + 2, "ud_regs2");
MemberName(struct_type, Shader::PushData::UdRegsIndex + 3, "ud_regs3");
MemberName(struct_type, Shader::PushData::XOffsetIndex, "xoffset");
MemberName(struct_type, Shader::PushData::YOffsetIndex, "yoffset");
MemberName(struct_type, Shader::PushData::XScaleIndex, "xscale");
MemberName(struct_type, Shader::PushData::YScaleIndex, "yscale");
MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U);
MemberDecorate(struct_type, 1, spv::Decoration::Offset, 4U);
MemberDecorate(struct_type, 2, spv::Decoration::Offset, 8U);
MemberDecorate(struct_type, 3, spv::Decoration::Offset, 24U);
MemberDecorate(struct_type, 4, spv::Decoration::Offset, 40U);
MemberDecorate(struct_type, 5, spv::Decoration::Offset, 56U);
MemberDecorate(struct_type, 6, spv::Decoration::Offset, 72U);
MemberDecorate(struct_type, 7, spv::Decoration::Offset, 88U);
MemberDecorate(struct_type, Shader::PushData::BufOffsetIndex + 0, spv::Decoration::Offset, 8U);
MemberDecorate(struct_type, Shader::PushData::BufOffsetIndex + 1, spv::Decoration::Offset, 24U);
MemberDecorate(struct_type, Shader::PushData::UdRegsIndex + 0, spv::Decoration::Offset, 40U);
MemberDecorate(struct_type, Shader::PushData::UdRegsIndex + 1, spv::Decoration::Offset, 56U);
MemberDecorate(struct_type, Shader::PushData::UdRegsIndex + 2, spv::Decoration::Offset, 72U);
MemberDecorate(struct_type, Shader::PushData::UdRegsIndex + 3, spv::Decoration::Offset, 88U);
MemberDecorate(struct_type, Shader::PushData::XOffsetIndex, spv::Decoration::Offset, 104U);
MemberDecorate(struct_type, Shader::PushData::YOffsetIndex, spv::Decoration::Offset, 108U);
MemberDecorate(struct_type, Shader::PushData::XScaleIndex, spv::Decoration::Offset, 112U);
MemberDecorate(struct_type, Shader::PushData::YScaleIndex, spv::Decoration::Offset, 116U);
push_data_block = DefineVar(struct_type, spv::StorageClass::PushConstant);
Name(push_data_block, "push_data");
interfaces.push_back(push_data_block);

View file

@ -96,11 +96,19 @@ using FMaskResourceList = boost::container::small_vector<FMaskResource, 16>;
struct PushData {
static constexpr u32 BufOffsetIndex = 2;
static constexpr u32 UdRegsIndex = 4;
static constexpr u32 XOffsetIndex = 8;
static constexpr u32 YOffsetIndex = 9;
static constexpr u32 XScaleIndex = 10;
static constexpr u32 YScaleIndex = 11;
u32 step0;
u32 step1;
std::array<u8, 32> buf_offsets;
std::array<u32, NumUserDataRegs> ud_regs;
float xoffset;
float yoffset;
float xscale;
float yscale;
void AddOffset(u32 binding, u32 offset) {
ASSERT(offset < 256 && binding < buf_offsets.size());

View file

@ -30,6 +30,8 @@ struct Profile {
bool needs_manual_interpolation{};
bool needs_lds_barriers{};
u64 min_ssbo_alignment{};
u32 max_viewport_width{};
u32 max_viewport_height{};
};
} // namespace Shader

View file

@ -84,6 +84,7 @@ struct VertexRuntimeInfo {
u32 num_outputs;
std::array<VsOutputMap, 3> outputs;
bool emulate_depth_negative_one_to_one{};
bool clip_disable{};
// Domain
AmdGpu::TessellationType tess_type;
AmdGpu::TessellationTopology tess_topology;
@ -92,7 +93,8 @@ struct VertexRuntimeInfo {
bool operator==(const VertexRuntimeInfo& other) const noexcept {
return emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one &&
tess_type == other.tess_type && tess_topology == other.tess_topology &&
clip_disable == other.clip_disable && tess_type == other.tess_type &&
tess_topology == other.tess_topology &&
tess_partitioning == other.tess_partitioning &&
hs_output_cp_stride == other.hs_output_cp_stride;
}