summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-03-26 21:54:16 -0500
committerJames Rowe <jroweboy@gmail.com>2018-04-06 20:44:46 -0600
commitb0ca330e149b5f1609980a8167faa0c363066fd2 (patch)
tree8ded3061ecb0cacf79e0f4b5d192c8fdddd09de4 /src
parentcb3183212d72836a7b6b196fde9896de66db62e6 (diff)
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() {
// TODO(bunnei): Sync framebuffer_scale uniform here
// TODO(bunnei): Sync scissorbox uniform(s) here
- // TODO(bunnei): Sync and bind the texture surfaces
+
+ // Sync and bind the texture surfaces
+ BindTextures();
// Sync and bind the shader
if (shader_dirty) {
@@ -380,6 +382,39 @@ void RasterizerOpenGL::DrawArrays() {
}
}
+void RasterizerOpenGL::BindTextures() {
+ using Regs = Tegra::Engines::Maxwell3D::Regs;
+ auto maxwell3d = Core::System::GetInstance().GPU().Get3DEngine();
+
+ // 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.
+ u32 host_texture_index = 0;
+ for (u32 stage = 0; stage < Regs::MaxShaderStage; ++stage) {
+ ASSERT(host_texture_index < texture_samplers.size());
+ const auto textures = maxwell3d.GetStageTextures(static_cast<Regs::ShaderStage>(stage));
+ for (unsigned texture_index = 0; texture_index < textures.size(); ++texture_index) {
+ const auto& texture = textures[texture_index];
+
+ if (texture.enabled) {
+ texture_samplers[host_texture_index].SyncWithConfig(texture.tsc);
+ Surface surface = res_cache.GetTextureSurface(texture);
+ if (surface != nullptr) {
+ state.texture_units[host_texture_index].texture_2d = surface->texture.handle;
+ } else {
+ // Can occur when texture addr is null or its memory is unmapped/invalid
+ state.texture_units[texture_index].texture_2d = 0;
+ }
+
+ ++host_texture_index;
+ } else {
+ state.texture_units[texture_index].texture_2d = 0;
+ }
+ }
+ }
+}
+
void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {}
void RasterizerOpenGL::FlushAll() {
@@ -470,7 +505,6 @@ void RasterizerOpenGL::SamplerInfo::Create() {
}
void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
-
GLuint s = sampler.handle;
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:
void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
bool has_stencil);
+ /// Binds the required textures to OpenGL before drawing a batch.
+ void BindTextures();
+
/// Syncs the viewport to match the guest state
void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);