texture_cache: Implement texception detection and texture barriers.

This commit is contained in:
Fernando Sahmkow 2019-06-15 13:22:57 -04:00 committed by ReinUsesLisp
parent 198a0395bb
commit d7587842eb
2 changed files with 40 additions and 7 deletions

View file

@ -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;

View file

@ -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;
}; };