summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-07-11 01:32:12 -0300
committerGravatar ReinUsesLisp2019-09-05 20:35:51 -0300
commit04cdecb7a114471fec50deab86bcd160ec85feb4 (patch)
tree69af6a51405451420ac7b80cf6d5b43f50b4e73f
parentgl_rasterizer: Implement image bindings (diff)
downloadyuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.tar.gz
yuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.tar.xz
yuzu-04cdecb7a114471fec50deab86bcd160ec85feb4.zip
gl_state: Split textures and samplers into two arrays
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp9
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp99
-rw-r--r--src/video_core/renderer_opengl/gl_state.h18
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp4
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
1019bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding, 1019bool 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
37template <typename T>
38std::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
37void Enable(GLenum cap, bool enable) { 56void 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
498void OpenGLState::ApplyTextures() const { 513void 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
524void OpenGLState::ApplySamplers() const { 519void 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
548void OpenGLState::ApplyImages() const { 525void 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
629OpenGLState& OpenGLState::UnbindTexture(GLuint handle) { 592OpenGLState& 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
638OpenGLState& OpenGLState::ResetSampler(GLuint handle) { 601OpenGLState& 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