gl_state: Remove viewport and depth range tracking

This commit is contained in:
ReinUsesLisp 2019-12-26 01:50:38 -03:00
parent 7c16b3551b
commit d3e433a380
7 changed files with 39 additions and 101 deletions

View file

@ -574,7 +574,7 @@ public:
f32 translate_z; f32 translate_z;
INSERT_UNION_PADDING_WORDS(2); INSERT_UNION_PADDING_WORDS(2);
Common::Rectangle<s32> GetRect() const { Common::Rectangle<f32> GetRect() const {
return { return {
GetX(), // left GetX(), // left
GetY() + GetHeight(), // top GetY() + GetHeight(), // top
@ -583,20 +583,20 @@ public:
}; };
}; };
s32 GetX() const { f32 GetX() const {
return static_cast<s32>(std::max(0.0f, translate_x - std::fabs(scale_x))); return std::max(0.0f, translate_x - std::fabs(scale_x));
} }
s32 GetY() const { f32 GetY() const {
return static_cast<s32>(std::max(0.0f, translate_y - std::fabs(scale_y))); return std::max(0.0f, translate_y - std::fabs(scale_y));
} }
s32 GetWidth() const { f32 GetWidth() const {
return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX(); return translate_x + std::fabs(scale_x) - GetX();
} }
s32 GetHeight() const { f32 GetHeight() const {
return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY(); return translate_y + std::fabs(scale_y) - GetY();
} }
}; };

View file

@ -360,7 +360,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
texture_cache.GuardRenderTargets(false); texture_cache.GuardRenderTargets(false);
state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key); state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
SyncViewport(state);
} }
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
@ -405,7 +404,6 @@ void RasterizerOpenGL::Clear() {
SCOPE_EXIT({ prev_state.Apply(); }); SCOPE_EXIT({ prev_state.Apply(); });
OpenGLState clear_state{OpenGLState::GetCurState()}; OpenGLState clear_state{OpenGLState::GetCurState()};
clear_state.SetDefaultViewports();
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
regs.clear_buffers.A) { regs.clear_buffers.A) {
use_color = true; use_color = true;
@ -464,7 +462,6 @@ void RasterizerOpenGL::Clear() {
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
SyncViewport(clear_state);
SyncRasterizeEnable(clear_state); SyncRasterizeEnable(clear_state);
if (regs.clear_flags.scissor) { if (regs.clear_flags.scissor) {
SyncScissorTest(); SyncScissorTest();
@ -496,6 +493,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
query_cache.UpdateCounters(); query_cache.UpdateCounters();
SyncViewport();
SyncRasterizeEnable(state); SyncRasterizeEnable(state);
SyncColorMask(); SyncColorMask();
SyncFragmentColorClampState(); SyncFragmentColorClampState();
@ -935,22 +933,14 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
state.images[binding] = view->GetTexture(); state.images[binding] = view->GetTexture();
} }
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { void RasterizerOpenGL::SyncViewport() {
const auto& regs = system.GPU().Maxwell3D().regs; const auto& regs = system.GPU().Maxwell3D().regs;
const bool geometry_shaders_enabled = for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
const std::size_t viewport_count =
geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
for (std::size_t i = 0; i < viewport_count; i++) {
auto& viewport = current_state.viewports[i];
const auto& src = regs.viewports[i]; const auto& src = regs.viewports[i];
const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()}; const Common::Rectangle<f32> rect{regs.viewport_transform[i].GetRect()};
viewport.x = viewport_rect.left; glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(),
viewport.y = viewport_rect.bottom; rect.GetHeight());
viewport.width = viewport_rect.GetWidth(); glDepthRangef(src.depth_range_near, src.depth_range_far);
viewport.height = viewport_rect.GetHeight();
viewport.depth_range_far = src.depth_range_far;
viewport.depth_range_near = src.depth_range_near;
} }
bool flip_y = false; bool flip_y = false;

View file

@ -130,7 +130,7 @@ private:
const GLShader::ImageEntry& entry); const GLShader::ImageEntry& entry);
/// Syncs the viewport and depth range to match the guest state /// Syncs the viewport and depth range to match the guest state
void SyncViewport(OpenGLState& current_state); void SyncViewport();
/// Syncs the depth clamp state /// Syncs the depth clamp state
void SyncDepthClamp(); void SyncDepthClamp();

View file

