rasterizer_cache: Remove shared_ptr usage
* Switches to yuzu's slot vector for improved memory locality.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "core/frontend/image_interface.h"
|
||||
#include "video_core/custom_textures/custom_tex_manager.h"
|
||||
#include "video_core/rasterizer_cache/surface_params.h"
|
||||
#include "video_core/rasterizer_cache/utils.h"
|
||||
|
||||
namespace VideoCore {
|
||||
|
||||
|
@@ -10,9 +10,9 @@ namespace VideoCore {
|
||||
|
||||
FramebufferBase::FramebufferBase() = default;
|
||||
|
||||
FramebufferBase::FramebufferBase(const Pica::Regs& regs, const SurfaceBase* const color,
|
||||
u32 color_level, const SurfaceBase* const depth_stencil,
|
||||
u32 depth_level, Common::Rectangle<u32> surfaces_rect) {
|
||||
FramebufferBase::FramebufferBase(const Pica::Regs& regs, const SurfaceBase* color, u32 color_level,
|
||||
const SurfaceBase* depth_stencil, u32 depth_level,
|
||||
Common::Rectangle<u32> surfaces_rect) {
|
||||
res_scale = color ? color->res_scale : (depth_stencil ? depth_stencil->res_scale : 1u);
|
||||
|
||||
// Determine the draw rectangle (render area + scissor)
|
||||
|
@@ -29,8 +29,8 @@ struct ViewportInfo {
|
||||
class FramebufferBase {
|
||||
public:
|
||||
FramebufferBase();
|
||||
FramebufferBase(const Pica::Regs& regs, const SurfaceBase* const color, u32 color_level,
|
||||
const SurfaceBase* const depth_stencil, u32 depth_level,
|
||||
FramebufferBase(const Pica::Regs& regs, const SurfaceBase* color, u32 color_level,
|
||||
const SurfaceBase* depth_stencil, u32 depth_level,
|
||||
Common::Rectangle<u32> surfaces_rect);
|
||||
|
||||
SurfaceParams ColorParams() const noexcept {
|
||||
@@ -66,6 +66,7 @@ protected:
|
||||
switch (type) {
|
||||
case VideoCore::SurfaceType::Color:
|
||||
return 0;
|
||||
case VideoCore::SurfaceType::Depth:
|
||||
case VideoCore::SurfaceType::DepthStencil:
|
||||
return 1;
|
||||
default:
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -51,32 +51,32 @@ class RasterizerCache {
|
||||
/// Address shift for caching surfaces into a hash table
|
||||
static constexpr u64 CITRA_PAGEBITS = 18;
|
||||
|
||||
using TextureRuntime = typename T::TextureRuntime;
|
||||
using Runtime = typename T::Runtime;
|
||||
using Sampler = typename T::Sampler;
|
||||
using SurfaceRef = std::shared_ptr<typename T::Surface>;
|
||||
using Surface = typename T::Surface;
|
||||
using Framebuffer = typename T::Framebuffer;
|
||||
|
||||
using SurfaceMap = boost::icl::interval_map<PAddr, SurfaceRef, boost::icl::partial_absorber,
|
||||
using SurfaceMap = boost::icl::interval_map<PAddr, SurfaceId, boost::icl::partial_absorber,
|
||||
std::less, boost::icl::inplace_plus,
|
||||
boost::icl::inter_section, SurfaceInterval>;
|
||||
|
||||
using SurfaceRect_Tuple = std::tuple<SurfaceRef, Common::Rectangle<u32>>;
|
||||
using SurfaceRect_Tuple = std::pair<SurfaceId, Common::Rectangle<u32>>;
|
||||
using PageMap = boost::icl::interval_map<u32, int>;
|
||||
|
||||
struct RenderTargets {
|
||||
SurfaceRef color_surface;
|
||||
SurfaceRef depth_surface;
|
||||
SurfaceId color_id;
|
||||
SurfaceId depth_id;
|
||||
};
|
||||
|
||||
struct TextureCube {
|
||||
SurfaceRef surface{};
|
||||
std::array<SurfaceRef, 6> faces{};
|
||||
std::array<u64, 6> ticks{};
|
||||
SurfaceId surface_id;
|
||||
std::array<SurfaceId, 6> face_ids;
|
||||
std::array<u64, 6> ticks;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit RasterizerCache(Memory::MemorySystem& memory, CustomTexManager& custom_tex_manager,
|
||||
TextureRuntime& runtime, Pica::Regs& regs, RendererBase& renderer);
|
||||
Runtime& runtime, Pica::Regs& regs, RendererBase& renderer);
|
||||
~RasterizerCache();
|
||||
|
||||
/// Notify the cache that a new frame has been queued
|
||||
@@ -91,17 +91,19 @@ public:
|
||||
/// Perform hardware accelerated memory fill according to the provided configuration
|
||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config);
|
||||
|
||||
/// Returns a reference to the surface object assigned to surface_id
|
||||
Surface& GetSurface(SurfaceId surface_id);
|
||||
|
||||
/// Returns a reference to the sampler object matching the provided configuration
|
||||
Sampler& GetSampler(const Pica::TexturingRegs::TextureConfig& config);
|
||||
Sampler& GetSampler(SamplerId sampler_id);
|
||||
|
||||
/// Copy one surface's region to another
|
||||
void CopySurface(const SurfaceRef& src_surface, const SurfaceRef& dst_surface,
|
||||
SurfaceInterval copy_interval);
|
||||
void CopySurface(Surface& src_surface, Surface& dst_surface, SurfaceInterval copy_interval);
|
||||
|
||||
/// Load a texture from 3DS memory to OpenGL and cache it (if not already cached)
|
||||
SurfaceRef GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||
bool load_if_create);
|
||||
SurfaceId GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||
bool load_if_create);
|
||||
|
||||
/// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from
|
||||
/// 3DS memory to OpenGL and caches it (if not already cached)
|
||||
@@ -109,11 +111,11 @@ public:
|
||||
bool load_if_create);
|
||||
|
||||
/// Get a surface based on the texture configuration
|
||||
SurfaceRef GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config);
|
||||
SurfaceRef GetTextureSurface(const Pica::Texture::TextureInfo& info, u32 max_level = 0);
|
||||
Surface& GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config);
|
||||
SurfaceId GetTextureSurface(const Pica::Texture::TextureInfo& info, u32 max_level = 0);
|
||||
|
||||
/// Get a texture cube based on the texture configuration
|
||||
SurfaceRef GetTextureCube(const TextureCubeConfig& config);
|
||||
Surface& GetTextureCube(const TextureCubeConfig& config);
|
||||
|
||||
/// Get the color and depth surfaces based on the framebuffer configuration
|
||||
Framebuffer GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb);
|
||||
@@ -125,10 +127,10 @@ public:
|
||||
SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params);
|
||||
|
||||
/// Write any cached resources overlapping the region back to memory (if dirty)
|
||||
void FlushRegion(PAddr addr, u32 size, SurfaceRef flush_surface = nullptr);
|
||||
void FlushRegion(PAddr addr, u32 size, SurfaceId flush_surface = {});
|
||||
|
||||
/// Mark region as being invalidated by region_owner (nullptr if 3DS memory)
|
||||
void InvalidateRegion(PAddr addr, u32 size, const SurfaceRef& region_owner);
|
||||
void InvalidateRegion(PAddr addr, u32 size, SurfaceId region_owner = {});
|
||||
|
||||
/// Flush all cached resources tracked by this cache manager
|
||||
void FlushAll();
|
||||
@@ -159,33 +161,29 @@ private:
|
||||
|
||||
/// Get the best surface match (and its match type) for the given flags
|
||||
template <MatchFlags find_flags>
|
||||
SurfaceRef FindMatch(const SurfaceParams& params, ScaleMatch match_scale_type,
|
||||
std::optional<SurfaceInterval> validate_interval = std::nullopt);
|
||||
SurfaceId FindMatch(const SurfaceParams& params, ScaleMatch match_scale_type,
|
||||
std::optional<SurfaceInterval> validate_interval = std::nullopt);
|
||||
|
||||
/// Transfers ownership of a memory region from src_surface to dest_surface
|
||||
void DuplicateSurface(const SurfaceRef& src_surface, const SurfaceRef& dest_surface);
|
||||
void DuplicateSurface(SurfaceId src_id, SurfaceId dst_id);
|
||||
|
||||
/// Update surface's texture for given region when necessary
|
||||
void ValidateSurface(const SurfaceRef& surface, PAddr addr, u32 size);
|
||||
void ValidateSurface(SurfaceId surface, PAddr addr, u32 size);
|
||||
|
||||
/// Copies pixel data in interval from the guest VRAM to the host GPU surface
|
||||
void UploadSurface(const SurfaceRef& surface, SurfaceInterval interval);
|
||||
void UploadSurface(Surface& surface, SurfaceInterval interval);
|
||||
|
||||
/// Uploads a custom texture identified with hash to the target surface
|
||||
bool UploadCustomSurface(const SurfaceRef& surface, const SurfaceParams& load_info, u64 hash);
|
||||
|
||||
/// Returns the hash used to lookup the custom surface.
|
||||
u64 ComputeCustomHash(const SurfaceParams& load_info, std::span<u8> decoded,
|
||||
std::span<u8> upload_data);
|
||||
bool UploadCustomSurface(SurfaceId surface_id, SurfaceInterval interval);
|
||||
|
||||
/// Copies pixel data in interval from the host GPU surface to the guest VRAM
|
||||
void DownloadSurface(const SurfaceRef& surface, SurfaceInterval interval);
|
||||
void DownloadSurface(Surface& surface, SurfaceInterval interval);
|
||||
|
||||
/// Downloads a fill surface to guest VRAM
|
||||
void DownloadFillSurface(const SurfaceRef& surface, SurfaceInterval interval);
|
||||
void DownloadFillSurface(Surface& surface, SurfaceInterval interval);
|
||||
|
||||
/// Returns false if there is a surface in the cache at the interval with the same bit-width,
|
||||
bool NoUnimplementedReinterpretations(const SurfaceRef& surface, SurfaceParams params,
|
||||
bool NoUnimplementedReinterpretations(const Surface& surface, SurfaceParams params,
|
||||
const SurfaceInterval& interval);
|
||||
|
||||
/// Return true if a surface with an invalid pixel format exists at the interval
|
||||
@@ -193,17 +191,17 @@ private:
|
||||
const SurfaceInterval& interval);
|
||||
|
||||
/// Attempt to find a reinterpretable surface in the cache and use it to copy for validation
|
||||
bool ValidateByReinterpretation(const SurfaceRef& surface, SurfaceParams params,
|
||||
bool ValidateByReinterpretation(Surface& surface, SurfaceParams params,
|
||||
const SurfaceInterval& interval);
|
||||
|
||||
/// Create a new surface
|
||||
SurfaceRef CreateSurface(const SurfaceParams& params);
|
||||
SurfaceId CreateSurface(const SurfaceParams& params);
|
||||
|
||||
/// Register surface into the cache
|
||||
void RegisterSurface(const SurfaceRef& surface);
|
||||
void RegisterSurface(SurfaceId surface);
|
||||
|
||||
/// Remove surface from the cache
|
||||
void UnregisterSurface(const SurfaceRef& surface);
|
||||
void UnregisterSurface(SurfaceId surface);
|
||||
|
||||
/// Unregisters all surfaces from the cache
|
||||
void UnregisterAll();
|
||||
@@ -214,16 +212,17 @@ private:
|
||||
private:
|
||||
Memory::MemorySystem& memory;
|
||||
CustomTexManager& custom_tex_manager;
|
||||
TextureRuntime& runtime;
|
||||
Runtime& runtime;
|
||||
Pica::Regs& regs;
|
||||
RendererBase& renderer;
|
||||
std::unordered_map<TextureCubeConfig, TextureCube> texture_cube_cache;
|
||||
tsl::robin_pg_map<u64, std::vector<SurfaceRef>, Common::IdentityHash<u64>> page_table;
|
||||
tsl::robin_pg_map<u64, std::vector<SurfaceId>, Common::IdentityHash<u64>> page_table;
|
||||
std::unordered_map<SamplerParams, SamplerId> samplers;
|
||||
SlotVector<Surface> slot_surfaces;
|
||||
SlotVector<Sampler> slot_samplers;
|
||||
SurfaceMap dirty_regions;
|
||||
PageMap cached_pages;
|
||||
std::vector<SurfaceRef> remove_surfaces;
|
||||
std::vector<SurfaceId> remove_surfaces;
|
||||
u32 resolution_scale_factor;
|
||||
RenderTargets render_targets;
|
||||
bool use_filter;
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <compare>
|
||||
#include "common/hash.h"
|
||||
#include "video_core/regs_texturing.h"
|
||||
|
||||
|
@@ -29,60 +29,6 @@ struct SlotId {
|
||||
template <class T>
|
||||
class SlotVector {
|
||||
public:
|
||||
class Iterator {
|
||||
friend SlotVector<T>;
|
||||
|
||||
public:
|
||||
constexpr Iterator() = default;
|
||||
|
||||
Iterator& operator++() noexcept {
|
||||
const u64* const bitset = slot_vector->stored_bitset.data();
|
||||
const u32 size = static_cast<u32>(slot_vector->stored_bitset.size()) * 64;
|
||||
if (id.index < size) {
|
||||
do {
|
||||
++id.index;
|
||||
} while (id.index < size && !IsValid(bitset));
|
||||
if (id.index == size) {
|
||||
id.index = SlotId::INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) noexcept {
|
||||
const Iterator copy{*this};
|
||||
++*this;
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const Iterator& other) const noexcept {
|
||||
return id.index == other.id.index;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator& other) const noexcept {
|
||||
return id.index != other.id.index;
|
||||
}
|
||||
|
||||
std::pair<SlotId, T*> operator*() const noexcept {
|
||||
return {id, std::addressof((*slot_vector)[id])};
|
||||
}
|
||||
|
||||
T* operator->() const noexcept {
|
||||
return std::addressof((*slot_vector)[id]);
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator(SlotVector<T>* slot_vector_, SlotId id_) noexcept
|
||||
: slot_vector{slot_vector_}, id{id_} {}
|
||||
|
||||
bool IsValid(const u64* bitset) const noexcept {
|
||||
return ((bitset[id.index / 64] >> (id.index % 64)) & 1) != 0;
|
||||
}
|
||||
|
||||
SlotVector<T>* slot_vector;
|
||||
SlotId id;
|
||||
};
|
||||
|
||||
~SlotVector() noexcept {
|
||||
size_t index = 0;
|
||||
for (u64 bits : stored_bitset) {
|
||||
@@ -121,21 +67,6 @@ public:
|
||||
ResetStorageBit(id.index);
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator begin() noexcept {
|
||||
const auto it = std::find_if(stored_bitset.begin(), stored_bitset.end(),
|
||||
[](u64 value) { return value != 0; });
|
||||
if (it == stored_bitset.end()) {
|
||||
return end();
|
||||
}
|
||||
const u32 word_index = static_cast<u32>(std::distance(it, stored_bitset.begin()));
|
||||
const SlotId first_id{word_index * 64 + static_cast<u32>(std::countr_zero(*it))};
|
||||
return Iterator(this, first_id);
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator end() noexcept {
|
||||
return Iterator(this, SlotId{SlotId::INVALID_INDEX});
|
||||
}
|
||||
|
||||
private:
|
||||
struct NonTrivialDummy {
|
||||
NonTrivialDummy() noexcept {}
|
||||
|
@@ -13,6 +13,14 @@ using SurfaceRegions = boost::icl::interval_set<PAddr, std::less, SurfaceInterva
|
||||
|
||||
struct Material;
|
||||
|
||||
enum class SurfaceFlagBits : u32 {
|
||||
Registered = 1 << 0, ///< Surface is registed in the rasterizer cache.
|
||||
Picked = 1 << 1, ///< Surface has been picked when searching for a match.
|
||||
Tracked = 1 << 2, ///< Surface is part of a texture cube and should be tracked.
|
||||
Custom = 1 << 3, ///< Surface texture has been replaced with a custom texture.
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(SurfaceFlagBits);
|
||||
|
||||
class SurfaceBase : public SurfaceParams {
|
||||
public:
|
||||
SurfaceBase(const SurfaceParams& params);
|
||||
@@ -43,7 +51,7 @@ public:
|
||||
}
|
||||
|
||||
bool IsCustom() const noexcept {
|
||||
return is_custom && custom_format != CustomPixelFormat::Invalid;
|
||||
return True(flags & SurfaceFlagBits::Custom) && custom_format != CustomPixelFormat::Invalid;
|
||||
}
|
||||
|
||||
bool IsRegionValid(SurfaceInterval interval) const {
|
||||
@@ -70,9 +78,7 @@ private:
|
||||
std::array<u8, 4> MakeFillBuffer(PAddr copy_addr);
|
||||
|
||||
public:
|
||||
bool registered = false;
|
||||
bool picked = false;
|
||||
bool is_custom = false;
|
||||
SurfaceFlagBits flags{};
|
||||
const Material* material = nullptr;
|
||||
SurfaceRegions invalid_regions;
|
||||
u32 fill_size = 0;
|
||||
|
@@ -11,7 +11,7 @@ bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
|
||||
return std::tie(other_surface.addr, other_surface.width, other_surface.height,
|
||||
other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) ==
|
||||
std::tie(addr, width, height, stride, pixel_format, is_tiled) &&
|
||||
pixel_format != PixelFormat::Invalid && levels >= other_surface.levels;
|
||||
pixel_format != PixelFormat::Invalid /*&& levels >= other_surface.levels*/;
|
||||
}
|
||||
|
||||
bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {
|
||||
|
@@ -17,8 +17,13 @@ namespace VideoCore {
|
||||
|
||||
using SurfaceInterval = boost::icl::right_open_interval<PAddr>;
|
||||
|
||||
using SurfaceId = SlotId;
|
||||
using SamplerId = SlotId;
|
||||
|
||||
/// Fake surface ID for null surfaces
|
||||
constexpr SurfaceId NULL_SURFACE_ID{0};
|
||||
/// Fake surface ID for null cube surfaces
|
||||
constexpr SurfaceId NULL_SURFACE_CUBE_ID{1};
|
||||
/// Fake sampler ID for null samplers
|
||||
constexpr SamplerId NULL_SAMPLER_ID{0};
|
||||
|
||||
@@ -77,9 +82,9 @@ struct BufferTextureCopy {
|
||||
};
|
||||
|
||||
struct StagingData {
|
||||
u32 size = 0;
|
||||
std::span<u8> mapped{};
|
||||
u64 buffer_offset = 0;
|
||||
u32 size;
|
||||
std::span<u8> mapped;
|
||||
u64 buffer_offset;
|
||||
};
|
||||
|
||||
struct TextureCubeConfig {
|
||||
|
@@ -25,7 +25,7 @@ MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(255, 128,
|
||||
MICROPROFILE_DEFINE(OpenGL_VS, "OpenGL", "Vertex Shader Setup", MP_RGB(192, 128, 128));
|
||||
MICROPROFILE_DEFINE(OpenGL_GS, "OpenGL", "Geometry Shader Setup", MP_RGB(128, 192, 128));
|
||||
MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
|
||||
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
||||
MICROPROFILE_DEFINE(OpenGL_Display, "OpenGL", "Display", MP_RGB(128, 128, 192));
|
||||
|
||||
using VideoCore::SurfaceType;
|
||||
|
||||
@@ -241,14 +241,14 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset,
|
||||
}
|
||||
}
|
||||
|
||||
PAddr data_addr =
|
||||
const PAddr data_addr =
|
||||
base_address + loader.data_offset + (vs_input_index_min * loader.byte_count);
|
||||
|
||||
u32 vertex_num = vs_input_index_max - vs_input_index_min + 1;
|
||||
u32 data_size = loader.byte_count * vertex_num;
|
||||
const u32 vertex_num = vs_input_index_max - vs_input_index_min + 1;
|
||||
const u32 data_size = loader.byte_count * vertex_num;
|
||||
|
||||
res_cache.FlushRegion(data_addr, data_size, nullptr);
|
||||
std::memcpy(array_ptr, VideoCore::g_memory->GetPhysicalPointer(data_addr), data_size);
|
||||
res_cache.FlushRegion(data_addr, data_size);
|
||||
std::memcpy(array_ptr, memory.GetPhysicalPointer(data_addr), data_size);
|
||||
|
||||
array_ptr += data_size;
|
||||
buffer_offset += data_size;
|
||||
@@ -277,8 +277,7 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset,
|
||||
|
||||
bool RasterizerOpenGL::SetupVertexShader() {
|
||||
MICROPROFILE_SCOPE(OpenGL_VS);
|
||||
return shader_program_manager->UseProgrammableVertexShader(Pica::g_state.regs,
|
||||
Pica::g_state.vs);
|
||||
return shader_program_manager->UseProgrammableVertexShader(regs, Pica::g_state.vs);
|
||||
}
|
||||
|
||||
bool RasterizerOpenGL::SetupGeometryShader() {
|
||||
@@ -510,8 +509,8 @@ void RasterizerOpenGL::SyncTextureUnits(const Framebuffer& framebuffer) {
|
||||
if (texture_index == 0) {
|
||||
switch (texture.config.type.Value()) {
|
||||
case TextureType::Shadow2D: {
|
||||
auto surface = res_cache.GetTextureSurface(texture);
|
||||
state.image_shadow_texture_px = surface->Handle();
|
||||
Surface& surface = res_cache.GetTextureSurface(texture);
|
||||
state.image_shadow_texture_px = surface.Handle();
|
||||
continue;
|
||||
}
|
||||
case TextureType::ShadowCube: {
|
||||
@@ -528,23 +527,14 @@ void RasterizerOpenGL::SyncTextureUnits(const Framebuffer& framebuffer) {
|
||||
}
|
||||
|
||||
// Sync texture unit sampler
|
||||
const Sampler& sampler = res_cache.GetSampler(texture.config);
|
||||
Sampler& sampler = res_cache.GetSampler(texture.config);
|
||||
state.texture_units[texture_index].sampler = sampler.Handle();
|
||||
|
||||
// Bind the texture provided by the rasterizer cache
|
||||
auto surface = res_cache.GetTextureSurface(texture);
|
||||
if (!surface) {
|
||||
// Can occur when texture addr is null or its memory is unmapped/invalid
|
||||
// HACK: In this case, the correct behaviour for the PICA is to use the last
|
||||
// rendered colour. But because this would be impractical to implement, the
|
||||
// next best alternative is to use a clear texture, essentially skipping
|
||||
// the geometry in question.
|
||||
// For example: a bug in Pokemon X/Y causes NULL-texture squares to be drawn
|
||||
// on the male character's face, which in the OpenGL default appear black.
|
||||
state.texture_units[texture_index].texture_2d = default_texture;
|
||||
} else if (!IsFeedbackLoop(texture_index, framebuffer, *surface)) {
|
||||
BindMaterial(texture_index, *surface);
|
||||
state.texture_units[texture_index].texture_2d = surface->Handle();
|
||||
Surface& surface = res_cache.GetTextureSurface(texture);
|
||||
if (!IsFeedbackLoop(texture_index, framebuffer, surface)) {
|
||||
BindMaterial(texture_index, surface);
|
||||
state.texture_units[texture_index].texture_2d = surface.Handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,8 +551,9 @@ void RasterizerOpenGL::BindShadowCube(const Pica::TexturingRegs::FullTextureConf
|
||||
const u32 binding = static_cast<u32>(face);
|
||||
info.physical_address = regs.texturing.GetCubePhysicalAddress(face);
|
||||
|
||||
auto surface = res_cache.GetTextureSurface(info);
|
||||
state.image_shadow_texture[binding] = surface->Handle();
|
||||
VideoCore::SurfaceId surface_id = res_cache.GetTextureSurface(info);
|
||||
Surface& surface = res_cache.GetSurface(surface_id);
|
||||
state.image_shadow_texture[binding] = surface.Handle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,10 +571,10 @@ void RasterizerOpenGL::BindTextureCube(const Pica::TexturingRegs::FullTextureCon
|
||||
.format = texture.format,
|
||||
};
|
||||
|
||||
auto surface = res_cache.GetTextureCube(config);
|
||||
Surface& surface = res_cache.GetTextureCube(config);
|
||||
Sampler& sampler = res_cache.GetSampler(texture.config);
|
||||
|
||||
state.texture_cube_unit.texture_cube = surface->Handle();
|
||||
state.texture_cube_unit.texture_cube = surface.Handle();
|
||||
state.texture_cube_unit.sampler = sampler.Handle();
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
}
|
||||
@@ -718,24 +709,20 @@ void RasterizerOpenGL::NotifyFixedFunctionPicaRegisterChanged(u32 id) {
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::FlushAll() {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
res_cache.FlushAll();
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::FlushRegion(PAddr addr, u32 size) {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
res_cache.FlushRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
res_cache.InvalidateRegion(addr, size, nullptr);
|
||||
res_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
res_cache.FlushRegion(addr, size);
|
||||
res_cache.InvalidateRegion(addr, size, nullptr);
|
||||
res_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::ClearAll(bool flush) {
|
||||
@@ -760,7 +747,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
|
||||
if (framebuffer_addr == 0) {
|
||||
return false;
|
||||
}
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
MICROPROFILE_SCOPE(OpenGL_Display);
|
||||
|
||||
VideoCore::SurfaceParams src_params;
|
||||
src_params.addr = framebuffer_addr;
|
||||
@@ -771,27 +758,27 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con
|
||||
src_params.pixel_format = VideoCore::PixelFormatFromGPUPixelFormat(config.color_format);
|
||||
src_params.UpdateParams();
|
||||
|
||||
auto [src_surface, src_rect] =
|
||||
const auto [src_surface_id, src_rect] =
|
||||
res_cache.GetSurfaceSubRect(src_params, VideoCore::ScaleMatch::Ignore, true);
|
||||
|
||||
if (src_surface == nullptr) {
|
||||
if (!src_surface_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 scaled_width = src_surface->GetScaledWidth();
|
||||
const u32 scaled_height = src_surface->GetScaledHeight();
|
||||
const Surface& src_surface = res_cache.GetSurface(src_surface_id);
|
||||
const u32 scaled_width = src_surface.GetScaledWidth();
|
||||
const u32 scaled_height = src_surface.GetScaledHeight();
|
||||
|
||||
screen_info.display_texcoords = Common::Rectangle<float>(
|
||||
(float)src_rect.bottom / (float)scaled_height, (float)src_rect.left / (float)scaled_width,
|
||||
(float)src_rect.top / (float)scaled_height, (float)src_rect.right / (float)scaled_width);
|
||||
|
||||
screen_info.display_texture = src_surface->Handle();
|
||||
screen_info.display_texture = src_surface.Handle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncClipEnabled() {
|
||||
state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0;
|
||||
state.clip_distance[1] = regs.rasterizer.clip_enable != 0;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncCullMode() {
|
||||
@@ -819,7 +806,7 @@ void RasterizerOpenGL::SyncCullMode() {
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendEnabled() {
|
||||
state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1);
|
||||
state.blend.enabled = (regs.framebuffer.output_merger.alphablend_enable == 1);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendFuncs() {
|
||||
@@ -838,8 +825,7 @@ void RasterizerOpenGL::SyncBlendFuncs() {
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncBlendColor() {
|
||||
auto blend_color =
|
||||
PicaToGL::ColorRGBA8(Pica::g_state.regs.framebuffer.output_merger.blend_const.raw);
|
||||
auto blend_color = PicaToGL::ColorRGBA8(regs.framebuffer.output_merger.blend_const.raw);
|
||||
state.blend.color.red = blend_color[0];
|
||||
state.blend.color.green = blend_color[1];
|
||||
state.blend.color.blue = blend_color[2];
|
||||
|
@@ -573,7 +573,6 @@ bool Surface::Swap(const VideoCore::Material* mat) {
|
||||
GetScaledWidth(), GetScaledHeight(), VideoCore::PixelFormatAsString(pixel_format),
|
||||
addr, width, height, VideoCore::CustomPixelFormatAsString(format));
|
||||
|
||||
is_custom = true;
|
||||
custom_format = format;
|
||||
material = mat;
|
||||
|
||||
@@ -615,13 +614,13 @@ HostTextureTag Surface::MakeTag() const noexcept {
|
||||
.res_scale = alloc.res_scale,
|
||||
.tuple = alloc.tuple,
|
||||
.type = texture_type,
|
||||
.is_custom = is_custom,
|
||||
.is_custom = True(flags & VideoCore::SurfaceFlagBits::Custom),
|
||||
.has_normal = HasNormalMap(),
|
||||
};
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(TextureRuntime& runtime, Surface* const color, u32 color_level,
|
||||
Surface* const depth_stencil, u32 depth_level, const Pica::Regs& regs,
|
||||
Framebuffer::Framebuffer(TextureRuntime& runtime, const Surface* color, u32 color_level,
|
||||
const Surface* depth_stencil, u32 depth_level, const Pica::Regs& regs,
|
||||
Common::Rectangle<u32> surfaces_rect)
|
||||
: VideoCore::FramebufferBase{regs, color, color_level,
|
||||
depth_stencil, depth_level, surfaces_rect} {
|
||||
|
@@ -201,8 +201,8 @@ private:
|
||||
|
||||
class Framebuffer : public VideoCore::FramebufferBase {
|
||||
public:
|
||||
explicit Framebuffer(TextureRuntime& runtime, Surface* const color, u32 color_level,
|
||||
Surface* const depth_stencil, u32 depth_level, const Pica::Regs& regs,
|
||||
explicit Framebuffer(TextureRuntime& runtime, const Surface* color, u32 color_level,
|
||||
const Surface* depth_stencil, u32 depth_level, const Pica::Regs& regs,
|
||||
Common::Rectangle<u32> surfaces_rect);
|
||||
~Framebuffer();
|
||||
|
||||
@@ -243,7 +243,7 @@ private:
|
||||
};
|
||||
|
||||
struct Traits {
|
||||
using TextureRuntime = OpenGL::TextureRuntime;
|
||||
using Runtime = OpenGL::TextureRuntime;
|
||||
using Sampler = OpenGL::Sampler;
|
||||
using Surface = OpenGL::Surface;
|
||||
using Framebuffer = OpenGL::Framebuffer;
|
||||
|
Reference in New Issue
Block a user