mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-12-28 14:16:57 +00:00
texture_cache: Implement texception detection and texture barriers.
This commit is contained in:
parent
198a0395bb
commit
d7587842eb
|
@ -422,7 +422,7 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||||
}
|
}
|
||||||
current_framebuffer_config_state = fb_config_state;
|
current_framebuffer_config_state = fb_config_state;
|
||||||
|
|
||||||
texture_cache.Guard(true);
|
texture_cache.GuardRenderTargets(true);
|
||||||
|
|
||||||
View depth_surface{};
|
View depth_surface{};
|
||||||
if (using_depth_fb) {
|
if (using_depth_fb) {
|
||||||
|
@ -500,7 +500,7 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||||
depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
|
depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_cache.Guard(false);
|
texture_cache.GuardRenderTargets(false);
|
||||||
|
|
||||||
current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey);
|
current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey);
|
||||||
SyncViewport(current_state);
|
SyncViewport(current_state);
|
||||||
|
@ -651,7 +651,9 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
SetupVertexBuffer(vao);
|
SetupVertexBuffer(vao);
|
||||||
|
|
||||||
DrawParameters params = SetupDraw();
|
DrawParameters params = SetupDraw();
|
||||||
|
texture_cache.GuardSamplers(true);
|
||||||
SetupShaders(params.primitive_mode);
|
SetupShaders(params.primitive_mode);
|
||||||
|
texture_cache.GuardSamplers(false);
|
||||||
|
|
||||||
ConfigureFramebuffers(state);
|
ConfigureFramebuffers(state);
|
||||||
|
|
||||||
|
@ -660,6 +662,10 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
shader_program_manager->ApplyTo(state);
|
shader_program_manager->ApplyTo(state);
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
if (texture_cache.TextureBarrier()) {
|
||||||
|
glTextureBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
params.DispatchDraw();
|
params.DispatchDraw();
|
||||||
|
|
||||||
accelerate_draw = AccelDraw::Disabled;
|
accelerate_draw = AccelDraw::Disabled;
|
||||||
|
|
|
@ -70,8 +70,12 @@ public:
|
||||||
* `Guard` guarantees that rendertargets don't unregister themselves if the
|
* `Guard` guarantees that rendertargets don't unregister themselves if the
|
||||||
* collide. Protection is currently only done on 3D slices.
|
* collide. Protection is currently only done on 3D slices.
|
||||||
**/
|
**/
|
||||||
void Guard(bool new_guard) {
|
void GuardRenderTargets(bool new_guard) {
|
||||||
guard_cache = new_guard;
|
guard_render_targets = new_guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuardSamplers(bool new_guard) {
|
||||||
|
guard_samplers = new_guard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushRegion(CacheAddr addr, std::size_t size) {
|
void FlushRegion(CacheAddr addr, std::size_t size) {
|
||||||
|
@ -98,7 +102,25 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto params{SurfaceParams::CreateForTexture(system, config, entry)};
|
const auto params{SurfaceParams::CreateForTexture(system, config, entry)};
|
||||||
return GetSurface(gpu_addr, params, true, false).second;
|
auto pair = GetSurface(gpu_addr, params, true, false);
|
||||||
|
if (guard_samplers) {
|
||||||
|
if (sampled_textures_stack_pointer == sampled_textures_stack.size()) {
|
||||||
|
sampled_textures_stack.resize(sampled_textures_stack.size() * 2);
|
||||||
|
}
|
||||||
|
sampled_textures_stack[sampled_textures_stack_pointer] = pair.first;
|
||||||
|
sampled_textures_stack_pointer++;
|
||||||
|
}
|
||||||
|
return pair.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureBarrier() {
|
||||||
|
bool must_do = false;
|
||||||
|
for (u32 i = 0; i < sampled_textures_stack_pointer; i++) {
|
||||||
|
must_do |= sampled_textures_stack[i]->IsRenderTarget();
|
||||||
|
sampled_textures_stack[i] = nullptr;
|
||||||
|
}
|
||||||
|
sampled_textures_stack_pointer = 0;
|
||||||
|
return must_do;
|
||||||
}
|
}
|
||||||
|
|
||||||
TView GetDepthBufferSurface(bool preserve_contents) {
|
TView GetDepthBufferSurface(bool preserve_contents) {
|
||||||
|
@ -239,6 +261,7 @@ protected:
|
||||||
make_siblings(PixelFormat::Z16, PixelFormat::R16F);
|
make_siblings(PixelFormat::Z16, PixelFormat::R16F);
|
||||||
make_siblings(PixelFormat::Z32F, PixelFormat::R32F);
|
make_siblings(PixelFormat::Z32F, PixelFormat::R32F);
|
||||||
make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F);
|
make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F);
|
||||||
|
sampled_textures_stack.resize(64);
|
||||||
}
|
}
|
||||||
|
|
||||||
~TextureCache() = default;
|
~TextureCache() = default;
|
||||||
|
@ -275,7 +298,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unregister(TSurface surface) {
|
void Unregister(TSurface surface) {
|
||||||
if (guard_cache && surface->IsProtected()) {
|
if (guard_render_targets && surface->IsProtected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
||||||
|
@ -766,7 +789,8 @@ private:
|
||||||
u64 ticks{};
|
u64 ticks{};
|
||||||
|
|
||||||
// Guards the cache for protection conflicts.
|
// Guards the cache for protection conflicts.
|
||||||
bool guard_cache{};
|
bool guard_render_targets{};
|
||||||
|
bool guard_samplers{};
|
||||||
|
|
||||||
// The siblings table is for formats that can inter exchange with one another
|
// The siblings table is for formats that can inter exchange with one another
|
||||||
// without causing issues. This is only valid when a conflict occurs on a non
|
// without causing issues. This is only valid when a conflict occurs on a non
|
||||||
|
@ -792,6 +816,9 @@ private:
|
||||||
render_targets;
|
render_targets;
|
||||||
FramebufferTargetInfo depth_buffer;
|
FramebufferTargetInfo depth_buffer;
|
||||||
|
|
||||||
|
std::vector<TSurface> sampled_textures_stack{};
|
||||||
|
u32 sampled_textures_stack_pointer{};
|
||||||
|
|
||||||
StagingCache staging_cache;
|
StagingCache staging_cache;
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue