diff options
| author | 2019-07-11 01:32:12 -0300 | |
|---|---|---|
| committer | 2019-09-05 20:35:51 -0300 | |
| commit | 04cdecb7a114471fec50deab86bcd160ec85feb4 (patch) | |
| tree | 69af6a51405451420ac7b80cf6d5b43f50b4e73f /src | |
| parent | gl_rasterizer: Implement image bindings (diff) | |
| download | yuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.tar.gz yuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.tar.xz yuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.zip | |
gl_state: Split textures and samplers into two arrays
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 99 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 4 |
4 files changed, 39 insertions, 91 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6636b3c74..818e71754 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -991,7 +991,7 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag | |||
| 991 | const auto& maxwell3d = gpu.Maxwell3D(); | 991 | const auto& maxwell3d = gpu.Maxwell3D(); |
| 992 | const auto& entries = shader->GetShaderEntries().samplers; | 992 | const auto& entries = shader->GetShaderEntries().samplers; |
| 993 | 993 | ||
| 994 | ASSERT_MSG(base_bindings.sampler + entries.size() <= std::size(state.texture_units), | 994 | ASSERT_MSG(base_bindings.sampler + entries.size() <= std::size(state.textures), |
| 995 | "Exceeded the number of active textures."); | 995 | "Exceeded the number of active textures."); |
| 996 | 996 | ||
| 997 | TextureBufferUsage texture_buffer_usage{0}; | 997 | TextureBufferUsage texture_buffer_usage{0}; |
| @@ -1019,16 +1019,15 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag | |||
| 1019 | bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding, | 1019 | bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding, |
| 1020 | const Tegra::Texture::FullTextureInfo& texture, | 1020 | const Tegra::Texture::FullTextureInfo& texture, |
| 1021 | const GLShader::SamplerEntry& entry) { | 1021 | const GLShader::SamplerEntry& entry) { |
| 1022 | auto& unit{state.texture_units[binding]}; | 1022 | state.samplers[binding] = sampler_cache.GetSampler(texture.tsc); |
| 1023 | unit.sampler = sampler_cache.GetSampler(texture.tsc); | ||
| 1024 | 1023 | ||
| 1025 | const auto view = texture_cache.GetTextureSurface(texture.tic, entry); | 1024 | const auto view = texture_cache.GetTextureSurface(texture.tic, entry); |
| 1026 | if (!view) { | 1025 | if (!view) { |
| 1027 | // Can occur when texture addr is null or its memory is unmapped/invalid | 1026 | // Can occur when texture addr is null or its memory is unmapped/invalid |
| 1028 | unit.texture = 0; | 1027 | state.textures[binding] = 0; |
| 1029 | return false; | 1028 | return false; |
| 1030 | } | 1029 | } |
| 1031 | unit.texture = view->GetTexture(); | 1030 | state.textures[binding] = view->GetTexture(); |
| 1032 | 1031 | ||
| 1033 | if (view->GetSurfaceParams().IsBuffer()) { | 1032 | if (view->GetSurfaceParams().IsBuffer()) { |
| 1034 | return true; | 1033 | return true; |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index a38f88182..6eabf4fac 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -34,6 +34,25 @@ bool UpdateTie(T1 current_value, const T2 new_value) { | |||
| 34 | return changed; | 34 | return changed; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | template <typename T> | ||
| 38 | std::optional<std::pair<GLuint, GLsizei>> UpdateArray(T& current_values, const T& new_values) { | ||
| 39 | std::optional<std::size_t> first; | ||
| 40 | std::size_t last; | ||
| 41 | for (std::size_t i = 0; i < std::size(current_values); ++i) { | ||
| 42 | if (!UpdateValue(current_values[i], new_values[i])) { | ||
| 43 | continue; | ||
| 44 | } | ||
| 45 | if (!first) { | ||
| 46 | first = i; | ||
| 47 | } | ||
| 48 | last = i; | ||
| 49 | } | ||
| 50 | if (!first) { | ||
| 51 | return std::nullopt; | ||
| 52 | } | ||
| 53 | return std::make_pair(static_cast<GLuint>(*first), static_cast<GLsizei>(last - *first + 1)); | ||
| 54 | } | ||
| 55 | |||
| 37 | void Enable(GLenum cap, bool enable) { | 56 | void Enable(GLenum cap, bool enable) { |
| 38 | if (enable) { | 57 | if (enable) { |
| 39 | glEnable(cap); | 58 | glEnable(cap); |
| @@ -134,10 +153,6 @@ OpenGLState::OpenGLState() { | |||
| 134 | logic_op.enabled = false; | 153 | logic_op.enabled = false; |
| 135 | logic_op.operation = GL_COPY; | 154 | logic_op.operation = GL_COPY; |
| 136 | 155 | ||
| 137 | for (auto& texture_unit : texture_units) { | ||
| 138 | texture_unit.Reset(); | ||
| 139 | } | ||
| 140 | |||
| 141 | draw.read_framebuffer = 0; | 156 | draw.read_framebuffer = 0; |
| 142 | draw.draw_framebuffer = 0; | 157 | draw.draw_framebuffer = 0; |
| 143 | draw.vertex_array = 0; | 158 | draw.vertex_array = 0; |
| @@ -496,72 +511,20 @@ void OpenGLState::ApplyAlphaTest() const { | |||
| 496 | } | 511 | } |
| 497 | 512 | ||
| 498 | void OpenGLState::ApplyTextures() const { | 513 | void OpenGLState::ApplyTextures() const { |
| 499 | bool has_delta{}; | 514 | if (const auto update = UpdateArray(cur_state.textures, textures)) { |
| 500 | std::size_t first{}; | 515 | glBindTextures(update->first, update->second, textures.data() + update->first); |
| 501 | std::size_t last{}; | ||
| 502 | std::array<GLuint, Maxwell::NumTextureSamplers> textures; | ||
| 503 | |||
| 504 | for (std::size_t i = 0; i < std::size(texture_units); ++i) { | ||
| 505 | const auto& texture_unit = texture_units[i]; | ||
| 506 | auto& cur_state_texture_unit = cur_state.texture_units[i]; | ||
| 507 | textures[i] = texture_unit.texture; | ||
| 508 | if (cur_state_texture_unit.texture == textures[i]) { | ||
| 509 | continue; | ||
| 510 | } | ||
| 511 | cur_state_texture_unit.texture = textures[i]; | ||
| 512 | if (!has_delta) { | ||
| 513 | first = i; | ||
| 514 | has_delta = true; | ||
| 515 | } | ||
| 516 | last = i; | ||
| 517 | } | ||
| 518 | if (has_delta) { | ||
| 519 | glBindTextures(static_cast<GLuint>(first), static_cast<GLsizei>(last - first + 1), | ||
| 520 | textures.data() + first); | ||
| 521 | } | 516 | } |
| 522 | } | 517 | } |
| 523 | 518 | ||
| 524 | void OpenGLState::ApplySamplers() const { | 519 | void OpenGLState::ApplySamplers() const { |
| 525 | bool has_delta{}; | 520 | if (const auto update = UpdateArray(cur_state.samplers, samplers)) { |
| 526 | std::size_t first{}; | 521 | glBindSamplers(update->first, update->second, samplers.data() + update->first); |
| 527 | std::size_t last{}; | ||
| 528 | std::array<GLuint, Maxwell::NumTextureSamplers> samplers; | ||
| 529 | |||
| 530 | for (std::size_t i = 0; i < std::size(samplers); ++i) { | ||
| 531 | samplers[i] = texture_units[i].sampler; | ||
| 532 | if (cur_state.texture_units[i].sampler == texture_units[i].sampler) { | ||
| 533 | continue; | ||
| 534 | } | ||
| 535 | cur_state.texture_units[i].sampler = texture_units[i].sampler; | ||
| 536 | if (!has_delta) { | ||
| 537 | first = i; | ||
| 538 | has_delta = true; | ||
| 539 | } | ||
| 540 | last = i; | ||
| 541 | } | ||
| 542 | if (has_delta) { | ||
| 543 | glBindSamplers(static_cast<GLuint>(first), static_cast<GLsizei>(last - first + 1), | ||
| 544 | samplers.data() + first); | ||
| 545 | } | 522 | } |
| 546 | } | 523 | } |
| 547 | 524 | ||
| 548 | void OpenGLState::ApplyImages() const { | 525 | void OpenGLState::ApplyImages() const { |
| 549 | bool has_delta{}; | 526 | if (const auto update = UpdateArray(cur_state.images, images)) { |
| 550 | std::size_t first{}; | 527 | glBindImageTextures(update->first, update->second, images.data() + update->first); |
| 551 | std::size_t last{}; | ||
| 552 | for (std::size_t i = 0; i < std::size(images); ++i) { | ||
| 553 | if (!UpdateValue(cur_state.images[i], images[i])) { | ||
| 554 | continue; | ||
| 555 | } | ||
| 556 | if (!has_delta) { | ||
| 557 | first = i; | ||
| 558 | has_delta = true; | ||
| 559 | } | ||
| 560 | last = i; | ||
| 561 | } | ||
| 562 | if (has_delta) { | ||
| 563 | glBindImageTextures(static_cast<GLuint>(first), static_cast<GLsizei>(last - first + 1), | ||
| 564 | images.data() + first); | ||
| 565 | } | 528 | } |
| 566 | } | 529 | } |
| 567 | 530 | ||
| @@ -627,18 +590,18 @@ void OpenGLState::EmulateViewportWithScissor() { | |||
| 627 | } | 590 | } |
| 628 | 591 | ||
| 629 | OpenGLState& OpenGLState::UnbindTexture(GLuint handle) { | 592 | OpenGLState& OpenGLState::UnbindTexture(GLuint handle) { |
| 630 | for (auto& unit : texture_units) { | 593 | for (auto& texture : textures) { |
| 631 | if (unit.texture == handle) { | 594 | if (texture == handle) { |
| 632 | unit.Unbind(); | 595 | texture = 0; |
| 633 | } | 596 | } |
| 634 | } | 597 | } |
| 635 | return *this; | 598 | return *this; |
| 636 | } | 599 | } |
| 637 | 600 | ||
| 638 | OpenGLState& OpenGLState::ResetSampler(GLuint handle) { | 601 | OpenGLState& OpenGLState::ResetSampler(GLuint handle) { |
| 639 | for (auto& unit : texture_units) { | 602 | for (auto& sampler : samplers) { |
| 640 | if (unit.sampler == handle) { | 603 | if (sampler == handle) { |
| 641 | unit.sampler = 0; | 604 | sampler = 0; |
| 642 | } | 605 | } |
| 643 | } | 606 | } |
| 644 | return *this; | 607 | return *this; |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 9748d60e2..949b13051 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -118,22 +118,8 @@ public: | |||
| 118 | GLenum operation; | 118 | GLenum operation; |
| 119 | } logic_op; | 119 | } logic_op; |
| 120 | 120 | ||
| 121 | // 3 texture units - one for each that is used in PICA fragment shader emulation | 121 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures{}; |
| 122 | struct TextureUnit { | 122 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers{}; |
| 123 | GLuint texture; // GL_TEXTURE_BINDING_2D | ||
| 124 | GLuint sampler; // GL_SAMPLER_BINDING | ||
| 125 | |||
| 126 | void Unbind() { | ||
| 127 | texture = 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | void Reset() { | ||
| 131 | Unbind(); | ||
| 132 | sampler = 0; | ||
| 133 | } | ||
| 134 | }; | ||
| 135 | std::array<TextureUnit, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_units; | ||
| 136 | |||
| 137 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{}; | 123 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{}; |
| 138 | 124 | ||
| 139 | struct { | 125 | struct { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index af9684839..839178152 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -342,7 +342,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 342 | ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), | 342 | ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), |
| 343 | }}; | 343 | }}; |
| 344 | 344 | ||
| 345 | state.texture_units[0].texture = screen_info.display_texture; | 345 | state.textures[0] = screen_info.display_texture; |
| 346 | // Workaround brigthness problems in SMO by enabling sRGB in the final output | 346 | // Workaround brigthness problems in SMO by enabling sRGB in the final output |
| 347 | // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987 | 347 | // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987 |
| 348 | state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); | 348 | state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); |
| @@ -352,7 +352,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 352 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 352 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 353 | // Restore default state | 353 | // Restore default state |
| 354 | state.framebuffer_srgb.enabled = false; | 354 | state.framebuffer_srgb.enabled = false; |
| 355 | state.texture_units[0].texture = 0; | 355 | state.textures[0] = 0; |
| 356 | state.AllDirty(); | 356 | state.AllDirty(); |
| 357 | state.Apply(); | 357 | state.Apply(); |
| 358 | // Clear sRGB state for the next frame | 358 | // Clear sRGB state for the next frame |