@ -85,10 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
OpenGLState::OpenGLState() = default; OpenGLState::OpenGLState() = default;
void OpenGLState::SetDefaultViewports() {
viewports.fill(Viewport{});
}
void OpenGLState::ApplyFramebufferState() { void OpenGLState::ApplyFramebufferState() {
if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
@ -150,30 +146,6 @@ void OpenGLState::ApplyStencilTest() {
ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back);
} }
void OpenGLState::ApplyViewport() {
for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) {
const auto& updated = viewports[i];
auto& current = cur_state.viewports[i];
if (current.x != updated.x || current.y != updated.y || current.width != updated.width ||
current.height != updated.height) {
current.x = updated.x;
current.y = updated.y;
current.width = updated.width;
current.height = updated.height;
glViewportIndexedf(i, static_cast<GLfloat>(updated.x), static_cast<GLfloat>(updated.y),
static_cast<GLfloat>(updated.width),
static_cast<GLfloat>(updated.height));
}
if (current.depth_range_near != updated.depth_range_near ||
current.depth_range_far != updated.depth_range_far) {
current.depth_range_near = updated.depth_range_near;
current.depth_range_far = updated.depth_range_far;
glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far);
}
}
}
void OpenGLState::ApplyGlobalBlending() { void OpenGLState::ApplyGlobalBlending() {
const Blend& updated = blend[0]; const Blend& updated = blend[0];
Blend& current = cur_state.blend[0]; Blend& current = cur_state.blend[0];
@ -283,7 +255,6 @@ void OpenGLState::Apply() {
ApplyProgramPipeline(); ApplyProgramPipeline();
ApplyClipDistances(); ApplyClipDistances();
ApplyRasterizerDiscard(); ApplyRasterizerDiscard();
ApplyViewport();
ApplyStencilTest(); ApplyStencilTest();
ApplyBlending(); ApplyBlending();
ApplyTextures(); ApplyTextures();

View file

@ -56,16 +56,6 @@ public:
GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
} draw; } draw;
struct Viewport {
GLint x = 0;
GLint y = 0;
GLint width = 0;
GLint height = 0;
GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE
GLfloat depth_range_far = 1.0f; // GL_DEPTH_RANGE
};
std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE
struct { struct {
@ -82,7 +72,6 @@ public:
return cur_state; return cur_state;
} }
void SetDefaultViewports();
/// Apply this state as the current OpenGL state /// Apply this state as the current OpenGL state
void Apply(); void Apply();
@ -92,7 +81,6 @@ public:
void ApplyClipDistances(); void ApplyClipDistances();
void ApplyRasterizerDiscard(); void ApplyRasterizerDiscard();
void ApplyStencilTest(); void ApplyStencilTest();
void ApplyViewport();
void ApplyTargetBlending(std::size_t target, bool force); void ApplyTargetBlending(std::size_t target, bool force);
void ApplyGlobalBlending(); void ApplyGlobalBlending();
void ApplyBlending(); void ApplyBlending();

View file

@ -205,8 +205,8 @@ constexpr GLint TexCoordLocation = 1;
constexpr GLint ModelViewMatrixLocation = 0; constexpr GLint ModelViewMatrixLocation = 0;
struct ScreenRectVertex { struct ScreenRectVertex {
constexpr ScreenRectVertex(GLfloat x, GLfloat y, GLfloat u, GLfloat v) constexpr ScreenRectVertex(u32 x, u32 y, GLfloat u, GLfloat v)
: position{{x, y}}, tex_coord{{u, v}} {} : position{{static_cast<GLfloat>(x), static_cast<GLfloat>(y)}}, tex_coord{{u, v}} {}
std::array<GLfloat, 2> position; std::array<GLfloat, 2> position;
std::array<GLfloat, 2> tex_coord; std::array<GLfloat, 2> tex_coord;
@ -514,8 +514,18 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height); glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height);
} }
void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
float h) { if (renderer_settings.set_background_color) {
// Update background color before drawing
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
0.0f);
}
// Set projection matrix
const std::array ortho_matrix =
MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data());
const auto& texcoords = screen_info.display_texcoords; const auto& texcoords = screen_info.display_texcoords;
auto left = texcoords.left; auto left = texcoords.left;
auto right = texcoords.right; auto right = texcoords.right;
@ -547,12 +557,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
static_cast<f32>(screen_info.texture.height); static_cast<f32>(screen_info.texture.height);
} }
const auto& screen = layout.screen;
const std::array vertices = { const std::array vertices = {
ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v), ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u, left * scale_v),
ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v), ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u, left * scale_v),
ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v), ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u, right * scale_v),
ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u, right * scale_v),
}; };
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
state.textures[0] = screen_info.display_texture; state.textures[0] = screen_info.display_texture;
state.Apply(); state.Apply();
@ -572,6 +584,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CW); glFrontFace(GL_CW);
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glViewport(0, 0, layout.width, layout.height);
glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
offsetof(ScreenRectVertex, position)); offsetof(ScreenRectVertex, position));
@ -581,7 +594,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
glVertexAttribBinding(TexCoordLocation, 0); glVertexAttribBinding(TexCoordLocation, 0);
glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex)); glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Restore default state // Restore default state
@ -589,28 +602,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
state.Apply(); state.Apply();
} }
void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
if (renderer_settings.set_background_color) {
// Update background color before drawing
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
0.0f);
}
const auto& screen = layout.screen;
glViewport(0, 0, layout.width, layout.height);
glClear(GL_COLOR_BUFFER_BIT);
// Set projection matrix
const std::array ortho_matrix =
MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data());
DrawScreenTriangles(screen_info, static_cast<float>(screen.left),
static_cast<float>(screen.top), static_cast<float>(screen.GetWidth()),
static_cast<float>(screen.GetHeight()));
}
void RendererOpenGL::TryPresent(int timeout_ms) { void RendererOpenGL::TryPresent(int timeout_ms) {
const auto& layout = render_window.GetFramebufferLayout(); const auto& layout = render_window.GetFramebufferLayout();
auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms); auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms);

View file

@ -76,8 +76,6 @@ private:
/// Draws the emulated screens to the emulator window. /// Draws the emulated screens to the emulator window.
void DrawScreen(const Layout::FramebufferLayout& layout); void DrawScreen(const Layout::FramebufferLayout& layout);
void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h);
void RenderScreenshot(); void RenderScreenshot();
/// Loads framebuffer from emulated memory into the active OpenGL texture. /// Loads framebuffer from emulated memory into the active OpenGL texture.