summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2019-02-07 02:17:59 +0100
committerGitHub <noreply@github.com>2019-02-07 02:17:59 +0100
commit40ac0585574499bc0dee47c4bef354c8e5676695 (patch)
tree096b8e8c32f4affbd791386daa4b1feac2d9bedc /src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
parentMerge pull request #2057 from FearlessTobi/port-4586 (diff)
parentgl_rasterizer_cache: Fixup test clause (diff)
downloadyuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.gz
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.bz2
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.lz
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.xz
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.tar.zst
yuzu-40ac0585574499bc0dee47c4bef354c8e5676695.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_rasterizer_cache.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp242
1 files changed, 110 insertions, 132 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 50286432d..a79eee03e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -18,7 +18,6 @@
#include "video_core/morton.h"
#include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
-#include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/utils.h"
#include "video_core/surface.h"
#include "video_core/textures/astc.h"
@@ -44,14 +43,14 @@ struct FormatTuple {
bool compressed;
};
-static void ApplyTextureDefaults(GLenum target, u32 max_mip_level) {
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1);
+static void ApplyTextureDefaults(GLuint texture, u32 max_mip_level) {
+ glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTextureParameteri(texture, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1);
if (max_mip_level == 1) {
- glTexParameterf(target, GL_TEXTURE_LOD_BIAS, 1000.0);
+ glTextureParameterf(texture, GL_TEXTURE_LOD_BIAS, 1000.0);
}
}
@@ -529,55 +528,41 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
CachedSurface::CachedSurface(const SurfaceParams& params)
: params(params), gl_target(SurfaceTargetToGL(params.target)),
cached_size_in_bytes(params.size_in_bytes) {
- texture.Create();
- const auto& rect{params.GetRect()};
-
- // Keep track of previous texture bindings
- OpenGLState cur_state = OpenGLState::GetCurState();
- const auto& old_tex = cur_state.texture_units[0];
- SCOPE_EXIT({
- cur_state.texture_units[0] = old_tex;
- cur_state.Apply();
- });
-
- cur_state.texture_units[0].texture = texture.handle;
- cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
- cur_state.Apply();
- glActiveTexture(GL_TEXTURE0);
+ texture.Create(gl_target);
+
+ // TODO(Rodrigo): Using params.GetRect() returns a different size than using its Mip*(0)
+ // alternatives. This signals a bug on those functions.
+ const auto width = static_cast<GLsizei>(params.MipWidth(0));
+ const auto height = static_cast<GLsizei>(params.MipHeight(0));
const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type);
gl_internal_format = format_tuple.internal_format;
- gl_is_compressed = format_tuple.compressed;
- if (!format_tuple.compressed) {
- // Only pre-create the texture for non-compressed textures.
- switch (params.target) {
- case SurfaceTarget::Texture1D:
- glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level,
- format_tuple.internal_format, rect.GetWidth());
- break;
- case SurfaceTarget::Texture2D:
- case SurfaceTarget::TextureCubemap:
- glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level,
- format_tuple.internal_format, rect.GetWidth(), rect.GetHeight());
- break;
- case SurfaceTarget::Texture3D:
- case SurfaceTarget::Texture2DArray:
- case SurfaceTarget::TextureCubeArray:
- glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level,
- format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(),
- params.depth);
- break;
- default:
- LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
- static_cast<u32>(params.target));
- UNREACHABLE();
- glTexStorage2D(GL_TEXTURE_2D, params.max_mip_level, format_tuple.internal_format,
- rect.GetWidth(), rect.GetHeight());
- }
+ switch (params.target) {
+ case SurfaceTarget::Texture1D:
+ glTextureStorage1D(texture.handle, params.max_mip_level, format_tuple.internal_format,
+ width);
+ break;
+ case SurfaceTarget::Texture2D:
+ case SurfaceTarget::TextureCubemap:
+ glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
+ width, height);
+ break;
+ case SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::TextureCubeArray:
+ glTextureStorage3D(texture.handle, params.max_mip_level, format_tuple.internal_format,
+ width, height, params.depth);
+ break;
+ default:
+ LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
+ static_cast<u32>(params.target));
+ UNREACHABLE();
+ glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
+ width, height);
}
- ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level);
+ ApplyTextureDefaults(texture.handle, params.max_mip_level);
OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.addr, params.IdentityString());
@@ -751,63 +736,50 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
const auto& rect{params.GetRect(mip_map)};
// Load data from memory to the surface
- const GLint x0 = static_cast<GLint>(rect.left);
- const GLint y0 = static_cast<GLint>(rect.bottom);
- std::size_t buffer_offset =
+ const auto x0 = static_cast<GLint>(rect.left);
+ const auto y0 = static_cast<GLint>(rect.bottom);
+ auto buffer_offset =
static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) +
static_cast<std::size_t>(x0)) *
GetBytesPerPixel(params.pixel_format);
const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
- const GLuint target_tex = texture.handle;
- OpenGLState cur_state = OpenGLState::GetCurState();
-
- const auto& old_tex = cur_state.texture_units[0];
- SCOPE_EXIT({
- cur_state.texture_units[0] = old_tex;
- cur_state.Apply();
- });
- cur_state.texture_units[0].texture = target_tex;
- cur_state.texture_units[0].target = SurfaceTargetToGL(params.target);
- cur_state.Apply();
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map)));
- GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false));
- glActiveTexture(GL_TEXTURE0);
+ const auto image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false));
if (tuple.compressed) {
switch (params.target) {
case SurfaceTarget::Texture2D:
- glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
- static_cast<GLsizei>(params.MipWidth(mip_map)),
- static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size,
- &gl_buffer[mip_map][buffer_offset]);
+ glCompressedTextureSubImage2D(
+ texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
+ static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format, image_size,
+ &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::Texture3D:
- glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
- static_cast<GLsizei>(params.MipWidth(mip_map)),
- static_cast<GLsizei>(params.MipHeight(mip_map)),
- static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size,
- &gl_buffer[mip_map][buffer_offset]);
+ glCompressedTextureSubImage3D(
+ texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
+ static_cast<GLsizei>(params.MipHeight(mip_map)),
+ static_cast<GLsizei>(params.MipDepth(mip_map)), tuple.internal_format, image_size,
+ &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::Texture2DArray:
case SurfaceTarget::TextureCubeArray:
- glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
- static_cast<GLsizei>(params.MipWidth(mip_map)),
- static_cast<GLsizei>(params.MipHeight(mip_map)),
- static_cast<GLsizei>(params.depth), 0, image_size,
- &gl_buffer[mip_map][buffer_offset]);
+ glCompressedTextureSubImage3D(
+ texture.handle, mip_map, 0, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
+ static_cast<GLsizei>(params.MipHeight(mip_map)), static_cast<GLsizei>(params.depth),
+ tuple.internal_format, image_size, &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::TextureCubemap: {
- GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map));
+ const auto layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map));
for (std::size_t face = 0; face < params.depth; ++face) {
- glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face),
- mip_map, tuple.internal_format,
- static_cast<GLsizei>(params.MipWidth(mip_map)),
- static_cast<GLsizei>(params.MipHeight(mip_map)), 0,
- layer_size, &gl_buffer[mip_map][buffer_offset]);
+ glCompressedTextureSubImage3D(
+ texture.handle, mip_map, 0, 0, static_cast<GLint>(face),
+ static_cast<GLsizei>(params.MipWidth(mip_map)),
+ static_cast<GLsizei>(params.MipHeight(mip_map)), 1, tuple.internal_format,
+ layer_size, &gl_buffer[mip_map][buffer_offset]);
buffer_offset += layer_size;
}
break;
@@ -816,46 +788,43 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
static_cast<u32>(params.target));
UNREACHABLE();
- glCompressedTexImage2D(GL_TEXTURE_2D, mip_map, tuple.internal_format,
- static_cast<GLsizei>(params.MipWidth(mip_map)),
- static_cast<GLsizei>(params.MipHeight(mip_map)), 0,
- static_cast<GLsizei>(params.size_in_bytes_gl),
- &gl_buffer[mip_map][buffer_offset]);
+ glCompressedTextureSubImage2D(
+ texture.handle, mip_map, 0, 0, static_cast<GLsizei>(params.MipWidth(mip_map)),
+ static_cast<GLsizei>(params.MipHeight(mip_map)), tuple.internal_format,
+ static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[mip_map][buffer_offset]);
}
} else {
-
switch (params.target) {
case SurfaceTarget::Texture1D:
- glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0,
- static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type,
- &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage1D(texture.handle, mip_map, x0, static_cast<GLsizei>(rect.GetWidth()),
+ tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::Texture2D:
- glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0,
- static_cast<GLsizei>(rect.GetWidth()),
- static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
- &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage2D(texture.handle, mip_map, x0, y0,
+ static_cast<GLsizei>(rect.GetWidth()),
+ static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
+ &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::Texture3D:
- glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
- static_cast<GLsizei>(rect.GetWidth()),
- static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map),
- tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0,
+ static_cast<GLsizei>(rect.GetWidth()),
+ static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map),
+ tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::Texture2DArray:
case SurfaceTarget::TextureCubeArray:
- glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
- static_cast<GLsizei>(rect.GetWidth()),
- static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
- tuple.type, &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage3D(texture.handle, mip_map, x0, y0, 0,
+ static_cast<GLsizei>(rect.GetWidth()),
+ static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
+ tuple.type, &gl_buffer[mip_map][buffer_offset]);
break;
case SurfaceTarget::TextureCubemap: {
std::size_t start = buffer_offset;
for (std::size_t face = 0; face < params.depth; ++face) {
- glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map,
- x0, y0, static_cast<GLsizei>(rect.GetWidth()),
- static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
- &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage3D(texture.handle, mip_map, x0, y0, static_cast<GLint>(face),
+ static_cast<GLsizei>(rect.GetWidth()),
+ static_cast<GLsizei>(rect.GetHeight()), 1, tuple.format,
+ tuple.type, &gl_buffer[mip_map][buffer_offset]);
buffer_offset += params.LayerSizeGL(mip_map);
}
break;
@@ -864,9 +833,10 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
static_cast<u32>(params.target));
UNREACHABLE();
- glTexSubImage2D(GL_TEXTURE_2D, mip_map, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
- static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
- &gl_buffer[mip_map][buffer_offset]);
+ glTextureSubImage2D(texture.handle, mip_map, x0, y0,
+ static_cast<GLsizei>(rect.GetWidth()),
+ static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
+ &gl_buffer[mip_map][buffer_offset]);
}
}
@@ -876,29 +846,18 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
void CachedSurface::EnsureTextureView() {
if (texture_view.handle != 0)
return;
- // Compressed texture are not being created with immutable storage
- UNIMPLEMENTED_IF(gl_is_compressed);
const GLenum target{TargetLayer()};
const GLuint num_layers{target == GL_TEXTURE_CUBE_MAP_ARRAY ? 6u : 1u};
constexpr GLuint min_layer = 0;
constexpr GLuint min_level = 0;
- texture_view.Create();
- glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, min_level,
- params.max_mip_level, min_layer, num_layers);
-
- OpenGLState cur_state = OpenGLState::GetCurState();
- const auto& old_tex = cur_state.texture_units[0];
- SCOPE_EXIT({
- cur_state.texture_units[0] = old_tex;
- cur_state.Apply();
- });
- cur_state.texture_units[0].texture = texture_view.handle;
- cur_state.texture_units[0].target = target;
- cur_state.Apply();
-
- ApplyTextureDefaults(target, params.max_mip_level);
+ glGenTextures(1, &texture_view.handle);
+ glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, 0,
+ params.max_mip_level, 0, 1);
+ ApplyTextureDefaults(texture_view.handle, params.max_mip_level);
+ glTextureParameteriv(texture_view.handle, GL_TEXTURE_SWIZZLE_RGBA,
+ reinterpret_cast<const GLint*>(swizzle.data()));
}
MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));
@@ -909,6 +868,25 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle);
}
+void CachedSurface::UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x,
+ Tegra::Texture::SwizzleSource swizzle_y,
+ Tegra::Texture::SwizzleSource swizzle_z,
+ Tegra::Texture::SwizzleSource swizzle_w) {
+ const GLenum new_x = MaxwellToGL::SwizzleSource(swizzle_x);
+ const GLenum new_y = MaxwellToGL::SwizzleSource(swizzle_y);
+ const GLenum new_z = MaxwellToGL::SwizzleSource(swizzle_z);
+ const GLenum new_w = MaxwellToGL::SwizzleSource(swizzle_w);
+ if (swizzle[0] == new_x && swizzle[1] == new_y && swizzle[2] == new_z && swizzle[3] == new_w) {
+ return;
+ }
+ swizzle = {new_x, new_y, new_z, new_w};
+ const auto swizzle_data = reinterpret_cast<const GLint*>(swizzle.data());
+ glTextureParameteriv(texture.handle, GL_TEXTURE_SWIZZLE_RGBA, swizzle_data);
+ if (texture_view.handle != 0) {
+ glTextureParameteriv(texture_view.handle, GL_TEXTURE_SWIZZLE_RGBA, swizzle_data);
+ }
+}
+
RasterizerCacheOpenGL::RasterizerCacheOpenGL(RasterizerOpenGL& rasterizer)
: RasterizerCache{rasterizer} {
read_framebuffer.Create();