summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Morph2020-06-16 01:30:01 -0400
committerGravatar Morph2020-06-16 03:03:07 -0400
commite2f5d165407ebb998cc24005bc30476ba29d5bcd (patch)
treed74286e399af31169b35b2bcc558858f88baa95e /src
parentMerge pull request #4091 from MerryMage/cmakelists-xbyak-order (diff)
downloadyuzu-e2f5d165407ebb998cc24005bc30476ba29d5bcd.tar.gz
yuzu-e2f5d165407ebb998cc24005bc30476ba29d5bcd.tar.xz
yuzu-e2f5d165407ebb998cc24005bc30476ba29d5bcd.zip
gl_device: Reserve at least 4 image bindings for fragment stage
Due to the limitation of GL_MAX_IMAGE_UNITS being low (8) on Intel's and Nvidia's proprietary drivers, we have to reserve an appropriate amount of image bindings for each of the stages. So far games have been observed to use 4 image bindings on the fragment stage (Kirby Star Allies) and 1 on the vertex stage (TWD series). No games thus far in my limited testing used more than 4 images concurrently and across all currently active programs. This fixes shader compilation errors on Kirby Star Allies on OpenGL (GLSL/GLASM)
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 890fc6c63..21a4f4def 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -123,16 +123,24 @@ std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindin
123 u32 num_images = GetInteger<u32>(GL_MAX_IMAGE_UNITS); 123 u32 num_images = GetInteger<u32>(GL_MAX_IMAGE_UNITS);
124 u32 base_images = 0; 124 u32 base_images = 0;
125 125
126 // Reserve more image bindings on fragment and vertex stages. 126 // GL_MAX_IMAGE_UNITS is guaranteed by the spec to have a minimum value of 8.
127 // Due to the limitation of GL_MAX_IMAGE_UNITS, reserve at least 4 image bindings on the
128 // fragment stage, and at least 1 for the rest of the stages.
129 // So far games are observed to use 1 image binding on vertex and 4 on fragment stages.
130
131 // Reserve at least 4 image bindings on the fragment stage.
127 bindings[4].image = 132 bindings[4].image =
128 Extract(base_images, num_images, num_images / NumStages + 2, LimitImages[4]); 133 Extract(base_images, num_images, std::max(4U, num_images / NumStages), LimitImages[4]);
129 bindings[0].image = 134
130 Extract(base_images, num_images, num_images / NumStages + 1, LimitImages[0]); 135 // This is guaranteed to be at least 1.
136 const u32 total_extracted_images = num_images / (NumStages - 1);
131 137
132 // Reserve the other image bindings. 138 // Reserve the other image bindings.
133 const u32 total_extracted_images = num_images / (NumStages - 2); 139 for (std::size_t i = 0; i < NumStages; ++i) {
134 for (std::size_t i = 2; i < NumStages; ++i) {
135 const std::size_t stage = stage_swizzle[i]; 140 const std::size_t stage = stage_swizzle[i];
141 if (stage == 4) {
142 continue;
143 }
136 bindings[stage].image = 144 bindings[stage].image =
137 Extract(base_images, num_images, total_extracted_images, LimitImages[stage]); 145 Extract(base_images, num_images, total_extracted_images, LimitImages[stage]);
138 } 146 }