rasterizer_cache: Shorten filenames and general cleanup

* AllocateSurfaceTexture now takes the PixelFormat directly as FormatTuple is an OpenGL struct and will be moved there
This commit is contained in:
emufan4568
2022-09-06 22:15:39 +03:00
committed by GPUCode
parent f584d143ff
commit 1b1988a37a
14 changed files with 195 additions and 160 deletions

View File

@ -31,9 +31,9 @@ add_library(video_core STATIC
rasterizer_cache/pixel_format.h rasterizer_cache/pixel_format.h
rasterizer_cache/rasterizer_cache.cpp rasterizer_cache/rasterizer_cache.cpp
rasterizer_cache/rasterizer_cache.h rasterizer_cache/rasterizer_cache.h
rasterizer_cache/rasterizer_cache_types.h rasterizer_cache/types.h
rasterizer_cache/rasterizer_cache_utils.cpp rasterizer_cache/utils.cpp
rasterizer_cache/rasterizer_cache_utils.h rasterizer_cache/utils.h
rasterizer_cache/surface_params.cpp rasterizer_cache/surface_params.cpp
rasterizer_cache/surface_params.h rasterizer_cache/surface_params.h
rasterizer_cache/texture_runtime.cpp rasterizer_cache/texture_runtime.cpp

View File

@ -35,9 +35,9 @@ static Aspect ToAspect(SurfaceType type) {
CachedSurface::~CachedSurface() { CachedSurface::~CachedSurface() {
if (texture.handle) { if (texture.handle) {
auto tag = is_custom ? HostTextureTag{GetFormatTuple(PixelFormat::RGBA8), auto tag = is_custom ? HostTextureTag{PixelFormat::RGBA8,
custom_tex_info.width, custom_tex_info.height} custom_tex_info.width, custom_tex_info.height}
: HostTextureTag{GetFormatTuple(pixel_format), GetScaledWidth(), : HostTextureTag{pixel_format, GetScaledWidth(),
GetScaledHeight()}; GetScaledHeight()};
owner.host_texture_recycler.emplace(tag, std::move(texture)); owner.host_texture_recycler.emplace(tag, std::move(texture));
@ -294,7 +294,6 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
GLint y0 = static_cast<GLint>(rect.bottom); GLint y0 = static_cast<GLint>(rect.bottom);
std::size_t buffer_offset = (y0 * stride + x0) * GetBytesPerPixel(pixel_format); std::size_t buffer_offset = (y0 * stride + x0) * GetBytesPerPixel(pixel_format);
const FormatTuple& tuple = GetFormatTuple(pixel_format);
GLuint target_tex = texture.handle; GLuint target_tex = texture.handle;
// If not 1x scale, create 1x texture that we will blit from to replace texture subrect in // If not 1x scale, create 1x texture that we will blit from to replace texture subrect in
@ -305,11 +304,10 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
y0 = 0; y0 = 0;
if (is_custom) { if (is_custom) {
const auto& tuple = GetFormatTuple(PixelFormat::RGBA8);
unscaled_tex = unscaled_tex =
owner.AllocateSurfaceTexture(tuple, custom_tex_info.width, custom_tex_info.height); owner.AllocateSurfaceTexture(PixelFormat::RGBA8, custom_tex_info.width, custom_tex_info.height);
} else { } else {
unscaled_tex = owner.AllocateSurfaceTexture(tuple, rect.GetWidth(), rect.GetHeight()); unscaled_tex = owner.AllocateSurfaceTexture(pixel_format, rect.GetWidth(), rect.GetHeight());
} }
target_tex = unscaled_tex.handle; target_tex = unscaled_tex.handle;
@ -321,11 +319,13 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
cur_state.texture_units[0].texture_2d = target_tex; cur_state.texture_units[0].texture_2d = target_tex;
cur_state.Apply(); cur_state.Apply();
const FormatTuple& tuple = GetFormatTuple(pixel_format);
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0); ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
if (is_custom) { if (is_custom) {
if (res_scale == 1) { if (res_scale == 1) {
texture = owner.AllocateSurfaceTexture(GetFormatTuple(PixelFormat::RGBA8), texture = owner.AllocateSurfaceTexture(PixelFormat::RGBA8,
custom_tex_info.width, custom_tex_info.height); custom_tex_info.width, custom_tex_info.height);
cur_state.texture_units[0].texture_2d = texture.handle; cur_state.texture_units[0].texture_2d = texture.handle;
cur_state.Apply(); cur_state.Apply();
@ -341,6 +341,7 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(stride)); glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(stride));
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
&gl_buffer[buffer_offset]); &gl_buffer[buffer_offset]);
@ -390,14 +391,14 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
OpenGLState prev_state = state; OpenGLState prev_state = state;
SCOPE_EXIT({ prev_state.Apply(); }); SCOPE_EXIT({ prev_state.Apply(); });
const FormatTuple& tuple = GetFormatTuple(pixel_format);
// Ensure no bad interactions with GL_PACK_ALIGNMENT // Ensure no bad interactions with GL_PACK_ALIGNMENT
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0); ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride)); glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride));
const std::size_t buffer_offset = const std::size_t buffer_offset =
(rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format); (rect.bottom * stride + rect.left) * GetBytesPerPixel(pixel_format);
const FormatTuple& tuple = GetFormatTuple(pixel_format);
// If not 1x scale, blit scaled texture to a new 1x texture and use that to flush // If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
const Aspect aspect = ToAspect(type); const Aspect aspect = ToAspect(type);
if (res_scale != 1) { if (res_scale != 1) {
@ -408,7 +409,7 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
scaled_rect.bottom *= res_scale; scaled_rect.bottom *= res_scale;
const Common::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0}; const Common::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0};
auto unscaled_tex = owner.AllocateSurfaceTexture(tuple, rect.GetWidth(), rect.GetHeight()); auto unscaled_tex = owner.AllocateSurfaceTexture(pixel_format, rect.GetWidth(), rect.GetHeight());
// Blit scaled texture to the unscaled one // Blit scaled texture to the unscaled one
runtime.BlitTextures(texture, {aspect, scaled_rect}, unscaled_tex, runtime.BlitTextures(texture, {aspect, scaled_rect}, unscaled_tex,
{aspect, unscaled_tex_rect}); {aspect, unscaled_tex_rect});

