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:
@ -32,9 +32,9 @@ add_library(video_core STATIC
|
||||
rasterizer_cache/pixel_format.h
|
||||
rasterizer_cache/rasterizer_cache.cpp
|
||||
rasterizer_cache/rasterizer_cache.h
|
||||
rasterizer_cache/rasterizer_cache_types.h
|
||||
rasterizer_cache/rasterizer_cache_utils.cpp
|
||||
rasterizer_cache/rasterizer_cache_utils.h
|
||||
rasterizer_cache/types.h
|
||||
rasterizer_cache/utils.cpp
|
||||
rasterizer_cache/utils.h
|
||||
rasterizer_cache/surface_params.cpp
|
||||
rasterizer_cache/surface_params.h
|
||||
rasterizer_cache/texture_runtime.cpp
|
||||
|
@ -35,9 +35,9 @@ static Aspect ToAspect(SurfaceType type) {
|
||||
|
||||
CachedSurface::~CachedSurface() {
|
||||
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}
|
||||
: HostTextureTag{GetFormatTuple(pixel_format), GetScaledWidth(),
|
||||
: HostTextureTag{pixel_format, GetScaledWidth(),
|
||||
GetScaledHeight()};
|
||||
|
||||
owner.host_texture_recycler.emplace(tag, std::move(texture));
|
||||
@ -297,7 +297,6 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
|
||||
GLint y0 = static_cast<GLint>(rect.bottom);
|
||||
std::size_t buffer_offset = (y0 * stride + x0) * GetBytesPerPixel(pixel_format);
|
||||
|
||||
const FormatTuple& tuple = GetFormatTuple(pixel_format);
|
||||
GLuint target_tex = texture.handle;
|
||||
|
||||
// If not 1x scale, create 1x texture that we will blit from to replace texture subrect in
|
||||
@ -308,11 +307,10 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
|
||||
y0 = 0;
|
||||
|
||||
if (is_custom) {
|
||||
const auto& tuple = GetFormatTuple(PixelFormat::RGBA8);
|
||||
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 {
|
||||
unscaled_tex = owner.AllocateSurfaceTexture(tuple, rect.GetWidth(), rect.GetHeight());
|
||||
unscaled_tex = owner.AllocateSurfaceTexture(pixel_format, rect.GetWidth(), rect.GetHeight());
|
||||
}
|
||||
|
||||
target_tex = unscaled_tex.handle;
|
||||
@ -324,11 +322,13 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
|
||||
cur_state.texture_units[0].texture_2d = target_tex;
|
||||
cur_state.Apply();
|
||||
|
||||
const FormatTuple& tuple = GetFormatTuple(pixel_format);
|
||||
|
||||
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
|
||||
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
||||
if (is_custom) {
|
||||
if (res_scale == 1) {
|
||||
texture = owner.AllocateSurfaceTexture(GetFormatTuple(PixelFormat::RGBA8),
|
||||
texture = owner.AllocateSurfaceTexture(PixelFormat::RGBA8,
|
||||
custom_tex_info.width, custom_tex_info.height);
|
||||
cur_state.texture_units[0].texture_2d = texture.handle;
|
||||
cur_state.Apply();
|
||||
@ -344,6 +344,7 @@ void CachedSurface::UploadGLTexture(Common::Rectangle<u32> rect) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(stride));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
|
||||
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
|
||||
&gl_buffer[buffer_offset]);
|
||||
@ -395,14 +396,14 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
|
||||
OpenGLState prev_state = state;
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
const FormatTuple& tuple = GetFormatTuple(pixel_format);
|
||||
|
||||
// Ensure no bad interactions with GL_PACK_ALIGNMENT
|
||||
ASSERT(stride * GetBytesPerPixel(pixel_format) % 4 == 0);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride));
|
||||
const std::size_t buffer_offset =
|
||||
(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
|
||||
const Aspect aspect = ToAspect(type);
|
||||
if (res_scale != 1) {
|
||||
@ -413,7 +414,7 @@ void CachedSurface::DownloadGLTexture(const Common::Rectangle<u32>& rect) {
|
||||
scaled_rect.bottom *= res_scale;
|
||||
|
||||
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
|
||||
runtime.BlitTextures(texture, {aspect, scaled_rect}, unscaled_tex,
|
||||
{aspect, unscaled_tex_rect});
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
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
|
||||
* surface collection objects, including texture cube and mipmap.
|
||||
|
@ -12,7 +12,7 @@ namespace OpenGL {
|
||||
|
||||
constexpr u32 PIXEL_FORMAT_COUNT = 18;
|
||||
|
||||
enum class PixelFormat : u8 {
|
||||
enum class PixelFormat : u32 {
|
||||
// First 5 formats are shared between textures and color buffers
|
||||
RGBA8 = 0,
|
||||
RGB8 = 1,
|
||||
|
@ -35,50 +35,15 @@ static Aspect ToAspect(SurfaceType type) {
|
||||
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>
|
||||
static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
|
||||
return boost::make_iterator_range(map.equal_range(interval));
|
||||
}
|
||||
|
||||
// Allocate an uninitialized texture of appropriate size and format for the surface
|
||||
OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(const FormatTuple& tuple, u32 width,
|
||||
u32 height) {
|
||||
auto recycled_tex = host_texture_recycler.find({tuple, width, height});
|
||||
OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(PixelFormat format, u32 width, u32 height) {
|
||||
const FormatTuple& tuple = GetFormatTuple(format);
|
||||
auto recycled_tex = host_texture_recycler.find({format, width, height});
|
||||
if (recycled_tex != host_texture_recycler.end()) {
|
||||
OGLTexture texture = std::move(recycled_tex->second);
|
||||
host_texture_recycler.erase(recycled_tex);
|
||||
@ -101,11 +66,14 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac
|
||||
MICROPROFILE_SCOPE(RasterizerCache_CopySurface);
|
||||
|
||||
SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval);
|
||||
ASSERT(subrect_params.GetInterval() == copy_interval);
|
||||
ASSERT(src_surface != dst_surface);
|
||||
ASSERT(subrect_params.GetInterval() == copy_interval && 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 Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.region = dst_surface->GetScaledSubRect(subrect_params)
|
||||
};
|
||||
|
||||
if (src_surface->type == SurfaceType::Fill) {
|
||||
// FillSurface needs a 4 bytes buffer
|
||||
const u32 fill_offset =
|
||||
@ -117,20 +85,21 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac
|
||||
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 =
|
||||
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;
|
||||
}
|
||||
|
||||
if (src_surface->CanSubRect(subrect_params)) {
|
||||
const auto src_rect = src_surface->GetScaledSubRect(subrect_params);
|
||||
const auto dst_rect = dst_surface->GetScaledSubRect(subrect_params);
|
||||
const Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.region = src_surface->GetScaledSubRect(subrect_params)
|
||||
};
|
||||
|
||||
runtime.BlitTextures(src_surface->texture, {aspect, src_rect}, dst_surface->texture,
|
||||
{aspect, dst_rect});
|
||||
runtime.BlitTextures(src_surface->texture, src_subresource, dst_surface->texture,
|
||||
dst_subresource);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -268,8 +237,18 @@ bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
|
||||
dst_surface->InvalidateAllWatcher();
|
||||
|
||||
const Aspect aspect = ToAspect(src_surface->type);
|
||||
return runtime.BlitTextures(src_surface->texture, {aspect, src_rect}, dst_surface->texture,
|
||||
{aspect, dst_rect});
|
||||
const Subresource src_subresource = {
|
||||
.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;
|
||||
@ -489,12 +468,19 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Pica::Texture::TextureInf
|
||||
}
|
||||
|
||||
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 Subresource src_subresource = {
|
||||
.aspect = aspect,
|
||||
.region = level_surface->GetScaledRect()
|
||||
};
|
||||
|
||||
runtime.BlitTextures(level_surface->texture, {aspect, src_rect},
|
||||
surface->texture, {aspect, dst_rect, level});
|
||||
const Subresource dst_subresource = {
|
||||
.aspect = aspect,
|
||||
.region = surface_params.GetScaledRect()
|
||||
};
|
||||
|
||||
runtime.BlitTextures(level_surface->texture, src_subresource,
|
||||
surface->texture, dst_subresource);
|
||||
}
|
||||
|
||||
watcher->Validate();
|
||||
@ -571,11 +557,19 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube
|
||||
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);
|
||||
runtime.BlitTextures(surface->texture, {aspect, src_rect}, cube.texture,
|
||||
{aspect, dst_rect, 0, static_cast<u32>(i)}, true);
|
||||
const Subresource src_subresource = {
|
||||
.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();
|
||||
}
|
||||
@ -864,7 +858,6 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
|
||||
const SurfaceInterval& interval) {
|
||||
const PixelFormat dst_format = surface->pixel_format;
|
||||
const SurfaceType type = GetFormatType(dst_format);
|
||||
const FormatTuple& tuple = GetFormatTuple(dst_format);
|
||||
|
||||
for (auto& reinterpreter :
|
||||
format_reinterpreter->GetPossibleReinterpretations(surface->pixel_format)) {
|
||||
@ -888,7 +881,7 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
|
||||
const u32 height = dest_rect.GetWidth() / resolution_scale_factor;
|
||||
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,
|
||||
tmp_rect);
|
||||
|
||||
@ -896,8 +889,18 @@ bool RasterizerCacheOpenGL::ValidateByReinterpretation(const Surface& surface,
|
||||
type)) {
|
||||
|
||||
const Aspect aspect = ToAspect(type);
|
||||
runtime.BlitTextures(tmp_tex, {aspect, tmp_rect}, surface->texture,
|
||||
{aspect, dest_rect});
|
||||
const Subresource src_subresource = {
|
||||
.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 {
|
||||
reinterpreter->Reinterpret(reinterpret_surface->texture, src_rect, surface->texture,
|
||||
@ -1042,9 +1045,8 @@ Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) {
|
||||
surface->invalid_regions.insert(surface->GetInterval());
|
||||
|
||||
// Allocate surface texture
|
||||
const FormatTuple& tuple = GetFormatTuple(surface->pixel_format);
|
||||
surface->texture =
|
||||
AllocateSurfaceTexture(tuple, surface->GetScaledWidth(), surface->GetScaledHeight());
|
||||
AllocateSurfaceTexture(params.pixel_format, surface->GetScaledWidth(), surface->GetScaledHeight());
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#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/texture/texture_decode.h"
|
||||
|
||||
@ -15,10 +15,27 @@ class RasterizerAccelerated;
|
||||
|
||||
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 {
|
||||
Exact, // only accept same res scale
|
||||
Upscale, // only allow higher scale than params
|
||||
Ignore // accept every scaled res
|
||||
Exact, // Only accept same res scale
|
||||
Upscale, // Only allow higher scale than params
|
||||
Ignore // Accept every scaled res
|
||||
};
|
||||
|
||||
class TextureDownloaderES;
|
||||
@ -123,7 +140,7 @@ private:
|
||||
std::recursive_mutex mutex;
|
||||
|
||||
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<FormatReinterpreterOpenGL> format_reinterpreter;
|
||||
|
@ -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
|
@ -6,11 +6,18 @@
|
||||
|
||||
#include <array>
|
||||
#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/rasterizer_cache_types.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
class CachedSurface;
|
||||
using Surface = std::shared_ptr<CachedSurface>;
|
||||
|
||||
using SurfaceInterval = boost::icl::right_open_interval<PAddr>;
|
||||
|
||||
class SurfaceParams {
|
||||
public:
|
||||
// Surface match traits
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#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/renderer_opengl/gl_state.h"
|
||||
|
||||
|
@ -3,34 +3,11 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
#include "common/math_util.h"
|
||||
#include "common/vector_math.h"
|
||||
#include "video_core/rasterizer_cache/types.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.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 {
|
||||
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;
|
||||
|
||||
/**
|
||||
|
36
src/video_core/rasterizer_cache/types.h
Normal file
36
src/video_core/rasterizer_cache/types.h
Normal 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
|
@ -4,7 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
#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"
|
||||
|
||||
namespace OpenGL {
|
||||
@ -53,4 +54,39 @@ const FormatTuple& GetFormatTuple(PixelFormat pixel_format) {
|
||||
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
|
@ -6,6 +6,7 @@
|
||||
#include <functional>
|
||||
#include "common/hash.h"
|
||||
#include "video_core/rasterizer_cache/pixel_format.h"
|
||||
#include "video_core/rasterizer_cache/types.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
@ -18,13 +19,11 @@ struct FormatTuple {
|
||||
const FormatTuple& GetFormatTuple(PixelFormat pixel_format);
|
||||
|
||||
struct HostTextureTag {
|
||||
FormatTuple format_tuple{};
|
||||
PixelFormat format{};
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
|
||||
bool operator==(const HostTextureTag& rhs) const noexcept {
|
||||
return std::memcmp(this, &rhs, sizeof(HostTextureTag)) == 0;
|
||||
};
|
||||
auto operator<=>(const HostTextureTag&) const noexcept = default;
|
||||
|
||||
const u64 Hash() const {
|
||||
return Common::ComputeHash64(this, sizeof(HostTextureTag));
|
||||
@ -41,19 +40,15 @@ struct TextureCubeConfig {
|
||||
u32 width;
|
||||
Pica::TexturingRegs::TextureFormat format;
|
||||
|
||||
bool operator==(const TextureCubeConfig& rhs) const {
|
||||
return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const TextureCubeConfig& rhs) const {
|
||||
return std::memcmp(this, &rhs, sizeof(TextureCubeConfig)) != 0;
|
||||
}
|
||||
auto operator<=>(const TextureCubeConfig&) const noexcept = default;
|
||||
|
||||
const u64 Hash() const {
|
||||
return Common::ComputeHash64(this, sizeof(TextureCubeConfig));
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] ClearValue MakeClearValue(Aspect aspect, PixelFormat format, const u8* fill_data);
|
||||
|
||||
} // namespace OpenGL
|
||||
|
||||
namespace std {
|
@ -6,7 +6,7 @@
|
||||
#include <vector>
|
||||
#include <fmt/chrono.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/texture_downloader_es.h"
|
||||
|
||||
|
Reference in New Issue
Block a user