NOTES:
regs.window_origin.flip_y MUST flip the y coordinate of any given FragCoord, we don't emulate this, this is the root cause of the error, but I'll just revert for now since it's easier
DON'T MERGE unless it's near 0.0.4 and I (or someone else) hasn't tackled this yet properly
This reverts commit 17fe74ef11.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3075
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
fe13539d72
commit
ed39ec4738
|
|
@ -62,29 +62,41 @@ struct DrawParams {
|
||||||
VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index, float scale) {
|
VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index, float scale) {
|
||||||
const auto& src = regs.viewport_transform[index];
|
const auto& src = regs.viewport_transform[index];
|
||||||
const auto conv = [scale](float value) {
|
const auto conv = [scale](float value) {
|
||||||
float const new_value = value * scale;
|
float new_value = value * scale;
|
||||||
return scale < 1.0f
|
if (scale < 1.0f) {
|
||||||
? std::round(std::abs(new_value)) * (std::signbit(new_value) ? -1.f : 1.f)
|
const bool sign = std::signbit(value);
|
||||||
: new_value;
|
new_value = std::round(std::abs(new_value));
|
||||||
|
new_value = sign ? -new_value : new_value;
|
||||||
|
}
|
||||||
|
return new_value;
|
||||||
};
|
};
|
||||||
float const w = src.scale_x;
|
const float x = conv(src.translate_x - src.scale_x);
|
||||||
float h = src.scale_y;
|
const float width = conv(src.scale_x * 2.0f);
|
||||||
if (regs.window_origin.mode == Maxwell::WindowOrigin::Mode::LowerLeft) // Flip by surface clip height
|
float y = conv(src.translate_y - src.scale_y);
|
||||||
h = -h;
|
float height = conv(src.scale_y * 2.0f);
|
||||||
if (!device.IsNvViewportSwizzleSupported() && src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY) // Flip by viewport height
|
|
||||||
h = -h;
|
const bool lower_left = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft;
|
||||||
// In theory, a raster flip is equivalent to a texture flip for a whole square viewport
|
const bool y_negate = !device.IsNvViewportSwizzleSupported() &&
|
||||||
// TODO: one day implement this properly and raster flip the triangles, not the whole viewport... guh
|
src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY;
|
||||||
if(regs.viewport_transform[1].scale_y == 0 && regs.window_origin.flip_y != 0)
|
|
||||||
h = -h;
|
if (lower_left) {
|
||||||
float const x = src.translate_x - w;
|
// Flip by surface clip height
|
||||||
float const y = src.translate_y - h;
|
y += conv(static_cast<f32>(regs.surface_clip.height));
|
||||||
float const reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f;
|
height = -height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y_negate) {
|
||||||
|
// Flip by viewport height
|
||||||
|
y += height;
|
||||||
|
height = -height;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f;
|
||||||
VkViewport viewport{
|
VkViewport viewport{
|
||||||
.x = conv(x),
|
.x = x,
|
||||||
.y = conv(y),
|
.y = y,
|
||||||
.width = w != 0.0f ? conv(w * 2.f) : 1.0f,
|
.width = width != 0.0f ? width : 1.0f,
|
||||||
.height = h != 0.0f ? conv(h * 2.f) : 1.0f,
|
.height = height != 0.0f ? height : 1.0f,
|
||||||
.minDepth = src.translate_z - src.scale_z * reduce_z,
|
.minDepth = src.translate_z - src.scale_z * reduce_z,
|
||||||
.maxDepth = src.translate_z + src.scale_z,
|
.maxDepth = src.translate_z + src.scale_z,
|
||||||
};
|
};
|
||||||
|
|
@ -1014,10 +1026,10 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!regs.viewport_scale_offset_enabled) {
|
if (!regs.viewport_scale_offset_enabled) {
|
||||||
float x = float(regs.surface_clip.x);
|
float x = static_cast<float>(regs.surface_clip.x);
|
||||||
float y = float(regs.surface_clip.y);
|
float y = static_cast<float>(regs.surface_clip.y);
|
||||||
float width = (std::max)(1.0f, float(regs.surface_clip.width));
|
float width = (std::max)(1.0f, static_cast<float>(regs.surface_clip.width));
|
||||||
float height = (std::max)(1.0f, float(regs.surface_clip.height));
|
float height = (std::max)(1.0f, static_cast<float>(regs.surface_clip.height));
|
||||||
if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) {
|
if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) {
|
||||||
y += height;
|
y += height;
|
||||||
height = -height;
|
height = -height;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue