summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-06-09 19:12:00 -0400
committerGravatar bunnei2015-06-09 19:12:00 -0400
commitca5d1545c3ca10e2069a6b7e08329bfa905a8d9a (patch)
tree8a8c33d02708a616ec090e57cb3c4002d0bdf06f /src
parentMerge pull request #851 from clienthax/master (diff)
parentRenderer formatting edits (diff)
downloadyuzu-ca5d1545c3ca10e2069a6b7e08329bfa905a8d9a.tar.gz
yuzu-ca5d1545c3ca10e2069a6b7e08329bfa905a8d9a.tar.xz
yuzu-ca5d1545c3ca10e2069a6b7e08329bfa905a8d9a.zip
Merge pull request #835 from tfarley/hw-renderer-fixes
HW Renderer Screen Fixes
Diffstat (limited to 'src')
-rw-r--r--src/common/math_util.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp154
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp36
-rw-r--r--src/video_core/renderer_opengl/gl_state.h7
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp6
5 files changed, 140 insertions, 65 deletions
diff --git a/src/common/math_util.h b/src/common/math_util.h
index 4b0910741..d44b06e74 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -12,7 +12,7 @@ namespace MathUtil
12{ 12{
13 13
14inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, unsigned length1) { 14inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, unsigned length1) {
15 return (std::max(start0, start1) <= std::min(start0 + length0, start1 + length1)); 15 return (std::max(start0, start1) < std::min(start0 + length0, start1 + length1));
16} 16}
17 17
18template<typename T> 18template<typename T>
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index d31c46cca..518f79331 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -94,14 +94,27 @@ void RasterizerOpenGL::InitObjects() {
94 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation 94 // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
95 fb_color_texture.texture.Create(); 95 fb_color_texture.texture.Create();
96 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1); 96 ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1);
97
98 state.texture_units[0].enabled_2d = true;
99 state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
100 state.Apply();
101
97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
102 107
108 state.texture_units[0].texture_2d = 0;
109 state.Apply();
110
103 fb_depth_texture.texture.Create(); 111 fb_depth_texture.texture.Create();
104 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1); 112 ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
113
114 state.texture_units[0].enabled_2d = true;
115 state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
116 state.Apply();
117
105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); 118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -110,14 +123,13 @@ void RasterizerOpenGL::InitObjects() {
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); 124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
112 125
126 state.texture_units[0].texture_2d = 0;
127 state.Apply();
128
113 // Configure OpenGL framebuffer 129 // Configure OpenGL framebuffer
114 framebuffer.Create(); 130 framebuffer.Create();
115 131
116 state.draw.framebuffer = framebuffer.handle; 132 state.draw.framebuffer = framebuffer.handle;
117
118 // Unbind texture to allow binding to framebuffer
119 state.texture_units[0].enabled_2d = true;
120 state.texture_units[0].texture_2d = 0;
121 state.Apply(); 133 state.Apply();
122 134
123 glActiveTexture(GL_TEXTURE0); 135 glActiveTexture(GL_TEXTURE0);
@@ -205,7 +217,19 @@ void RasterizerOpenGL::DrawTriangles() {
205 217
206 vertex_batch.clear(); 218 vertex_batch.clear();
207 219
208 // TODO: Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture 220 // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture
221 const auto& regs = Pica::g_state.regs;
222
223 PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress();
224 u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format)
225 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
226
227 PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress();
228 u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format)
229 * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight();
230
231 res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size);
232 res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size);
209} 233}
210 234
211void RasterizerOpenGL::CommitFramebuffer() { 235void RasterizerOpenGL::CommitFramebuffer() {
@@ -472,6 +496,9 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs:
472 glActiveTexture(GL_TEXTURE0); 496 glActiveTexture(GL_TEXTURE0);
473 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, 497 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
474 texture.gl_format, texture.gl_type, nullptr); 498 texture.gl_format, texture.gl_type, nullptr);
499
500 state.texture_units[0].texture_2d = 0;
501 state.Apply();
475} 502}
476 503
477void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) { 504void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) {
@@ -491,7 +518,7 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
491 case Pica::Regs::DepthFormat::D24: 518 case Pica::Regs::DepthFormat::D24:
492 internal_format = GL_DEPTH_COMPONENT24; 519 internal_format = GL_DEPTH_COMPONENT24;
493 texture.gl_format = GL_DEPTH_COMPONENT; 520 texture.gl_format = GL_DEPTH_COMPONENT;
494 texture.gl_type = GL_UNSIGNED_INT_24_8; 521 texture.gl_type = GL_UNSIGNED_INT;
495 break; 522 break;
496 523
497 case Pica::Regs::DepthFormat::D24S8: 524 case Pica::Regs::DepthFormat::D24S8:
@@ -513,6 +540,9 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
513 glActiveTexture(GL_TEXTURE0); 540 glActiveTexture(GL_TEXTURE0);
514 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, 541 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
515 texture.gl_format, texture.gl_type, nullptr); 542 texture.gl_format, texture.gl_type, nullptr);
543
544 state.texture_units[0].texture_2d = 0;
545 state.Apply();
516} 546}
517 547
518void RasterizerOpenGL::SyncFramebuffer() { 548void RasterizerOpenGL::SyncFramebuffer() {
@@ -652,6 +682,10 @@ void RasterizerOpenGL::SyncDepthTest() {
652 const auto& regs = Pica::g_state.regs; 682 const auto& regs = Pica::g_state.regs;
653 state.depth.test_enabled = (regs.output_merger.depth_test_enable == 1); 683 state.depth.test_enabled = (regs.output_merger.depth_test_enable == 1);
654 state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func); 684 state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func);
685 state.color_mask.red_enabled = regs.output_merger.red_enable;
686 state.color_mask.green_enabled = regs.output_merger.green_enable;
687 state.color_mask.blue_enabled = regs.output_merger.blue_enable;
688 state.color_mask.alpha_enabled = regs.output_merger.alpha_enable;
655 state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE; 689 state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
656} 690}
657 691
@@ -759,10 +793,10 @@ void RasterizerOpenGL::ReloadColorBuffer() {
759 for (int x = 0; x < fb_color_texture.width; ++x) { 793 for (int x = 0; x < fb_color_texture.width; ++x) {
760 const u32 coarse_y = y & ~7; 794 const u32 coarse_y = y & ~7;
761 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 795 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
762 u32 gl_px_idx = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; 796 u32 gl_pixel_index = (x + y * fb_color_texture.width) * bytes_per_pixel;
763 797
764 u8* pixel = color_buffer + dst_offset; 798 u8* pixel = color_buffer + dst_offset;
765 memcpy(&temp_fb_color_buffer[gl_px_idx], pixel, bytes_per_pixel); 799 memcpy(&temp_fb_color_buffer[gl_pixel_index], pixel, bytes_per_pixel);
766 } 800 }
767 } 801 }
768 802
@@ -773,6 +807,9 @@ void RasterizerOpenGL::ReloadColorBuffer() {
773 glActiveTexture(GL_TEXTURE0); 807 glActiveTexture(GL_TEXTURE0);
774 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height, 808 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height,
775 fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get()); 809 fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get());
810
811 state.texture_units[0].texture_2d = 0;
812 state.Apply();
776} 813}
777 814
778void RasterizerOpenGL::ReloadDepthBuffer() { 815void RasterizerOpenGL::ReloadDepthBuffer() {
@@ -790,29 +827,29 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
790 827
791 std::unique_ptr<u8[]> temp_fb_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]); 828 std::unique_ptr<u8[]> temp_fb_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]);
792 829
793 for (int y = 0; y < fb_depth_texture.height; ++y) { 830 u8* temp_fb_depth_data = bytes_per_pixel == 3 ? (temp_fb_depth_buffer.get() + 1) : temp_fb_depth_buffer.get();
794 for (int x = 0; x < fb_depth_texture.width; ++x) { 831
795 const u32 coarse_y = y & ~7; 832 if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) {
796 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 833 for (int y = 0; y < fb_depth_texture.height; ++y) {
797 u32 gl_px_idx = x + y * fb_depth_texture.width; 834 for (int x = 0; x < fb_depth_texture.width; ++x) {
798 835 const u32 coarse_y = y & ~7;
799 switch (fb_depth_texture.format) { 836 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
800 case Pica::Regs::DepthFormat::D16: 837 u32 gl_pixel_index = (x + y * fb_depth_texture.width);
801 ((u16*)temp_fb_depth_buffer.get())[gl_px_idx] = Color::DecodeD16(depth_buffer + dst_offset); 838
802 break; 839 u8* pixel = depth_buffer + dst_offset;
803 case Pica::Regs::DepthFormat::D24: 840 u32 depth_stencil = *(u32*)pixel;
804 ((u32*)temp_fb_depth_buffer.get())[gl_px_idx] = Color::DecodeD24(depth_buffer + dst_offset); 841 ((u32*)temp_fb_depth_data)[gl_pixel_index] = (depth_stencil << 8) | (depth_stencil >> 24);
805 break;
806 case Pica::Regs::DepthFormat::D24S8:
807 {
808 Math::Vec2<u32> depth_stencil = Color::DecodeD24S8(depth_buffer + dst_offset);
809 ((u32*)temp_fb_depth_buffer.get())[gl_px_idx] = (depth_stencil.x << 8) | depth_stencil.y;
810 break;
811 } 842 }
812 default: 843 }
813 LOG_CRITICAL(Render_OpenGL, "Unknown memory framebuffer depth format %x", fb_depth_texture.format); 844 } else {
814 UNIMPLEMENTED(); 845 for (int y = 0; y < fb_depth_texture.height; ++y) {
815 break; 846 for (int x = 0; x < fb_depth_texture.width; ++x) {
847 const u32 coarse_y = y & ~7;
848 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
849 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp;
850
851 u8* pixel = depth_buffer + dst_offset;
852 memcpy(&temp_fb_depth_data[gl_pixel_index], pixel, bytes_per_pixel);
816 } 853 }
817 } 854 }
818 } 855 }
@@ -824,6 +861,9 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
824 glActiveTexture(GL_TEXTURE0); 861 glActiveTexture(GL_TEXTURE0);
825 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_depth_texture.width, fb_depth_texture.height, 862 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_depth_texture.width, fb_depth_texture.height,
826 fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get()); 863 fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get());
864
865 state.texture_units[0].texture_2d = 0;
866 state.Apply();
827} 867}
828 868
829void RasterizerOpenGL::CommitColorBuffer() { 869void RasterizerOpenGL::CommitColorBuffer() {
@@ -842,15 +882,18 @@ void RasterizerOpenGL::CommitColorBuffer() {
842 glActiveTexture(GL_TEXTURE0); 882 glActiveTexture(GL_TEXTURE0);
843 glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get()); 883 glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get());
844 884
885 state.texture_units[0].texture_2d = 0;
886 state.Apply();
887
845 // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary. 888 // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary.
846 for (int y = 0; y < fb_color_texture.height; ++y) { 889 for (int y = 0; y < fb_color_texture.height; ++y) {
847 for (int x = 0; x < fb_color_texture.width; ++x) { 890 for (int x = 0; x < fb_color_texture.width; ++x) {
848 const u32 coarse_y = y & ~7; 891 const u32 coarse_y = y & ~7;
849 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel; 892 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_color_texture.width * bytes_per_pixel;
850 u32 gl_px_idx = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel; 893 u32 gl_pixel_index = x * bytes_per_pixel + y * fb_color_texture.width * bytes_per_pixel;
851 894
852 u8* pixel = color_buffer + dst_offset; 895 u8* pixel = color_buffer + dst_offset;
853 memcpy(pixel, &temp_gl_color_buffer[gl_px_idx], bytes_per_pixel); 896 memcpy(pixel, &temp_gl_color_buffer[gl_pixel_index], bytes_per_pixel);
854 } 897 }
855 } 898 }
856 } 899 }
@@ -877,29 +920,32 @@ void RasterizerOpenGL::CommitDepthBuffer() {
877 glActiveTexture(GL_TEXTURE0); 920 glActiveTexture(GL_TEXTURE0);
878 glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get()); 921 glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get());
879 922
880 for (int y = 0; y < fb_depth_texture.height; ++y) { 923 state.texture_units[0].texture_2d = 0;
881 for (int x = 0; x < fb_depth_texture.width; ++x) { 924 state.Apply();
882 const u32 coarse_y = y & ~7; 925
883 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel; 926 u8* temp_gl_depth_data = bytes_per_pixel == 3 ? (temp_gl_depth_buffer.get() + 1) : temp_gl_depth_buffer.get();
884 u32 gl_px_idx = x + y * fb_depth_texture.width; 927
885 928 if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) {
886 switch (fb_depth_texture.format) { 929 for (int y = 0; y < fb_depth_texture.height; ++y) {
887 case Pica::Regs::DepthFormat::D16: 930 for (int x = 0; x < fb_depth_texture.width; ++x) {
888 Color::EncodeD16(((u16*)temp_gl_depth_buffer.get())[gl_px_idx], depth_buffer + dst_offset); 931 const u32 coarse_y = y & ~7;
889 break; 932 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
890 case Pica::Regs::DepthFormat::D24: 933 u32 gl_pixel_index = (x + y * fb_depth_texture.width);
891 Color::EncodeD24(((u32*)temp_gl_depth_buffer.get())[gl_px_idx], depth_buffer + dst_offset); 934
892 break; 935 u8* pixel = depth_buffer + dst_offset;
893 case Pica::Regs::DepthFormat::D24S8: 936 u32 depth_stencil = ((u32*)temp_gl_depth_data)[gl_pixel_index];
894 { 937 *(u32*)pixel = (depth_stencil >> 8) | (depth_stencil << 24);
895 u32 depth_stencil = ((u32*)temp_gl_depth_buffer.get())[gl_px_idx];
896 Color::EncodeD24S8((depth_stencil >> 8), depth_stencil & 0xFF, depth_buffer + dst_offset);
897 break;
898 } 938 }
899 default: 939 }
900 LOG_CRITICAL(Render_OpenGL, "Unknown framebuffer depth format %x", fb_depth_texture.format); 940 } else {
901 UNIMPLEMENTED(); 941 for (int y = 0; y < fb_depth_texture.height; ++y) {
902 break; 942 for (int x = 0; x < fb_depth_texture.width; ++x) {
943 const u32 coarse_y = y & ~7;
944 u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * fb_depth_texture.width * bytes_per_pixel;
945 u32 gl_pixel_index = (x + y * fb_depth_texture.width) * gl_bpp;
946
947 u8* pixel = depth_buffer + dst_offset;
948 memcpy(pixel, &temp_gl_depth_data[gl_pixel_index], bytes_per_pixel);
903 } 949 }
904 } 950 }
905 } 951 }
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 9c5f38f94..3526e16d5 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -16,6 +16,11 @@ OpenGLState::OpenGLState() {
16 depth.test_func = GL_LESS; 16 depth.test_func = GL_LESS;
17 depth.write_mask = GL_TRUE; 17 depth.write_mask = GL_TRUE;
18 18
19 color_mask.red_enabled = GL_TRUE;
20 color_mask.green_enabled = GL_TRUE;
21 color_mask.blue_enabled = GL_TRUE;
22 color_mask.alpha_enabled = GL_TRUE;
23
19 stencil.test_enabled = false; 24 stencil.test_enabled = false;
20 stencil.test_func = GL_ALWAYS; 25 stencil.test_func = GL_ALWAYS;
21 stencil.test_ref = 0; 26 stencil.test_ref = 0;
@@ -77,6 +82,15 @@ void OpenGLState::Apply() {
77 glDepthMask(depth.write_mask); 82 glDepthMask(depth.write_mask);
78 } 83 }
79 84
85 // Color mask
86 if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
87 color_mask.green_enabled != cur_state.color_mask.green_enabled ||
88 color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
89 color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
90 glColorMask(color_mask.red_enabled, color_mask.green_enabled,
91 color_mask.blue_enabled, color_mask.alpha_enabled);
92 }
93
80 // Stencil test 94 // Stencil test
81 if (stencil.test_enabled != cur_state.stencil.test_enabled) { 95 if (stencil.test_enabled != cur_state.stencil.test_enabled) {
82 if (stencil.test_enabled) { 96 if (stencil.test_enabled) {
@@ -87,8 +101,8 @@ void OpenGLState::Apply() {
87 } 101 }
88 102
89 if (stencil.test_func != cur_state.stencil.test_func || 103 if (stencil.test_func != cur_state.stencil.test_func ||
90 stencil.test_ref != cur_state.stencil.test_ref || 104 stencil.test_ref != cur_state.stencil.test_ref ||
91 stencil.test_mask != cur_state.stencil.test_mask) { 105 stencil.test_mask != cur_state.stencil.test_mask) {
92 glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); 106 glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask);
93 } 107 }
94 108
@@ -112,17 +126,19 @@ void OpenGLState::Apply() {
112 } 126 }
113 127
114 if (blend.color.red != cur_state.blend.color.red || 128 if (blend.color.red != cur_state.blend.color.red ||
115 blend.color.green != cur_state.blend.color.green || 129 blend.color.green != cur_state.blend.color.green ||
116 blend.color.blue != cur_state.blend.color.blue || 130 blend.color.blue != cur_state.blend.color.blue ||
117 blend.color.alpha != cur_state.blend.color.alpha) { 131 blend.color.alpha != cur_state.blend.color.alpha) {
118 glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); 132 glBlendColor(blend.color.red, blend.color.green,
133 blend.color.blue, blend.color.alpha);
119 } 134 }
120 135
121 if (blend.src_rgb_func != cur_state.blend.src_rgb_func || 136 if (blend.src_rgb_func != cur_state.blend.src_rgb_func ||
122 blend.dst_rgb_func != cur_state.blend.dst_rgb_func || 137 blend.dst_rgb_func != cur_state.blend.dst_rgb_func ||
123 blend.src_a_func != cur_state.blend.src_a_func || 138 blend.src_a_func != cur_state.blend.src_a_func ||
124 blend.dst_a_func != cur_state.blend.dst_a_func) { 139 blend.dst_a_func != cur_state.blend.dst_a_func) {
125 glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); 140 glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func,
141 blend.src_a_func, blend.dst_a_func);
126 } 142 }
127 143
128 if (logic_op != cur_state.logic_op) { 144 if (logic_op != cur_state.logic_op) {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 6b97721d6..26b916360 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -20,6 +20,13 @@ public:
20 } depth; 20 } depth;
21 21
22 struct { 22 struct {
23 GLboolean red_enabled;
24 GLboolean green_enabled;
25 GLboolean blue_enabled;
26 GLboolean alpha_enabled;
27 } color_mask; // GL_COLOR_WRITEMASK
28
29 struct {
23 bool test_enabled; // GL_STENCIL_TEST 30 bool test_enabled; // GL_STENCIL_TEST
24 GLenum test_func; // GL_STENCIL_FUNC 31 GLenum test_func; // GL_STENCIL_FUNC
25 GLint test_ref; // GL_STENCIL_REF 32 GLint test_ref; // GL_STENCIL_REF
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 382aeaa05..058ad12cd 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -170,6 +170,9 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
170 texture.gl_format, texture.gl_type, framebuffer_data); 170 texture.gl_format, texture.gl_type, framebuffer_data);
171 171
172 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 172 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
173
174 state.texture_units[0].texture_2d = 0;
175 state.Apply();
173} 176}
174 177
175/** 178/**
@@ -239,6 +242,9 @@ void RendererOpenGL::InitOpenGLObjects() {
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
240 } 243 }
241 244
245 state.texture_units[0].texture_2d = 0;
246 state.Apply();
247
242 hw_rasterizer->InitObjects(); 248 hw_rasterizer->InitObjects();
243} 249}
244 250