summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-03-26 21:54:16 -0500
committerGravatar James Rowe2018-04-06 20:44:46 -0600
commitb0ca330e149b5f1609980a8167faa0c363066fd2 (patch)
tree8ded3061ecb0cacf79e0f4b5d192c8fdddd09de4 /src
parentGL: Bind the textures to the shaders used for drawing. (diff)
downloadyuzu-b0ca330e149b5f1609980a8167faa0c363066fd2.tar.gz
yuzu-b0ca330e149b5f1609980a8167faa0c363066fd2.tar.xz
yuzu-b0ca330e149b5f1609980a8167faa0c363066fd2.zip
GL: Set up the textures used for each draw call.
Each Maxwell shader stage can have an arbitrary number of textures, but we're limited to a certain number in OpenGL. We try to only use the minimum amount of host textures by not keeping a 1:1 relation between guest texture ids and host texture ids, ie, guest texture id 8 can be host texture id 0 if it's the only texture used in the guest shader program. This mapping will have to be passed to the shader decompiler so it can rewrite the texture accesses.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp38
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
2 files changed, 39 insertions, 2 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 77e2fd039..f217a265b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -276,7 +276,9 @@ void RasterizerOpenGL::DrawArrays() {
276 276
277 // TODO(bunnei): Sync framebuffer_scale uniform here 277 // TODO(bunnei): Sync framebuffer_scale uniform here
278 // TODO(bunnei): Sync scissorbox uniform(s) here 278 // TODO(bunnei): Sync scissorbox uniform(s) here
279 // TODO(bunnei): Sync and bind the texture surfaces 279
280 // Sync and bind the texture surfaces
281 BindTextures();
280 282
281 // Sync and bind the shader 283 // Sync and bind the shader
282 if (shader_dirty) { 284 if (shader_dirty) {
@@ -380,6 +382,39 @@ void RasterizerOpenGL::DrawArrays() {
380 } 382 }
381} 383}
382 384
385void RasterizerOpenGL::BindTextures() {
386 using Regs = Tegra::Engines::Maxwell3D::Regs;
387 auto maxwell3d = Core::System::GetInstance().GPU().Get3DEngine();
388
389 // Each Maxwell shader stage can have an arbitrary number of textures, but we're limited to a
390 // certain number in OpenGL. We try to only use the minimum amount of host textures by not
391 // keeping a 1:1 relation between guest texture ids and host texture ids, ie, guest texture id 8
392 // can be host texture id 0 if it's the only texture used in the guest shader program.
393 u32 host_texture_index = 0;
394 for (u32 stage = 0; stage < Regs::MaxShaderStage; ++stage) {
395 ASSERT(host_texture_index < texture_samplers.size());
396 const auto textures = maxwell3d.GetStageTextures(static_cast<Regs::ShaderStage>(stage));
397 for (unsigned texture_index = 0; texture_index < textures.size(); ++texture_index) {
398 const auto& texture = textures[texture_index];
399
400 if (texture.enabled) {
401 texture_samplers[host_texture_index].SyncWithConfig(texture.tsc);
402 Surface surface = res_cache.GetTextureSurface(texture);
403 if (surface != nullptr) {
404 state.texture_units[host_texture_index].texture_2d = surface->texture.handle;
405 } else {
406 // Can occur when texture addr is null or its memory is unmapped/invalid
407 state.texture_units[texture_index].texture_2d = 0;
408 }
409
410 ++host_texture_index;
411 } else {
412 state.texture_units[texture_index].texture_2d = 0;
413 }
414 }
415 }
416}
417
383void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {} 418void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {}
384 419
385void RasterizerOpenGL::FlushAll() { 420void RasterizerOpenGL::FlushAll() {
@@ -470,7 +505,6 @@ void RasterizerOpenGL::SamplerInfo::Create() {
470} 505}
471 506
472void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { 507void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
473
474 GLuint s = sampler.handle; 508 GLuint s = sampler.handle;
475 509
476 if (mag_filter != config.mag_filter) { 510 if (mag_filter != config.mag_filter) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ba2113921..d868bf421 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -110,6 +110,9 @@ private:
110 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, 110 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
111 bool has_stencil); 111 bool has_stencil);
112 112
113 /// Binds the required textures to OpenGL before drawing a batch.
114 void BindTextures();
115
113 /// Syncs the viewport to match the guest state 116 /// Syncs the viewport to match the guest state
114 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale); 117 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);
115 118