rasterizer_cache: Use SurfaceType instead of Aspect
* It was doing pointless enum conversions when both enums described the same thing
This commit is contained in:
@ -23,6 +23,8 @@ struct Rectangle {
|
||||
constexpr Rectangle(T left, T top, T right, T bottom)
|
||||
: left(left), top(top), right(right), bottom(bottom) {}
|
||||
|
||||
auto operator<=>(const Rectangle&) const = default;
|
||||
|
||||
[[nodiscard]] T GetWidth() const {
|
||||
return std::abs(static_cast<std::make_signed_t<T>>(right - left));
|
||||
}
|
||||
|
@ -6,12 +6,14 @@
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/texture.h"
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "video_core/rasterizer_cache/cached_surface.h"
|
||||
#include "video_core/rasterizer_cache/morton_swizzle.h"
|
||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/gl_state.h"
|
||||
#include "video_core/renderer_opengl/gl_vars.h"
|
||||
#include "video_core/renderer_opengl/texture_downloader_es.h"
|
||||
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
@ -337,8 +339,17 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
|
||||
const Common::Rectangle<u32> from_rect{0, height, width, 0};
|
||||
|
||||
if (!owner.texture_filterer->Filter(unscaled_tex, from_rect, texture, scaled_rect, type)) {
|
||||
const Aspect aspect = ToAspect(type);
|
||||
runtime.BlitTextures(unscaled_tex, {aspect, from_rect}, texture, {aspect, scaled_rect});
|
||||
const Subresource src_subresource = {
|
||||
.type = type,
|
||||
.region = from_rect
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.type = type,
|
||||
.region = scaled_rect
|
||||
};
|
||||
|
||||
runtime.BlitTextures(unscaled_tex, src_subresource, texture, dst_subresource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +381,6 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
|
||||
const FormatTuple& tuple = GetFormatTuple(pixel_format);
|
||||
|
||||
// If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
|
||||
const Aspect aspect = ToAspect(type);
|
||||
if (res_scale != 1) {
|
||||
auto scaled_rect = rect;
|
||||
scaled_rect.left *= res_scale;
|
||||
@ -380,9 +390,19 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
|
||||
|
||||
const Common::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0};
|
||||
auto unscaled_tex = owner.AllocateSurfaceTexture(pixel_format, rect.GetWidth(), rect.GetHeight());
|
||||
|
||||
const Subresource src_subresource = {
|
||||
.type = type,
|
||||
.region = scaled_rect
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.type = type,
|
||||
.region = unscaled_tex_rect
|
||||
};
|
||||
|
||||
// Blit scaled texture to the unscaled one
|
||||
runtime.BlitTextures(texture, {aspect, scaled_rect}, unscaled_tex,
|
||||
{aspect, unscaled_tex_rect});
|
||||
runtime.BlitTextures(texture, src_subresource, unscaled_tex, dst_subresource);
|
||||
|
||||
state.texture_units[0].texture_2d = unscaled_tex.handle;
|
||||
state.Apply();
|
||||
@ -396,7 +416,12 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, &gl_buffer[buffer_offset]);
|
||||
}
|
||||
} else {
|
||||
runtime.ReadTexture(texture, {aspect, rect}, tuple, gl_buffer.data());
|
||||
const Subresource subresource = {
|
||||
.type = type,
|
||||
.region = rect
|
||||
};
|
||||
|
||||
runtime.ReadTexture(texture, subresource, tuple, gl_buffer.data());
|
||||
}
|
||||
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
|
@ -48,9 +48,8 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst
|
||||
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
|
||||
ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
|
||||
|
||||
const Aspect aspect = ToAspect(dst_surface->type);
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = dst_surface->type,
|
||||
.region = dst_surface->GetScaledSubRect(subrect_params)
|
||||
};
|
||||
|
||||
@ -66,7 +65,7 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst
|
||||
}
|
||||
|
||||
const ClearValue clear_value =
|
||||
MakeClearValue(aspect, dst_surface->pixel_format, fill_buffer.data());
|
||||
MakeClearValue(dst_surface->type, dst_surface->pixel_format, fill_buffer.data());
|
||||
|
||||
runtime.ClearTexture(dst_surface->texture, dst_subresource, clear_value);
|
||||
return;
|
||||
@ -74,7 +73,7 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& dst
|
||||
|
||||
if (src_surface->CanSubRect(subrect_params)) {
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = src_surface->type,
|
||||
.region = src_surface->GetScaledSubRect(subrect_params)
|
||||
};
|
||||
|
||||
@ -209,14 +208,13 @@ bool RasterizerCache::BlitSurfaces(const Surface& src_surface,
|
||||
if (CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) {
|
||||
dst_surface->InvalidateAllWatcher();
|
||||
|
||||
const Aspect aspect = ToAspect(src_surface->type);
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = src_surface->type,
|
||||
.region = src_rect
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = dst_surface->type,
|
||||
.region = dst_rect
|
||||
};
|
||||
|
||||
@ -441,14 +439,13 @@ Surface RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo& inf
|
||||
}
|
||||
|
||||
if (!surface->is_custom && texture_filterer->IsNull()) {
|
||||
const Aspect aspect = ToAspect(surface->type);
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = surface->type,
|
||||
.region = level_surface->GetScaledRect()
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = surface->type,
|
||||
.region = surface_params.GetScaledRect(),
|
||||
.level = level
|
||||
};
|
||||
@ -531,14 +528,13 @@ const CachedTextureCube& RasterizerCache::GetTextureCube(const TextureCubeConfig
|
||||
ValidateSurface(surface, surface->addr, surface->size);
|
||||
}
|
||||
|
||||
const Aspect aspect = ToAspect(surface->type);
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = surface->type,
|
||||
.region = surface->GetScaledRect()
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = surface->type,
|
||||
.region = Common::Rectangle<u32>{0, scaled_size, scaled_size, 0}
|
||||
};
|
||||
|
||||
@ -862,14 +858,13 @@ bool RasterizerCache::ValidateByReinterpretation(const Surface& surface,
|
||||
if (!texture_filterer->Filter(tmp_tex, tmp_rect, surface->texture, dest_rect,
|
||||
type)) {
|
||||
|
||||
const Aspect aspect = ToAspect(type);
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = type,
|
||||
.region = tmp_rect
|
||||
};
|
||||
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.type = type,
|
||||
.region = dest_rect
|
||||
};
|
||||
|
||||
|
@ -9,15 +9,21 @@
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
GLbitfield ToBufferMask(Aspect aspect) {
|
||||
switch (aspect) {
|
||||
case Aspect::Color:
|
||||
GLbitfield MakeBufferMask(SurfaceType type) {
|
||||
switch (type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill:
|
||||
return GL_COLOR_BUFFER_BIT;
|
||||
case Aspect::Depth:
|
||||
case SurfaceType::Depth:
|
||||
return GL_DEPTH_BUFFER_BIT;
|
||||
case Aspect::DepthStencil:
|
||||
case SurfaceType::DepthStencil:
|
||||
return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid surface type!");
|
||||
}
|
||||
|
||||
return GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
TextureRuntime::TextureRuntime() {
|
||||
@ -37,24 +43,28 @@ void TextureRuntime::ReadTexture(const OGLTexture& tex, Subresource subresource,
|
||||
state.Apply();
|
||||
|
||||
const u32 level = subresource.level;
|
||||
switch (subresource.aspect) {
|
||||
case Aspect::Color:
|
||||
switch (subresource.type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill:
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.handle,
|
||||
level);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
0);
|
||||
break;
|
||||
case Aspect::Depth:
|
||||
case SurfaceType::Depth:
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex.handle,
|
||||
level);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
break;
|
||||
case Aspect::DepthStencil:
|
||||
case SurfaceType::DepthStencil:
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
tex.handle, level);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid surface type!");
|
||||
}
|
||||
|
||||
const auto& rect = subresource.region;
|
||||
@ -79,8 +89,10 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource
|
||||
state.Apply();
|
||||
|
||||
const u32 level = subresource.level;
|
||||
switch (subresource.aspect) {
|
||||
case Aspect::Color:
|
||||
switch (subresource.type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill:
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.handle,
|
||||
level);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
@ -94,7 +106,7 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource
|
||||
|
||||
glClearBufferfv(GL_COLOR, 0, value.color.AsArray());
|
||||
break;
|
||||
case Aspect::Depth:
|
||||
case SurfaceType::Depth:
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex.handle,
|
||||
level);
|
||||
@ -105,7 +117,7 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource
|
||||
|
||||
glClearBufferfv(GL_DEPTH, 0, &value.depth);
|
||||
break;
|
||||
case Aspect::DepthStencil:
|
||||
case SurfaceType::DepthStencil:
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
tex.handle, level);
|
||||
@ -116,6 +128,8 @@ bool TextureRuntime::ClearTexture(const OGLTexture& tex, Subresource subresource
|
||||
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, value.depth, value.stencil);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid surface type!");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -146,24 +160,28 @@ bool TextureRuntime::BlitTextures(const OGLTexture& src_tex, Subresource src_sub
|
||||
};
|
||||
|
||||
// Sanity check; Can't blit a color texture to a depth buffer
|
||||
ASSERT(src_subresource.aspect == dst_subresource.aspect);
|
||||
switch (src_subresource.aspect) {
|
||||
case Aspect::Color:
|
||||
ASSERT(src_subresource.type == dst_subresource.type);
|
||||
switch (src_subresource.type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill:
|
||||
// Bind only color
|
||||
BindAttachment(GL_COLOR_ATTACHMENT0, src_tex.handle, dst_tex.handle);
|
||||
BindAttachment(GL_DEPTH_STENCIL_ATTACHMENT, 0, 0);
|
||||
break;
|
||||
case Aspect::Depth:
|
||||
case SurfaceType::Depth:
|
||||
// Bind only depth
|
||||
BindAttachment(GL_COLOR_ATTACHMENT0, 0, 0);
|
||||
BindAttachment(GL_DEPTH_ATTACHMENT, src_tex.handle, dst_tex.handle);
|
||||
BindAttachment(GL_STENCIL_ATTACHMENT, 0, 0);
|
||||
break;
|
||||
case Aspect::DepthStencil:
|
||||
case SurfaceType::DepthStencil:
|
||||
// Bind to combined depth + stencil
|
||||
BindAttachment(GL_COLOR_ATTACHMENT0, 0, 0);
|
||||
BindAttachment(GL_DEPTH_STENCIL_ATTACHMENT, src_tex.handle, dst_tex.handle);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid surface type!");
|
||||
}
|
||||
|
||||
// TODO (wwylele): use GL_NEAREST for shadow map texture
|
||||
@ -171,12 +189,13 @@ bool TextureRuntime::BlitTextures(const OGLTexture& src_tex, Subresource src_sub
|
||||
// doing linear intepolation componentwise would cause incorrect value. However, for a
|
||||
// well-programmed game this code path should be rarely executed for shadow map with
|
||||
// inconsistent scale.
|
||||
const GLenum filter = src_subresource.aspect == Aspect::Color ? GL_LINEAR : GL_NEAREST;
|
||||
const GLbitfield buffer_mask = MakeBufferMask(src_subresource.type);
|
||||
const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST;
|
||||
const auto& src_rect = src_subresource.region;
|
||||
const auto& dst_rect = dst_subresource.region;
|
||||
glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left,
|
||||
dst_rect.bottom, dst_rect.right, dst_rect.top,
|
||||
ToBufferMask(src_subresource.aspect), filter);
|
||||
buffer_mask, filter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3,18 +3,12 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include "common/common_types.h"
|
||||
#include "common/math_util.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
// Describes the type of data a texture holds
|
||||
enum class Aspect { Color = 0, Depth = 1, DepthStencil = 2 };
|
||||
|
||||
// A union for both color and depth/stencil clear values
|
||||
union ClearValue {
|
||||
Common::Vec4f color;
|
||||
@ -27,7 +21,7 @@ union ClearValue {
|
||||
struct Subresource {
|
||||
auto operator<=>(const Subresource&) const = default;
|
||||
|
||||
Aspect aspect;
|
||||
SurfaceType type;
|
||||
Common::Rectangle<u32> region;
|
||||
u32 level = 0;
|
||||
u32 layer = 0;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
||||
#include "common/assert.h"
|
||||
#include "video_core/texture/texture_decode.h"
|
||||
#include "video_core/rasterizer_cache/morton_swizzle.h"
|
||||
#include "video_core/rasterizer_cache/surface_params.h"
|
||||
@ -99,10 +100,12 @@ void UnswizzleTexture(const SurfaceParams& params, u32 load_start, u32 load_end,
|
||||
}
|
||||
}
|
||||
|
||||
ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data) {
|
||||
ClearValue MakeClearValue(SurfaceType type, PixelFormat format, const u8* fill_data) {
|
||||
ClearValue result{};
|
||||
switch (aspect) {
|
||||
case Aspect::Color: {
|
||||
switch (type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill: {
|
||||
Pica::Texture::TextureInfo tex_info{};
|
||||
tex_info.format = static_cast<Pica::TexturingRegs::TextureFormat>(format);
|
||||
|
||||
@ -110,7 +113,7 @@ ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data
|
||||
result.color = color / 255.f;
|
||||
break;
|
||||
}
|
||||
case Aspect::Depth: {
|
||||
case SurfaceType::Depth: {
|
||||
u32 depth_uint = 0;
|
||||
if (format == PixelFormat::D16) {
|
||||
std::memcpy(&depth_uint, fill_data, 2);
|
||||
@ -121,7 +124,7 @@ ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Aspect::DepthStencil: {
|
||||
case SurfaceType::DepthStencil: {
|
||||
u32 clear_value_uint;
|
||||
std::memcpy(&clear_value_uint, fill_data, sizeof(u32));
|
||||
|
||||
@ -129,27 +132,11 @@ ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data
|
||||
result.stencil = (clear_value_uint >> 24);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid surface type!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Aspect ToAspect(SurfaceType type) {
|
||||
switch (type) {
|
||||
case SurfaceType::Color:
|
||||
case SurfaceType::Texture:
|
||||
case SurfaceType::Fill:
|
||||
return Aspect::Color;
|
||||
case SurfaceType::Depth:
|
||||
return Aspect::Depth;
|
||||
case SurfaceType::DepthStencil:
|
||||
return Aspect::DepthStencil;
|
||||
default:
|
||||
LOG_CRITICAL(Render_OpenGL, "Unknown SurfaceType {}", type);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return Aspect::Color;
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
@ -56,9 +56,7 @@ void SwizzleTexture(const SurfaceParams& params, u32 flush_start, u32 flush_end,
|
||||
void UnswizzleTexture(const SurfaceParams& params, u32 load_start, u32 load_end,
|
||||
std::span<const std::byte> source, std::span<std::byte> dest);
|
||||
|
||||
[[nodiscard]] ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data);
|
||||
|
||||
[[nodiscard]] Aspect ToAspect(SurfaceType type);
|
||||
[[nodiscard]] ClearValue MakeClearValue(SurfaceType type, PixelFormat format, const u8* fill_data);
|
||||
|
||||
} // namespace OpenGL
|
||||
|
||||
|
Reference in New Issue
Block a user