diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 38 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 |
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 | ||
| 385 | void 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 | |||
| 383 | void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {} | 418 | void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {} |
| 384 | 419 | ||
| 385 | void RasterizerOpenGL::FlushAll() { | 420 | void RasterizerOpenGL::FlushAll() { |
| @@ -470,7 +505,6 @@ void RasterizerOpenGL::SamplerInfo::Create() { | |||
| 470 | } | 505 | } |
| 471 | 506 | ||
| 472 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) { | 507 | void 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 | ||