Fixup: C&P bugs, tex1d as part of generic unit
This commit is contained in:
		| @@ -91,7 +91,7 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { | ||||
|     for (size_t i = 0; i < lighting_luts.size(); ++i) { | ||||
|         lighting_luts[i].Create(); | ||||
|         state.SetActiveTextureUnit(GL_TEXTURE3 + i); | ||||
|         state.SetLUTTexture1D(lighting_luts[i].handle); | ||||
|         state.SetTexture1D(lighting_luts[i].handle); | ||||
|         glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); | ||||
|         glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|         glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
| @@ -166,7 +166,7 @@ void RasterizerOpenGL::DrawTriangles() { | ||||
|     bool has_stencil = regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; | ||||
|     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, (has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0); | ||||
|  | ||||
|     if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|     if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| @@ -616,13 +616,12 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) | ||||
|     utility_state.MakeCurrent(); | ||||
|  | ||||
|     utility_state.SetDrawFramebuffer(framebuffer.handle); | ||||
|     // TODO: When scissor test is implemented, need to disable scissor test in the state here so Clear call isn't affected | ||||
|  | ||||
|     if (dst_type == SurfaceType::Color || dst_type == SurfaceType::Texture) { | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_surface->texture.handle, 0); | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||||
|  | ||||
|         if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|             old_state->MakeCurrent(); | ||||
|             return false; | ||||
|         } | ||||
| @@ -707,7 +706,7 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0); | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||||
|  | ||||
|         if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|             old_state->MakeCurrent(); | ||||
|             return false; | ||||
|         } | ||||
| @@ -725,7 +724,7 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); | ||||
|         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0); | ||||
|  | ||||
|         if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|             old_state->MakeCurrent(); | ||||
|             return false; | ||||
|         } | ||||
|   | ||||
| @@ -145,12 +145,12 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS | ||||
|         buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | ||||
|     } | ||||
|  | ||||
|     if (OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|     if (OpenGLState::CheckBoundFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         old_state->MakeCurrent(); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|     if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         old_state->MakeCurrent(); | ||||
|         return false; | ||||
|     } | ||||
|   | ||||
| @@ -49,14 +49,11 @@ OpenGLState::OpenGLState() { | ||||
|     logic_op = GL_COPY; | ||||
|  | ||||
|     for (auto& texture_unit : texture_units) { | ||||
|         texture_unit.texture_1d = 0; | ||||
|         texture_unit.texture_2d = 0; | ||||
|         texture_unit.sampler = 0; | ||||
|     } | ||||
|  | ||||
|     for (auto& lut : lighting_luts) { | ||||
|         lut.texture_1d = 0; | ||||
|     } | ||||
|  | ||||
|     active_texture_unit = GL_TEXTURE0; | ||||
|  | ||||
|     draw.read_framebuffer = 0; | ||||
| @@ -71,6 +68,51 @@ OpenGLState* OpenGLState::GetCurrentState() { | ||||
|     return cur_state; | ||||
| } | ||||
|  | ||||
| void OpenGLState::MakeCurrent() { | ||||
|     if (cur_state == this) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     SetCullEnabled(cull.enabled); | ||||
|     SetCullMode(cull.mode); | ||||
|     SetCullFrontFace(cull.front_face); | ||||
|  | ||||
|     SetDepthTestEnabled(depth.test_enabled); | ||||
|     SetDepthFunc(depth.test_func); | ||||
|     SetDepthWriteMask(depth.write_mask); | ||||
|  | ||||
|     SetColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); | ||||
|  | ||||
|     SetStencilTestEnabled(stencil.test_enabled); | ||||
|     SetStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); | ||||
|     SetStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); | ||||
|     SetStencilWriteMask(stencil.write_mask); | ||||
|  | ||||
|     SetBlendEnabled(blend.enabled); | ||||
|     SetBlendFunc(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); | ||||
|     SetBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); | ||||
|  | ||||
|     SetLogicOp(logic_op); | ||||
|  | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { | ||||
|         SetActiveTextureUnit(GL_TEXTURE0 + i); | ||||
|         SetTexture1D(texture_units[i].texture_1d); | ||||
|         SetTexture2D(texture_units[i].texture_2d); | ||||
|         SetSampler(texture_units[i].sampler); | ||||
|     } | ||||
|  | ||||
|     SetActiveTextureUnit(active_texture_unit); | ||||
|  | ||||
|     SetReadFramebuffer(draw.read_framebuffer); | ||||
|     SetDrawFramebuffer(draw.draw_framebuffer); | ||||
|     SetVertexArray(draw.vertex_array); | ||||
|     SetVertexBuffer(draw.vertex_buffer); | ||||
|     SetUniformBuffer(draw.uniform_buffer); | ||||
|     SetShaderProgram(draw.shader_program); | ||||
|  | ||||
|     cur_state = this; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetCullEnabled(bool n_enabled) { | ||||
|     if (n_enabled != cur_state->cull.enabled) { | ||||
|         if (n_enabled) { | ||||
| @@ -158,14 +200,14 @@ void OpenGLState::SetStencilFunc(GLenum n_test_func, GLint n_test_ref, GLuint n_ | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetStencilOp(GLenum n_action_stencil_fail, GLenum n_action_depth_fail, GLenum n_action_depth_pass) { | ||||
|     if (n_action_stencil_fail != cur_state->stencil.action_depth_fail || | ||||
|             n_action_depth_fail != cur_state->stencil.action_depth_pass || | ||||
|             n_action_depth_pass != cur_state->stencil.action_stencil_fail) { | ||||
|     if (n_action_stencil_fail != cur_state->stencil.action_stencil_fail || | ||||
|             n_action_depth_fail != cur_state->stencil.action_depth_fail || | ||||
|             n_action_depth_pass != cur_state->stencil.action_depth_pass) { | ||||
|         glStencilOp(n_action_stencil_fail, n_action_depth_fail, n_action_depth_pass); | ||||
|     } | ||||
|     stencil.action_depth_fail = n_action_stencil_fail; | ||||
|     stencil.action_depth_pass = n_action_depth_fail; | ||||
|     stencil.action_stencil_fail = n_action_depth_pass; | ||||
|     stencil.action_stencil_fail = n_action_stencil_fail; | ||||
|     stencil.action_depth_fail = n_action_depth_fail; | ||||
|     stencil.action_depth_pass = n_action_depth_pass; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetStencilWriteMask(GLuint n_write_mask) { | ||||
| @@ -225,6 +267,16 @@ void OpenGLState::SetLogicOp(GLenum n_logic_op) { | ||||
|     logic_op = n_logic_op; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetTexture1D(GLuint n_texture_1d) { | ||||
|     unsigned unit_index = active_texture_unit - GL_TEXTURE0; | ||||
|     ASSERT(unit_index < ARRAY_SIZE(texture_units)); | ||||
|  | ||||
|     if (n_texture_1d != cur_state->texture_units[unit_index].texture_1d) { | ||||
|         glBindTexture(GL_TEXTURE_1D, n_texture_1d); | ||||
|     } | ||||
|     texture_units[unit_index].texture_1d = n_texture_1d; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetTexture2D(GLuint n_texture_2d) { | ||||
|     unsigned unit_index = active_texture_unit - GL_TEXTURE0; | ||||
|     ASSERT(unit_index < ARRAY_SIZE(texture_units)); | ||||
| @@ -245,16 +297,6 @@ void OpenGLState::SetSampler(GLuint n_sampler) { | ||||
|     texture_units[unit_index].sampler = n_sampler; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetLUTTexture1D(GLuint n_texture_1d) { | ||||
|     unsigned unit_index = active_texture_unit - GL_TEXTURE3; | ||||
|     ASSERT(unit_index < ARRAY_SIZE(lighting_luts)); | ||||
|  | ||||
|     if (n_texture_1d != cur_state->lighting_luts[unit_index].texture_1d) { | ||||
|         glBindTexture(GL_TEXTURE_1D, n_texture_1d); | ||||
|     } | ||||
|     lighting_luts[unit_index].texture_1d = n_texture_1d; | ||||
| } | ||||
|  | ||||
| void OpenGLState::SetActiveTextureUnit(GLenum n_active_texture_unit) { | ||||
|     if (n_active_texture_unit != cur_state->active_texture_unit) { | ||||
|         glActiveTexture(n_active_texture_unit); | ||||
| @@ -304,85 +346,31 @@ void OpenGLState::SetShaderProgram(GLuint n_shader_program) { | ||||
|     draw.shader_program = n_shader_program; | ||||
| } | ||||
|  | ||||
| void OpenGLState::MakeCurrent() { | ||||
|     if (cur_state == this) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     SetCullEnabled(cull.enabled); | ||||
|     SetCullMode(cull.mode); | ||||
|     SetCullFrontFace(cull.front_face); | ||||
|  | ||||
|     SetDepthTestEnabled(depth.test_enabled); | ||||
|     SetDepthFunc(depth.test_func); | ||||
|     SetDepthWriteMask(depth.write_mask); | ||||
|  | ||||
|     SetColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); | ||||
|  | ||||
|     SetStencilTestEnabled(stencil.test_enabled); | ||||
|     SetStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); | ||||
|     SetStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); | ||||
|     SetStencilWriteMask(stencil.write_mask); | ||||
|  | ||||
|     SetBlendEnabled(blend.enabled); | ||||
|     SetBlendFunc(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); | ||||
|     SetBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); | ||||
|  | ||||
|     SetLogicOp(logic_op); | ||||
|  | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { | ||||
|         SetActiveTextureUnit(GL_TEXTURE0 + i); | ||||
|         SetTexture2D(texture_units[i].texture_2d); | ||||
|         SetSampler(texture_units[i].sampler); | ||||
|     } | ||||
|  | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(lighting_luts); ++i) { | ||||
|         SetActiveTextureUnit(GL_TEXTURE3 + i); | ||||
|         SetLUTTexture1D(lighting_luts[i].texture_1d); | ||||
|     } | ||||
|  | ||||
|     SetActiveTextureUnit(active_texture_unit); | ||||
|  | ||||
|     SetReadFramebuffer(draw.read_framebuffer); | ||||
|     SetDrawFramebuffer(draw.draw_framebuffer); | ||||
|     SetVertexArray(draw.vertex_array); | ||||
|     SetVertexBuffer(draw.vertex_buffer); | ||||
|     SetUniformBuffer(draw.uniform_buffer); | ||||
|     SetShaderProgram(draw.shader_program); | ||||
|  | ||||
|     cur_state = this; | ||||
| } | ||||
|  | ||||
| GLenum OpenGLState::CheckFBStatus(GLenum target) { | ||||
|     GLenum fb_status = glCheckFramebufferStatus(target); | ||||
|     if (fb_status != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         const char* fb_description = (target == GL_READ_FRAMEBUFFER ? "READ" : (target == GL_DRAW_FRAMEBUFFER ? "DRAW" : "UNK")); | ||||
|         LOG_CRITICAL(Render_OpenGL, "OpenGL %s framebuffer check failed, status %X", fb_description, fb_status); | ||||
|     } | ||||
|  | ||||
|     return fb_status; | ||||
| } | ||||
|  | ||||
| void OpenGLState::ResetTexture(GLuint handle) { | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { | ||||
|         if (cur_state->texture_units[i].texture_1d == handle) { | ||||
|             GLenum prev_active_texture_unit = cur_state->active_texture_unit; | ||||
|             cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i); | ||||
|             cur_state->SetTexture1D(0); | ||||
|             cur_state->SetActiveTextureUnit(prev_active_texture_unit); | ||||
|         } | ||||
|  | ||||
|         if (cur_state->texture_units[i].texture_2d == handle) { | ||||
|             GLenum prev_active_texture_unit = cur_state->active_texture_unit; | ||||
|             cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i); | ||||
|             cur_state->SetTexture2D(0); | ||||
|         } | ||||
|     } | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(lighting_luts); ++i) { | ||||
|         if (cur_state->lighting_luts[i].texture_1d == handle) { | ||||
|             cur_state->SetActiveTextureUnit(GL_TEXTURE3 + i); | ||||
|             cur_state->SetLUTTexture1D(0); | ||||
|             cur_state->SetActiveTextureUnit(prev_active_texture_unit); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void OpenGLState::ResetSampler(GLuint handle) { | ||||
|     for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { | ||||
|         if (cur_state->texture_units[i].texture_2d == handle) { | ||||
|         if (cur_state->texture_units[i].sampler == handle) { | ||||
|             GLenum prev_active_texture_unit = cur_state->active_texture_unit; | ||||
|             cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i); | ||||
|             cur_state->SetSampler(0); | ||||
|             cur_state->SetActiveTextureUnit(prev_active_texture_unit); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -416,3 +404,13 @@ void OpenGLState::ResetFramebuffer(GLuint handle) { | ||||
|         cur_state->SetDrawFramebuffer(0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| GLenum OpenGLState::CheckBoundFBStatus(GLenum target) { | ||||
|     GLenum fb_status = glCheckFramebufferStatus(target); | ||||
|     if (fb_status != GL_FRAMEBUFFER_COMPLETE) { | ||||
|         const char* fb_description = (target == GL_READ_FRAMEBUFFER ? "READ" : (target == GL_DRAW_FRAMEBUFFER ? "DRAW" : "UNK")); | ||||
|         LOG_CRITICAL(Render_OpenGL, "OpenGL %s framebuffer check failed, status %X", fb_description, fb_status); | ||||
|     } | ||||
|  | ||||
|     return fb_status; | ||||
| } | ||||
|   | ||||
| @@ -10,22 +10,13 @@ class OpenGLState { | ||||
| public: | ||||
|     OpenGLState(); | ||||
|  | ||||
|     /// Get a pointer to the currently bound state tracker object | ||||
|     static OpenGLState* GetCurrentState(); | ||||
|  | ||||
|     /// Apply this state as the current OpenGL state | ||||
|     void MakeCurrent(); | ||||
|  | ||||
|     /// Check the status of the current OpenGL read or draw framebuffer configuration | ||||
|     static GLenum CheckFBStatus(GLenum target); | ||||
|  | ||||
|     /// Resets and unbinds any references to the given resource in the current OpenGL state | ||||
|     static void ResetTexture(GLuint handle); | ||||
|     static void ResetSampler(GLuint handle); | ||||
|     static void ResetProgram(GLuint handle); | ||||
|     static void ResetBuffer(GLuint handle); | ||||
|     static void ResetVertexArray(GLuint handle); | ||||
|     static void ResetFramebuffer(GLuint handle); | ||||
|  | ||||
|     /// Setter functions for OpenGL state | ||||
|     void SetCullEnabled(bool n_enabled); | ||||
|     void SetCullMode(GLenum n_mode); | ||||
|     void SetCullFrontFace(GLenum n_front_face); | ||||
| @@ -47,11 +38,10 @@ public: | ||||
|  | ||||
|     void SetLogicOp(GLenum n_logic_op); | ||||
|  | ||||
|     void SetTexture1D(GLuint n_texture_1d); | ||||
|     void SetTexture2D(GLuint n_texture_2d); | ||||
|     void SetSampler(GLuint n_sampler); | ||||
|  | ||||
|     void SetLUTTexture1D(GLuint n_texture_1d); | ||||
|  | ||||
|     void SetActiveTextureUnit(GLenum n_active_texture_unit); | ||||
|  | ||||
|     void SetReadFramebuffer(GLuint n_read_framebuffer); | ||||
| @@ -61,6 +51,17 @@ public: | ||||
|     void SetUniformBuffer(GLuint n_uniform_buffer); | ||||
|     void SetShaderProgram(GLuint n_shader_program); | ||||
|  | ||||
|     /// Resets and unbinds any references to the given resource in the current OpenGL state | ||||
|     static void ResetTexture(GLuint handle); | ||||
|     static void ResetSampler(GLuint handle); | ||||
|     static void ResetProgram(GLuint handle); | ||||
|     static void ResetBuffer(GLuint handle); | ||||
|     static void ResetVertexArray(GLuint handle); | ||||
|     static void ResetFramebuffer(GLuint handle); | ||||
|  | ||||
|     /// Check the status of the currently bound OpenGL read or draw framebuffer configuration | ||||
|     static GLenum CheckBoundFBStatus(GLenum target); | ||||
|  | ||||
| private: | ||||
|     struct { | ||||
|         bool enabled; // GL_CULL_FACE | ||||
| @@ -111,13 +112,10 @@ private: | ||||
|  | ||||
|     // 3 texture units - one for each that is used in PICA fragment shader emulation | ||||
|     struct { | ||||
|         GLuint texture_1d; // GL_TEXTURE_BINDING_1D | ||||
|         GLuint texture_2d; // GL_TEXTURE_BINDING_2D | ||||
|         GLuint sampler; // GL_SAMPLER_BINDING | ||||
|     } texture_units[3]; | ||||
|  | ||||
|     struct { | ||||
|         GLuint texture_1d; // GL_TEXTURE_BINDING_1D | ||||
|     } lighting_luts[6]; | ||||
|     } texture_units[9]; | ||||
|  | ||||
|     GLenum active_texture_unit; // GL_ACTIVE_TEXTURE | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 tfarley
					tfarley