gl_rasterizer: Properly scale viewports and scissors
This commit is contained in:
parent
05d98d9bbf
commit
4a512d6827
|
@ -214,8 +214,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
|
|
||||||
query_cache.UpdateCounters();
|
query_cache.UpdateCounters();
|
||||||
|
|
||||||
SyncState();
|
|
||||||
|
|
||||||
GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
|
GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()};
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
return;
|
return;
|
||||||
|
@ -223,6 +221,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
|
||||||
pipeline->Configure(is_indexed);
|
pipeline->Configure(is_indexed);
|
||||||
|
|
||||||
|
SyncState();
|
||||||
|
|
||||||
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology);
|
const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology);
|
||||||
BeginTransformFeedback(pipeline, primitive_mode);
|
BeginTransformFeedback(pipeline, primitive_mode);
|
||||||
|
|
||||||
|
@ -554,7 +554,6 @@ void RasterizerOpenGL::SyncViewport() {
|
||||||
}
|
}
|
||||||
glFrontFace(mode);
|
glFrontFace(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty_viewport || flags[Dirty::ClipControl]) {
|
if (dirty_viewport || flags[Dirty::ClipControl]) {
|
||||||
flags[Dirty::ClipControl] = false;
|
flags[Dirty::ClipControl] = false;
|
||||||
|
|
||||||
|
@ -571,6 +570,8 @@ void RasterizerOpenGL::SyncViewport() {
|
||||||
state_tracker.ClipControl(origin, depth);
|
state_tracker.ClipControl(origin, depth);
|
||||||
state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0);
|
state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0);
|
||||||
}
|
}
|
||||||
|
const bool is_rescaling{texture_cache.IsRescaling()};
|
||||||
|
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
|
||||||
|
|
||||||
if (dirty_viewport) {
|
if (dirty_viewport) {
|
||||||
flags[Dirty::Viewports] = false;
|
flags[Dirty::Viewports] = false;
|
||||||
|
@ -579,38 +580,38 @@ void RasterizerOpenGL::SyncViewport() {
|
||||||
flags[Dirty::ViewportTransform] = false;
|
flags[Dirty::ViewportTransform] = false;
|
||||||
flags[VideoCommon::Dirty::RescaleViewports] = false;
|
flags[VideoCommon::Dirty::RescaleViewports] = false;
|
||||||
|
|
||||||
const auto& resolution = Settings::values.resolution_info;
|
for (size_t index = 0; index < Maxwell::NumViewports; ++index) {
|
||||||
const auto scale_up = [&](u32 value) -> u32 {
|
if (!force && !flags[Dirty::Viewport0 + index]) {
|
||||||
if (value == 0) {
|
|
||||||
return 0U;
|
|
||||||
}
|
|
||||||
const u32 converted_value = (value * resolution.up_scale) >> resolution.down_shift;
|
|
||||||
return std::max<u32>(converted_value, 1U);
|
|
||||||
};
|
|
||||||
for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
|
|
||||||
if (!force && !flags[Dirty::Viewport0 + i]) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
flags[Dirty::Viewport0 + i] = false;
|
flags[Dirty::Viewport0 + index] = false;
|
||||||
|
|
||||||
const auto& src = regs.viewport_transform[i];
|
const auto& src = regs.viewport_transform[index];
|
||||||
const Common::Rectangle<f32> rect{src.GetRect()};
|
GLfloat x = (src.translate_x - src.scale_x) * scale;
|
||||||
glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom,
|
GLfloat y = (src.translate_y - src.scale_y) * scale;
|
||||||
scale_up(rect.GetWidth()), scale_up(rect.GetHeight()));
|
GLfloat width = src.scale_x * 2.0f * scale;
|
||||||
|
GLfloat height = src.scale_y * 2.0f * scale;
|
||||||
|
if (height < 0) {
|
||||||
|
y += height;
|
||||||
|
height = -height;
|
||||||
|
}
|
||||||
|
glViewportIndexedf(static_cast<GLuint>(index), x, y, width != 0.0f ? width : 1.0f,
|
||||||
|
height != 0.0f ? height : 1.0f);
|
||||||
|
|
||||||
const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne;
|
const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne;
|
||||||
const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z;
|
const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z;
|
||||||
const GLdouble far_depth = src.translate_z + src.scale_z;
|
const GLdouble far_depth = src.translate_z + src.scale_z;
|
||||||
if (device.HasDepthBufferFloat()) {
|
if (device.HasDepthBufferFloat()) {
|
||||||
glDepthRangeIndexeddNV(static_cast<GLuint>(i), near_depth, far_depth);
|
glDepthRangeIndexeddNV(static_cast<GLuint>(index), near_depth, far_depth);
|
||||||
} else {
|
} else {
|
||||||
glDepthRangeIndexed(static_cast<GLuint>(i), near_depth, far_depth);
|
glDepthRangeIndexed(static_cast<GLuint>(index), near_depth, far_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLAD_GL_NV_viewport_swizzle) {
|
if (!GLAD_GL_NV_viewport_swizzle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glViewportSwizzleNV(static_cast<GLuint>(i), MaxwellToGL::ViewportSwizzle(src.swizzle.x),
|
glViewportSwizzleNV(static_cast<GLuint>(index),
|
||||||
|
MaxwellToGL::ViewportSwizzle(src.swizzle.x),
|
||||||
MaxwellToGL::ViewportSwizzle(src.swizzle.y),
|
MaxwellToGL::ViewportSwizzle(src.swizzle.y),
|
||||||
MaxwellToGL::ViewportSwizzle(src.swizzle.z),
|
MaxwellToGL::ViewportSwizzle(src.swizzle.z),
|
||||||
MaxwellToGL::ViewportSwizzle(src.swizzle.w));
|
MaxwellToGL::ViewportSwizzle(src.swizzle.w));
|
||||||
|
@ -940,7 +941,7 @@ void RasterizerOpenGL::SyncScissorTest() {
|
||||||
const auto& src = regs.scissor_test[index];
|
const auto& src = regs.scissor_test[index];
|
||||||
if (src.enable) {
|
if (src.enable) {
|
||||||
glEnablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
|
glEnablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
|
||||||
glScissorIndexed(static_cast<GLuint>(index), src.min_x, src.min_y,
|
glScissorIndexed(static_cast<GLuint>(index), scale_up(src.min_x), scale_up(src.min_y),
|
||||||
scale_up(src.max_x - src.min_x), scale_up(src.max_y - src.min_y));
|
scale_up(src.max_x - src.min_x), scale_up(src.max_y - src.min_y));
|
||||||
} else {
|
} else {
|
||||||
glDisablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
|
glDisablei(GL_SCISSOR_TEST, static_cast<GLuint>(index));
|
||||||
|
|
Reference in New Issue