diff options
| author | 2018-06-06 21:39:47 -0400 | |
|---|---|---|
| committer | 2018-06-06 21:39:47 -0400 | |
| commit | 37f50c877374ac49eefb205cc55e7f6fc84cef29 (patch) | |
| tree | 0d9b2242e432454ee6d8fffa0fb82971e25fa6fe /src | |
| parent | Merge pull request #536 from bunnei/isetp_imm (diff) | |
| parent | GPU: Support changing the texture swizzles for Maxwell textures. (diff) | |
| download | yuzu-37f50c877374ac49eefb205cc55e7f6fc84cef29.tar.gz yuzu-37f50c877374ac49eefb205cc55e7f6fc84cef29.tar.xz yuzu-37f50c877374ac49eefb205cc55e7f6fc84cef29.zip | |
Merge pull request #535 from Subv/gpu_swizzle
GPU: Support changing the texture swizzles for Maxwell textures.
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 21 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/textures/texture.h | 16 |
6 files changed, 65 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b23b8fb29..2e90ebcf4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -681,6 +681,14 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program, | |||
| 681 | Surface surface = res_cache.GetTextureSurface(texture); | 681 | Surface surface = res_cache.GetTextureSurface(texture); |
| 682 | if (surface != nullptr) { | 682 | if (surface != nullptr) { |
| 683 | state.texture_units[current_bindpoint].texture_2d = surface->texture.handle; | 683 | state.texture_units[current_bindpoint].texture_2d = surface->texture.handle; |
| 684 | state.texture_units[current_bindpoint].swizzle.r = | ||
| 685 | MaxwellToGL::SwizzleSource(texture.tic.x_source); | ||
| 686 | state.texture_units[current_bindpoint].swizzle.g = | ||
| 687 | MaxwellToGL::SwizzleSource(texture.tic.y_source); | ||
| 688 | state.texture_units[current_bindpoint].swizzle.b = | ||
| 689 | MaxwellToGL::SwizzleSource(texture.tic.z_source); | ||
| 690 | state.texture_units[current_bindpoint].swizzle.a = | ||
| 691 | MaxwellToGL::SwizzleSource(texture.tic.w_source); | ||
| 684 | } else { | 692 | } else { |
| 685 | // Can occur when texture addr is null or its memory is unmapped/invalid | 693 | // Can occur when texture addr is null or its memory is unmapped/invalid |
| 686 | state.texture_units[current_bindpoint].texture_2d = 0; | 694 | state.texture_units[current_bindpoint].texture_2d = 0; |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index f91dfe36a..44f0c8a01 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -50,6 +50,10 @@ OpenGLState::OpenGLState() { | |||
| 50 | for (auto& texture_unit : texture_units) { | 50 | for (auto& texture_unit : texture_units) { |
| 51 | texture_unit.texture_2d = 0; | 51 | texture_unit.texture_2d = 0; |
| 52 | texture_unit.sampler = 0; | 52 | texture_unit.sampler = 0; |
| 53 | texture_unit.swizzle.r = GL_RED; | ||
| 54 | texture_unit.swizzle.g = GL_GREEN; | ||
| 55 | texture_unit.swizzle.b = GL_BLUE; | ||
| 56 | texture_unit.swizzle.a = GL_ALPHA; | ||
| 53 | } | 57 | } |
| 54 | 58 | ||
| 55 | lighting_lut.texture_buffer = 0; | 59 | lighting_lut.texture_buffer = 0; |
| @@ -200,6 +204,15 @@ void OpenGLState::Apply() const { | |||
| 200 | if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { | 204 | if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { |
| 201 | glBindSampler(i, texture_units[i].sampler); | 205 | glBindSampler(i, texture_units[i].sampler); |
| 202 | } | 206 | } |
| 207 | // Update the texture swizzle | ||
| 208 | if (texture_units[i].swizzle.r != cur_state.texture_units[i].swizzle.r || | ||
| 209 | texture_units[i].swizzle.g != cur_state.texture_units[i].swizzle.g || | ||
| 210 | texture_units[i].swizzle.b != cur_state.texture_units[i].swizzle.b || | ||
| 211 | texture_units[i].swizzle.a != cur_state.texture_units[i].swizzle.a) { | ||
| 212 | std::array<GLint, 4> mask = {texture_units[i].swizzle.r, texture_units[i].swizzle.g, | ||
| 213 | texture_units[i].swizzle.b, texture_units[i].swizzle.a}; | ||
| 214 | glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask.data()); | ||
| 215 | } | ||
| 203 | } | 216 | } |
| 204 | 217 | ||
| 205 | // Constbuffers | 218 | // Constbuffers |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 75c08e645..839e50e93 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -85,6 +85,12 @@ public: | |||
| 85 | struct { | 85 | struct { |
| 86 | GLuint texture_2d; // GL_TEXTURE_BINDING_2D | 86 | GLuint texture_2d; // GL_TEXTURE_BINDING_2D |
| 87 | GLuint sampler; // GL_SAMPLER_BINDING | 87 | GLuint sampler; // GL_SAMPLER_BINDING |
| 88 | struct { | ||
| 89 | GLint r; // GL_TEXTURE_SWIZZLE_R | ||
| 90 | GLint g; // GL_TEXTURE_SWIZZLE_G | ||
| 91 | GLint b; // GL_TEXTURE_SWIZZLE_B | ||
| 92 | GLint a; // GL_TEXTURE_SWIZZLE_A | ||
| 93 | } swizzle; | ||
| 88 | } texture_units[32]; | 94 | } texture_units[32]; |
| 89 | 95 | ||
| 90 | struct { | 96 | struct { |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index cf11983cf..2155fb019 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -180,4 +180,25 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { | |||
| 180 | return {}; | 180 | return {}; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) { | ||
| 184 | switch (source) { | ||
| 185 | case Tegra::Texture::SwizzleSource::Zero: | ||
| 186 | return GL_ZERO; | ||
| 187 | case Tegra::Texture::SwizzleSource::R: | ||
| 188 | return GL_RED; | ||
| 189 | case Tegra::Texture::SwizzleSource::G: | ||
| 190 | return GL_GREEN; | ||
| 191 | case Tegra::Texture::SwizzleSource::B: | ||
| 192 | return GL_BLUE; | ||
| 193 | case Tegra::Texture::SwizzleSource::A: | ||
| 194 | return GL_ALPHA; | ||
| 195 | case Tegra::Texture::SwizzleSource::OneInt: | ||
| 196 | case Tegra::Texture::SwizzleSource::OneFloat: | ||
| 197 | return GL_ONE; | ||
| 198 | } | ||
| 199 | NGLOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source)); | ||
| 200 | UNREACHABLE(); | ||
| 201 | return {}; | ||
| 202 | } | ||
| 203 | |||
| 183 | } // namespace MaxwellToGL | 204 | } // namespace MaxwellToGL |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3440d2190..f33766bfd 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -316,6 +316,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 316 | }}; | 316 | }}; |
| 317 | 317 | ||
| 318 | state.texture_units[0].texture_2d = screen_info.display_texture; | 318 | state.texture_units[0].texture_2d = screen_info.display_texture; |
| 319 | state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; | ||
| 319 | state.Apply(); | 320 | state.Apply(); |
| 320 | 321 | ||
| 321 | glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); | 322 | glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index f48ca30b8..a17eaf19d 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -122,6 +122,17 @@ enum class ComponentType : u32 { | |||
| 122 | FLOAT = 7 | 122 | FLOAT = 7 |
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | enum class SwizzleSource : u32 { | ||
| 126 | Zero = 0, | ||
| 127 | |||
| 128 | R = 2, | ||
| 129 | G = 3, | ||
| 130 | B = 4, | ||
| 131 | A = 5, | ||
| 132 | OneInt = 6, | ||
| 133 | OneFloat = 7, | ||
| 134 | }; | ||
| 135 | |||
| 125 | union TextureHandle { | 136 | union TextureHandle { |
| 126 | u32 raw; | 137 | u32 raw; |
| 127 | BitField<0, 20, u32> tic_id; | 138 | BitField<0, 20, u32> tic_id; |
| @@ -139,6 +150,11 @@ struct TICEntry { | |||
| 139 | BitField<10, 3, ComponentType> g_type; | 150 | BitField<10, 3, ComponentType> g_type; |
| 140 | BitField<13, 3, ComponentType> b_type; | 151 | BitField<13, 3, ComponentType> b_type; |
| 141 | BitField<16, 3, ComponentType> a_type; | 152 | BitField<16, 3, ComponentType> a_type; |
| 153 | |||
| 154 | BitField<19, 3, SwizzleSource> x_source; | ||
| 155 | BitField<22, 3, SwizzleSource> y_source; | ||
| 156 | BitField<25, 3, SwizzleSource> z_source; | ||
| 157 | BitField<28, 3, SwizzleSource> w_source; | ||
| 142 | }; | 158 | }; |
| 143 | u32 address_low; | 159 | u32 address_low; |
| 144 | union { | 160 | union { |