View File

@ -11,6 +11,8 @@
namespace OpenGL { namespace OpenGL {
using SurfaceRegions = boost::icl::interval_set<PAddr, std::less, SurfaceInterval>;
/** /**
* A watcher that notifies whether a cached surface has been changed. This is useful for caching * A watcher that notifies whether a cached surface has been changed. This is useful for caching
* surface collection objects, including texture cube and mipmap. * surface collection objects, including texture cube and mipmap.

View File

@ -12,7 +12,7 @@ namespace OpenGL {
constexpr u32 PIXEL_FORMAT_COUNT = 18; constexpr u32 PIXEL_FORMAT_COUNT = 18;
enum class PixelFormat : u8 { enum class PixelFormat : u32 {
// First 5 formats are shared between textures and color buffers // First 5 formats are shared between textures and color buffers
RGBA8 = 0, RGBA8 = 0,
RGB8 = 1, RGB8 = 1,

View File

@ -35,50 +35,15 @@ static Aspect ToAspect(SurfaceType type) {
return Aspect::Color; return Aspect::Color;
} }
static ClearValue ToClearValue(Aspect aspect, PixelFormat format, const u8* fill_data) {
ClearValue result{};
switch (aspect) {
case Aspect::Color: {
Pica::Texture::TextureInfo tex_info{};
tex_info.format = static_cast<Pica::TexturingRegs::TextureFormat>(format);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
result.color = color / 255.f;
break;
}
case Aspect::Depth: {
u32 depth_uint = 0;
if (format == PixelFormat::D16) {
std::memcpy(&depth_uint, fill_data, 2);
result.depth = depth_uint / 65535.0f; // 2^16 - 1
} else if (format == PixelFormat::D24) {
std::memcpy(&depth_uint, fill_data, 3);
result.depth = depth_uint / 16777215.0f; // 2^24 - 1
}
break;
}
case Aspect::DepthStencil: {
u32 clear_value_uint;
std::memcpy(&clear_value_uint, fill_data, sizeof(u32));
result.depth = (clear_value_uint & 0xFFFFFF) / 16777215.0f; // 2^24 - 1
result.stencil = (clear_value_uint >> 24);
break;
}
}
return result;
}
template <typename Map, typename Interval> template <typename Map, typename Interval>
static constexpr auto RangeFromInterval(Map& map, const Interval& interval) { static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
return boost::make_iterator_range(map.equal_range(interval)); return boost::make_iterator_range(map.equal_range(interval));
} }
// Allocate an uninitialized texture of appropriate size and format for the surface // Allocate an uninitialized texture of appropriate size and format for the surface
OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(const FormatTuple& tuple, u32 width, OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(PixelFormat format, u32 width, u32 height) {
u32 height) { const FormatTuple& tuple = GetFormatTuple(format);
auto recycled_tex = host_texture_recycler.find({tuple, width, height}); auto recycled_tex = host_texture_recycler.find({format, width, height});
if (recycled_tex != host_texture_recycler.end()) { if (recycled_tex != host_texture_recycler.end()) {
OGLTexture texture = std::move(recycled_tex->second); OGLTexture texture = std::move(recycled_tex->second);
host_texture_recycler.erase(recycled_tex); host_texture_recycler.erase(recycled_tex);
@ -100,11 +65,14 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac
MICROPROFILE_SCOPE(OpenGL_CopySurface); MICROPROFILE_SCOPE(OpenGL_CopySurface);
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval); SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
ASSERT(subrect_params.GetInterval() == copy_interval); ASSERT(subrect_params.GetInterval() == copy_interval && src_surface != dst_surface);
ASSERT(src_surface != dst_surface);
// This is only called when CanCopy is true, no need to run checks here
const Aspect aspect = ToAspect(dst_surface->type); const Aspect aspect = ToAspect(dst_surface->type);
const Subresource dst_subresource = {
.aspect = aspect,
.region = dst_surface->GetScaledSubRect(subrect_params)
};
if (src_surface->type == SurfaceType::Fill) { if (src_surface->type == SurfaceType::Fill) {
// FillSurface needs a 4 bytes buffer // FillSurface needs a 4 bytes buffer
const u32 fill_offset = const u32 fill_offset =
@ -116,20 +84,21 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac
fill_buffer[i] = src_surface->fill_data[fill_buff_pos++ % src_surface->fill_size]; fill_buffer[i] = src_surface->fill_data[fill_buff_pos++ % src_surface->fill_size];
} }
const auto clear_rect = dst_surface->GetScaledSubRect(subrect_params);
const ClearValue clear_value = const ClearValue clear_value =
ToClearValue(aspect, dst_surface->pixel_format, fill_buffer.data()); MakeClearValue(aspect, dst_surface->pixel_format, fill_buffer.data());
runtime.ClearTexture(dst_surface->texture, {aspect, clear_rect}, clear_value); runtime.ClearTexture(dst_surface->texture, dst_subresource, clear_value);
return; return;
} }
if (src_surface->CanSubRect(subrect_params)) { if (src_surface->CanSubRect(subrect_params)) {
const auto src_rect = src_surface->GetScaledSubRect(subrect_params); const Subresource src_subresource = {
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params); .aspect = aspect,
.region = src_surface->GetScaledSubRect(subrect_params)
};
runtime.BlitTextures(src_surface->texture, {aspect, src_rect}, dst_surface->texture, runtime.BlitTextures(src_surface->texture, src_subresource, dst_surface->texture,
{aspect, dst_rect}); dst_subresource);
return; return;
} }
@ -266,8 +235,18 @@ bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
dst_surface->InvalidateAllWatcher(); dst_surface->InvalidateAllWatcher();
const Aspect aspect = ToAspect(src_surface->type); const Aspect aspect = ToAspect(src_surface->type);
return runtime.BlitTextures(src_surface->texture, {aspect, src_rect}, dst_surface->texture, const Subresource src_subresource = {
{aspect, dst_rect}); .aspect = aspect,
.region = src_rect
};
const Subresource dst_subresource = {
.aspect = aspect,
.region = dst_rect
};
return runtime.BlitTextures(src_surface->texture, src_subresource,
dst_surface->texture, dst_subresource);
} }
return false; return false;
@ -487,12 +466,19 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Pica::Texture::TextureInf
} }
if (!surface->is_custom && texture_filterer->IsNull()) { if (!surface->is_custom && texture_filterer->IsNull()) {
const auto src_rect = level_surface->GetScaledRect();
const auto dst_rect = surface_params.GetScaledRect();
const Aspect aspect = ToAspect(surface->type); const Aspect aspect = ToAspect(surface->type);
const Subresource src_subresource = {
.aspect = aspect,
.region = level_surface->GetScaledRect()
};
runtime.BlitTextures(level_surface->texture, {aspect, src_rect}, const Subresource dst_subresource = {
surface->texture, {aspect, dst_rect, level}); .aspect = aspect,
.region = surface_params.GetScaledRect()
};
runtime.BlitTextures(level_surface->texture, src_subresource,
surface->texture, dst_subresource);
} }
watcher->Validate(); watcher->Validate();
@ -569,11 +555,19 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube
ValidateSurface(surface, surface->addr, surface->size); ValidateSurface(surface, surface->addr, surface->size);
} }
const auto src_rect = surface->GetScaledRect();
const auto dst_rect = Common::Rectangle<u32>{0, scaled_size, scaled_size, 0};
const Aspect aspect = ToAspect(surface->type); const Aspect aspect = ToAspect(surface->type);
runtime.BlitTextures(surface->texture, {aspect, src_rect}, cube.texture, const Subresource src_subresource = {
{aspect, dst_rect, 0, static_cast<u32>(i)}, true); .aspect = aspect,
.region = surface->GetScaledRect()
};
const Subresource dst_subresource = {
.aspect = aspect,
.region = Common::Rectangle<u32>{0, scaled_size, scaled_size, 0}
};
runtime.BlitTextures(surface->texture, src_subresource,
cube.texture, dst_subresource);
face.watcher->Validate(); face.watcher->Validate();
} }
@ -862,7 +856,6 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
const SurfaceInterval& interval) { const SurfaceInterval& interval) {
const PixelFormat dst_format = surface->pixel_format; const PixelFormat dst_format = surface->pixel_format;
const SurfaceType type = GetFormatType(dst_format); const SurfaceType type = GetFormatType(dst_format);
const FormatTuple& tuple = GetFormatTuple(dst_format);
for (auto& reinterpreter : for (auto& reinterpreter :
format_reinterpreter->GetPossibleReinterpretations(surface->pixel_format)) { format_reinterpreter->GetPossibleReinterpretations(surface->pixel_format)) {
@ -886,7 +879,7 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
const u32 height = dest_rect.GetWidth() / resolution_scale_factor; const u32 height = dest_rect.GetWidth() / resolution_scale_factor;
const Common::Rectangle<u32> tmp_rect{0, width, height, 0}; const Common::Rectangle<u32> tmp_rect{0, width, height, 0};
OGLTexture tmp_tex = AllocateSurfaceTexture(tuple, height, width); OGLTexture tmp_tex = AllocateSurfaceTexture(dst_format, height, width);
reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, tmp_tex, reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, tmp_tex,
tmp_rect); tmp_rect);
@ -894,8 +887,18 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
type)) { type)) {
const Aspect aspect = ToAspect(type); const Aspect aspect = ToAspect(type);
runtime.BlitTextures(tmp_tex, {aspect, tmp_rect}, surface->texture, const Subresource src_subresource = {
{aspect, dest_rect}); .aspect = aspect,
.region = tmp_rect
};
const Subresource dst_subresource = {
.aspect = aspect,
.region = dest_rect
};
runtime.BlitTextures(tmp_tex, src_subresource,
surface->texture, dst_subresource);
} }
} else { } else {
reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, surface->texture, reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, surface->texture,
@ -1040,9 +1043,8 @@ Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) {
surface->invalid_regions.insert(surface->GetInterval()); surface->invalid_regions.insert(surface->GetInterval());
// Allocate surface texture // Allocate surface texture
const FormatTuple& tuple = GetFormatTuple(surface->pixel_format);
surface->texture = surface->texture =
AllocateSurfaceTexture(tuple, surface->GetScaledWidth(), surface->GetScaledHeight()); AllocateSurfaceTexture(params.pixel_format, surface->GetScaledWidth(), surface->GetScaledHeight());
return surface; return surface;
} }

View File

@ -5,7 +5,7 @@
#pragma once #pragma once
#include <unordered_map> #include <unordered_map>
#include "video_core/rasterizer_cache/cached_surface.h" #include "video_core/rasterizer_cache/cached_surface.h"
#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" #include "video_core/rasterizer_cache/utils.h"
#include "video_core/rasterizer_cache/surface_params.h" #include "video_core/rasterizer_cache/surface_params.h"
#include "video_core/texture/texture_decode.h" #include "video_core/texture/texture_decode.h"
@ -15,10 +15,27 @@ class RasterizerAccelerated;
namespace OpenGL { namespace OpenGL {
// Declare rasterizer interval types
using SurfaceSet = std::set<Surface>;
using SurfaceMap =
boost::icl::interval_map<PAddr, Surface, boost::icl::partial_absorber, std::less,
boost::icl::inplace_plus, boost::icl::inter_section, SurfaceInterval>;
using SurfaceCache =
boost::icl::interval_map<PAddr, SurfaceSet, boost::icl::partial_absorber, std::less,
boost::icl::inplace_plus, boost::icl::inter_section, SurfaceInterval>;
static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(),
"Incorrect interval types");
using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
using PageMap = boost::icl::interval_map<u32, int>;
enum class ScaleMatch { enum class ScaleMatch {
Exact, // only accept same res scale Exact, // Only accept same res scale
Upscale, // only allow higher scale than params Upscale, // Only allow higher scale than params
Ignore // accept every scaled res Ignore // Accept every scaled res
}; };
class TextureDownloaderES; class TextureDownloaderES;
@ -123,7 +140,7 @@ private:
std::recursive_mutex mutex; std::recursive_mutex mutex;
public: public:
OGLTexture AllocateSurfaceTexture(const FormatTuple& format_tuple, u32 width, u32 height); OGLTexture AllocateSurfaceTexture(PixelFormat format, u32 width, u32 height);
std::unique_ptr<TextureFilterer> texture_filterer; std::unique_ptr<TextureFilterer> texture_filterer;
std::unique_ptr<FormatReinterpreterOpenGL> format_reinterpreter; std::unique_ptr<FormatReinterpreterOpenGL> format_reinterpreter;

View File

@ -1,38 +0,0 @@
// Copyright 2022 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <set>
#include <tuple>
#include <boost/icl/interval_map.hpp>
#include <boost/icl/interval_set.hpp>
#include "common/common_types.h"
#include "common/math_util.h"
namespace OpenGL {
class CachedSurface;
using Surface = std::shared_ptr<CachedSurface>;
// Declare rasterizer interval types
using SurfaceInterval = boost::icl::right_open_interval<PAddr>;
using SurfaceSet = std::set<Surface>;
using SurfaceRegions = boost::icl::interval_set<PAddr, std::less, SurfaceInterval>;
using SurfaceMap =
boost::icl::interval_map<PAddr, Surface, boost::icl::partial_absorber, std::less,
boost::icl::inplace_plus, boost::icl::inter_section, SurfaceInterval>;
using SurfaceCache =
boost::icl::interval_map<PAddr, SurfaceSet, boost::icl::partial_absorber, std::less,
boost::icl::inplace_plus, boost::icl::inter_section, SurfaceInterval>;
static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(),
"Incorrect interval types");
using SurfaceRect_Tuple = std::tuple<Surface, Common::Rectangle<u32>>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, Common::Rectangle<u32>>;
using PageMap = boost::icl::interval_map<u32, int>;
} // namespace OpenGL

View File

@ -6,11 +6,18 @@
#include <array> #include <array>
#include <climits> #include <climits>
#include <boost/icl/interval_map.hpp>
#include <boost/icl/interval_set.hpp>
#include "common/math_util.h"
#include "video_core/rasterizer_cache/pixel_format.h" #include "video_core/rasterizer_cache/pixel_format.h"
#include "video_core/rasterizer_cache/rasterizer_cache_types.h"
namespace OpenGL { namespace OpenGL {
class CachedSurface;
using Surface = std::shared_ptr<CachedSurface>;
using SurfaceInterval = boost::icl::right_open_interval<PAddr>;
class SurfaceParams { class SurfaceParams {
public: public:
// Surface match traits // Surface match traits

View File

@ -3,7 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" #include "video_core/rasterizer_cache/utils.h"
#include "video_core/rasterizer_cache/texture_runtime.h" #include "video_core/rasterizer_cache/texture_runtime.h"
#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_state.h"

View File

@ -3,34 +3,11 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#pragma once #pragma once
#include "common/math_util.h" #include "video_core/rasterizer_cache/types.h"
#include "common/vector_math.h"
#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h"
namespace OpenGL { 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;
struct {
float depth;
u8 stencil;
};
};
struct Subresource {
Subresource(Aspect aspect, Common::Rectangle<u32> region, u32 level = 0, u32 layer = 0)
: aspect(aspect), region(region), level(level), layer(layer) {}
Aspect aspect;
Common::Rectangle<u32> region;
u32 level = 0;
u32 layer = 0;
};
struct FormatTuple; struct FormatTuple;
/** /**

View File

@ -0,0 +1,36 @@
// Copyright 2022 Citra Emulator Project
// Licensed under GPLv2 or any later version
// 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"
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;
struct {
float depth;
u8 stencil;
};
};
struct Subresource {
auto operator<=>(const Subresource&) const = default;
Aspect aspect;
Common::Rectangle<u32> region;
u32 level = 0;
u32 layer = 0;
};
} // namespace OpenGL

View File

@ -4,7 +4,8 @@
#pragma once #pragma once
#include <glad/glad.h> #include <glad/glad.h>
#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" #include "video_core/texture/texture_decode.h"
#include "video_core/rasterizer_cache/utils.h"
#include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/gl_vars.h"
namespace OpenGL { namespace OpenGL {
@ -53,4 +54,39 @@ const FormatTuple& GetFormatTuple(PixelFormat pixel_format) {
return tex_tuple; return tex_tuple;
} }
ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data) {
ClearValue result{};
switch (aspect) {
case Aspect::Color: {
Pica::Texture::TextureInfo tex_info{};
tex_info.format = static_cast<Pica::TexturingRegs::TextureFormat>(format);
Common::Vec4<u8> color = Pica::Texture::LookupTexture(fill_data, 0, 0, tex_info);
result.color = color / 255.f;
break;
}
case Aspect::Depth: {
u32 depth_uint = 0;
if (format == PixelFormat::D16) {
std::memcpy(&depth_uint, fill_data, 2);
result.depth = depth_uint / 65535.0f; // 2^16 - 1
} else if (format == PixelFormat::D24) {
std::memcpy(&depth_uint, fill_data, 3);
result.depth = depth_uint / 16777215.0f; // 2^24 - 1
}
break;
}
case Aspect::DepthStencil: {
u32 clear_value_uint;
std::memcpy(&clear_value_uint, fill_data, sizeof(u32));
result.depth = (clear_value_uint & 0xFFFFFF) / 16777215.0f; // 2^24 - 1
result.stencil = (clear_value_uint >> 24);
break;
}
}
return result;
}
} // namespace OpenGL } // namespace OpenGL

View File

@ -6,6 +6,7 @@
#include <functional> #include <functional>
#include "common/hash.h" #include "common/hash.h"
#include "video_core/rasterizer_cache/pixel_format.h" #include "video_core/rasterizer_cache/pixel_format.h"
#include "video_core/rasterizer_cache/types.h"
namespace OpenGL { namespace OpenGL {
@ -18,13 +19,11 @@ struct FormatTuple {
const FormatTuple& GetFormatTuple(PixelFormat pixel_format); const FormatTuple& GetFormatTuple(PixelFormat pixel_format);
struct HostTextureTag { struct HostTextureTag {
FormatTuple format_tuple{}; PixelFormat format{};
u32 width = 0; u32 width = 0;
u32 height = 0; u32 height = 0;
bool operator==(const HostTextureTag& rhs) const noexcept { auto operator<=>(const HostTextureTag&) const noexcept = default;
return std::memcmp(this, &rhs, sizeof(HostTextureTag)) == 0;
};
const u64 Hash() const { const u64 Hash() const {
return Common::ComputeHash64(this, sizeof(HostTextureTag)); return Common::ComputeHash64(this, sizeof(HostTextureTag));
@ -41,19 +40,15 @@ struct TextureCubeConfig {
u32 width; u32 width;
Pica::TexturingRegs::TextureFormat format; Pica::TexturingRegs::TextureFormat format;
bool operator==(const TextureCubeConfig& rhs) const { auto operator<=>(const TextureCubeConfig&) const noexcept = default;
return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) == 0;
}
bool operator!=(const TextureCubeConfig& rhs) const {
return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) != 0;
}
const u64 Hash() const { const u64 Hash() const {
return Common::ComputeHash64(this, sizeof(TextureCubeConfig)); return Common::ComputeHash64(this, sizeof(TextureCubeConfig));
} }
}; };
[[nodiscard]] ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data);
} // namespace OpenGL } // namespace OpenGL
namespace std { namespace std {

View File

@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include <fmt/chrono.h> #include <fmt/chrono.h>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "video_core/rasterizer_cache/rasterizer_cache_utils.h" #include "video_core/rasterizer_cache/utils.h"
#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/texture_downloader_es.h" #include "video_core/renderer_opengl/texture_downloader_es.h"