summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-08-30 10:05:56 -0300
committerGravatar Yuri Kunde Schlesner2015-09-03 15:09:51 -0300
commitb044c047c48469be479ba2633ae14eff8643041e (patch)
treef76ddff71ac10838e6429815d8267c82b602737f /src
parentOpenGL: Remove ugly and endian-unsafe color pointer casts (diff)
downloadyuzu-b044c047c48469be479ba2633ae14eff8643041e.tar.gz
yuzu-b044c047c48469be479ba2633ae14eff8643041e.tar.xz
yuzu-b044c047c48469be479ba2633ae14eff8643041e.zip
OpenGL: Use Sampler Objects to decouple sampler config from textures
Fixes #978
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp46
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h19
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp25
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h7
4 files changed, 76 insertions, 21 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index b556ea65b..0260a28ce 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -68,6 +68,12 @@ void RasterizerOpenGL::InitObjects() {
68 uniform_tev_cfg.updates_combiner_buffer_color_alpha = glGetUniformLocation(shader.handle, (tev_ref_str + ".updates_combiner_buffer_color_alpha").c_str()); 68 uniform_tev_cfg.updates_combiner_buffer_color_alpha = glGetUniformLocation(shader.handle, (tev_ref_str + ".updates_combiner_buffer_color_alpha").c_str());
69 } 69 }
70 70
71 // Create sampler objects
72 for (int i = 0; i < texture_samplers.size(); ++i) {
73 texture_samplers[i].Create();
74 state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
75 }
76
71 // Generate VBO and VAO 77 // Generate VBO and VAO
72 vertex_buffer.Create(); 78 vertex_buffer.Create();
73 vertex_array.Create(); 79 vertex_array.Create();
@@ -445,6 +451,45 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) {
445 res_cache.NotifyFlush(addr, size); 451 res_cache.NotifyFlush(addr, size);
446} 452}
447 453
454void RasterizerOpenGL::SamplerInfo::Create() {
455 sampler.Create();
456 mag_filter = min_filter = TextureConfig::Linear;
457 wrap_s = wrap_t = TextureConfig::Repeat;
458 border_color = 0;
459
460 glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // default is GL_LINEAR_MIPMAP_LINEAR
461 // Other attributes have correct defaults
462}
463
464void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Pica::Regs::TextureConfig& config) {
465 GLuint s = sampler.handle;
466
467 if (mag_filter != config.mag_filter) {
468 mag_filter = config.mag_filter;
469 glSamplerParameteri(s, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(mag_filter));
470 }
471 if (min_filter != config.min_filter) {
472 min_filter = config.min_filter;
473 glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(min_filter));
474 }
475
476 if (wrap_s != config.wrap_s) {
477 wrap_s = config.wrap_s;
478 glSamplerParameteri(s, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(wrap_s));
479 }
480 if (wrap_t != config.wrap_t) {
481 wrap_t = config.wrap_t;
482 glSamplerParameteri(s, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(wrap_t));
483 }
484
485 if (wrap_s == TextureConfig::ClampToBorder || wrap_t == TextureConfig::ClampToBorder) {
486 if (border_color != config.border_color.raw) {
487 auto gl_color = PicaToGL::ColorRGBA8(border_color);
488 glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, gl_color.data());
489 }
490 }
491}
492
448void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height) { 493void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height) {
449 GLint internal_format; 494 GLint internal_format;
450 495
@@ -772,6 +817,7 @@ void RasterizerOpenGL::SyncDrawState() {
772 const auto& texture = pica_textures[texture_index]; 817 const auto& texture = pica_textures[texture_index];
773 818
774 if (texture.enabled) { 819 if (texture.enabled) {
820 texture_samplers[texture_index].SyncWithConfig(texture.config);
775 res_cache.LoadAndBindTexture(state, texture_index, texture); 821 res_cache.LoadAndBindTexture(state, texture_index, texture);
776 } else { 822 } else {
777 state.texture_units[texture_index].texture_2d = 0; 823 state.texture_units[texture_index].texture_2d = 0;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index a02d5c856..24560d7f8 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -80,6 +80,24 @@ private:
80 GLenum gl_type; 80 GLenum gl_type;
81 }; 81 };
82 82
83 struct SamplerInfo {
84 using TextureConfig = Pica::Regs::TextureConfig;
85
86 OGLSampler sampler;
87
88 /// Creates the sampler object, initializing its state so that it's in sync with the SamplerInfo struct.
89 void Create();
90 /// Syncs the sampler object with the config, updating any necessary state.
91 void SyncWithConfig(const TextureConfig& config);
92
93 private:
94 TextureConfig::TextureFilter mag_filter;
95 TextureConfig::TextureFilter min_filter;
96 TextureConfig::WrapMode wrap_s;
97 TextureConfig::WrapMode wrap_t;
98 u32 border_color;
99 };
100
83 /// Structure that the hardware rendered vertices are composed of 101 /// Structure that the hardware rendered vertices are composed of
84 struct HardwareVertex { 102 struct HardwareVertex {
85 HardwareVertex(const Pica::Shader::OutputVertex& v) { 103 HardwareVertex(const Pica::Shader::OutputVertex& v) {
@@ -193,6 +211,7 @@ private:
193 PAddr last_fb_depth_addr; 211 PAddr last_fb_depth_addr;
194 212
195 // Hardware rasterizer 213 // Hardware rasterizer
214 std::array<SamplerInfo, 3> texture_samplers;
196 TextureInfo fb_color_texture; 215 TextureInfo fb_color_texture;
197 DepthTextureInfo fb_depth_texture; 216 DepthTextureInfo fb_depth_texture;
198 OGLShader shader; 217 OGLShader shader;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 5d9a80cd4..d9ccf2a3f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -20,9 +20,8 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
20 20
21MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); 21MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
22 22
23void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { 23void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::DebugUtils::TextureInfo& info) {
24 PAddr texture_addr = config.config.GetPhysicalAddress(); 24 const auto cached_texture = texture_cache.find(info.physical_address);
25 const auto cached_texture = texture_cache.find(texture_addr);
26 25
27 if (cached_texture != texture_cache.end()) { 26 if (cached_texture != texture_cache.end()) {
28 state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle; 27 state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.handle;
@@ -37,26 +36,12 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
37 state.Apply(); 36 state.Apply();
38 glActiveTexture(GL_TEXTURE0 + texture_unit); 37 glActiveTexture(GL_TEXTURE0 + texture_unit);
39 38
40 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter)); 39 u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address);
41 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter));
42
43 GLenum wrap_s = PicaToGL::WrapMode(config.config.wrap_s);
44 GLenum wrap_t = PicaToGL::WrapMode(config.config.wrap_t);
45 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s);
46 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t);
47
48 if (wrap_s == GL_CLAMP_TO_BORDER || wrap_t == GL_CLAMP_TO_BORDER) {
49 auto border_color = PicaToGL::ColorRGBA8(config.config.border_color.raw);
50 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color.data());
51 }
52
53 const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format);
54 u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr);
55 40
56 new_texture->width = info.width; 41 new_texture->width = info.width;
57 new_texture->height = info.height; 42 new_texture->height = info.height;
58 new_texture->size = info.stride * info.height; 43 new_texture->size = info.stride * info.height;
59 new_texture->addr = texture_addr; 44 new_texture->addr = info.physical_address;
60 new_texture->hash = Common::ComputeHash64(texture_src_data, new_texture->size); 45 new_texture->hash = Common::ComputeHash64(texture_src_data, new_texture->size);
61 46
62 std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]); 47 std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]);
@@ -69,7 +54,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
69 54
70 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get()); 55 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_texture_buffer_rgba.get());
71 56
72 texture_cache.emplace(texture_addr, std::move(new_texture)); 57 texture_cache.emplace(info.physical_address, std::move(new_texture));
73 } 58 }
74} 59}
75 60
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index d8f9edf59..ec56237b5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -6,6 +6,7 @@
6 6
7#include "gl_state.h" 7#include "gl_state.h"
8#include "gl_resource_manager.h" 8#include "gl_resource_manager.h"
9#include "video_core/debug_utils/debug_utils.h"
9#include "video_core/pica.h" 10#include "video_core/pica.h"
10 11
11#include <memory> 12#include <memory>
@@ -16,7 +17,11 @@ public:
16 ~RasterizerCacheOpenGL(); 17 ~RasterizerCacheOpenGL();
17 18
18 /// Loads a texture from 3DS memory to OpenGL and caches it (if not already cached) 19 /// Loads a texture from 3DS memory to OpenGL and caches it (if not already cached)
19 void LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config); 20 void LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::DebugUtils::TextureInfo& info);
21
22 void LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) {
23 LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format));
24 }
20 25
21 /// Flush any cached resource that touches the flushed region 26 /// Flush any cached resource that touches the flushed region
22 void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false); 27 void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false);