diff options
| author | 2015-08-30 10:05:56 -0300 | |
|---|---|---|
| committer | 2015-09-03 15:09:51 -0300 | |
| commit | b044c047c48469be479ba2633ae14eff8643041e (patch) | |
| tree | f76ddff71ac10838e6429815d8267c82b602737f /src | |
| parent | OpenGL: Remove ugly and endian-unsafe color pointer casts (diff) | |
| download | yuzu-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.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 7 |
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 | ||
| 454 | void 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 | |||
| 464 | void 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 | |||
| 448 | void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height) { | 493 | void 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 | ||
| 21 | MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); | 21 | MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); |
| 22 | 22 | ||
| 23 | void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned texture_unit, const Pica::Regs::FullTextureConfig& config) { | 23 | void 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); |