account for max viewport limit, add todo for ViewportIndex

This commit is contained in:
Vladislav Mikhalin 2025-01-17 19:13:38 +03:00
parent b6f2ce34e0
commit 172308aab4
5 changed files with 33 additions and 14 deletions

View File

@ -47,14 +47,14 @@ void ConvertPositionToClipSpace(EmitContext& ctx) {
ctx.push_data_block,
ctx.ConstU32(PushData::YScaleIndex))};
const Id yscale{ctx.OpLoad(type, yscale_ptr)};
Id ndc_x = ctx.OpFMul(type, x, xscale);
ndc_x = ctx.OpFAdd(type, ndc_x, xoffset);
ndc_x = ctx.OpFDiv(type, ndc_x, ctx.Constant(type, float(8_KB)));
ndc_x = ctx.OpFSub(type, ndc_x, ctx.Constant(type, 1.f));
Id ndc_y = ctx.OpFMul(type, y, yscale);
ndc_y = ctx.OpFAdd(type, ndc_y, yoffset);
ndc_y = ctx.OpFDiv(type, ndc_y, ctx.Constant(type, float(8_KB)));
ndc_y = ctx.OpFSub(type, ndc_y, ctx.Constant(type, 1.f));
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);
}

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

@ -274,6 +274,14 @@ public:
return min_imported_host_pointer_alignment;
}
u32 GetMaxViewportWidth() const {
return properties.limits.maxViewportDimensions[0];
}
u32 GetMaxViewportHeight() const {
return properties.limits.maxViewportDimensions[1];
}
/// Returns the sample count flags supported by framebuffers.
vk::SampleCountFlags GetFramebufferSampleCounts() const {
return properties.limits.framebufferColorSampleCounts &

View File

@ -210,6 +210,8 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
.needs_lds_barriers = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary ||
instance.GetDriverID() == vk::DriverId::eMoltenvk,
.max_viewport_width = instance.GetMaxViewportWidth(),
.max_viewport_height = instance.GetMaxViewportHeight(),
};
auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({});
ASSERT_MSG(cache_result == vk::Result::eSuccess, "Failed to create pipeline cache: {}",

View File

@ -504,10 +504,17 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) {
}
push_data.step0 = regs.vgt_instance_step_rate_0;
push_data.step1 = regs.vgt_instance_step_rate_1;
push_data.xoffset = regs.viewport_control.xoffset_enable ? regs.viewports[0].xoffset : 0.f;
// TODO(roamic): add support for multiple viewports and geometry shaders when ViewportIndex
// is encountered and implemented in the recompiler.
if (stage->stage == Shader::Stage::Vertex) {
push_data.xoffset =
regs.viewport_control.xoffset_enable ? regs.viewports[0].xoffset : 0.f;
push_data.xscale = regs.viewport_control.xscale_enable ? regs.viewports[0].xscale : 1.f;
push_data.yoffset = regs.viewport_control.yoffset_enable ? regs.viewports[0].yoffset : 0.f;
push_data.yoffset =
regs.viewport_control.yoffset_enable ? regs.viewports[0].yoffset : 0.f;
push_data.yscale = regs.viewport_control.yscale_enable ? regs.viewports[0].yscale : 1.f;
}
stage->PushUd(binding, push_data);
BindBuffers(*stage, binding, push_data, set_writes, buffer_barriers);
@ -1174,8 +1181,8 @@ void Rasterizer::UpdateViewportScissorState(const GraphicsPipeline& pipeline) {
viewports.push_back({
.x = 0.f,
.y = 0.f,
.width = float(16_KB),
.height = float(16_KB),
.width = float(std::min<u32>(instance.GetMaxViewportWidth(), 16_KB)),
.height = float(std::min<u32>(instance.GetMaxViewportHeight(), 16_KB)),
.minDepth = 0.0,
.maxDepth = 1.0,
});