mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-27 04:25:12 +00:00
Use conditional rendering based on the occlusion query results
This commit is contained in:
parent
ab9254f21a
commit
34f0f03f99
@ -405,7 +405,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
}
|
}
|
||||||
else if (predication->pred_op.Value() == PredicateOperation::Zpass) {
|
else if (predication->pred_op.Value() == PredicateOperation::Zpass) {
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
rasterizer->StartPredication();
|
rasterizer->StartPredication(predication->Address<VAddr>(),
|
||||||
|
predication->action.Value() == Predication::DrawIfVisible,
|
||||||
|
predication->hint.Value() == PredicationHint::Wait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -42,7 +42,9 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_,
|
|||||||
: instance{instance_}, scheduler{scheduler_}, page_manager{this},
|
: instance{instance_}, scheduler{scheduler_}, page_manager{this},
|
||||||
buffer_cache{instance, scheduler, *this, liverpool_, texture_cache, page_manager},
|
buffer_cache{instance, scheduler, *this, liverpool_, texture_cache, page_manager},
|
||||||
texture_cache{instance, scheduler, buffer_cache, page_manager}, liverpool{liverpool_},
|
texture_cache{instance, scheduler, buffer_cache, page_manager}, liverpool{liverpool_},
|
||||||
memory{Core::Memory::Instance()}, pipeline_cache{instance, scheduler, liverpool} {
|
memory{Core::Memory::Instance()}, pipeline_cache{instance, scheduler, liverpool},
|
||||||
|
occlusion_query_buffer{instance, scheduler, VideoCore::MemoryUsage::DeviceLocal, 0,
|
||||||
|
vk::BufferUsageFlagBits::eConditionalRenderingEXT | vk::BufferUsageFlagBits::eTransferDst, sizeof(u32)*OCCLUSION_QUERIES_COUNT} {
|
||||||
if (!Config::nullGpu()) {
|
if (!Config::nullGpu()) {
|
||||||
liverpool->BindRasterizer(this);
|
liverpool->BindRasterizer(this);
|
||||||
}
|
}
|
||||||
@ -52,6 +54,7 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_,
|
|||||||
.queryCount = OCCLUSION_QUERIES_COUNT,
|
.queryCount = OCCLUSION_QUERIES_COUNT,
|
||||||
}));
|
}));
|
||||||
instance.GetDevice().resetQueryPool(occlusion_query_pool, 0, OCCLUSION_QUERIES_COUNT);
|
instance.GetDevice().resetQueryPool(occlusion_query_pool, 0, OCCLUSION_QUERIES_COUNT);
|
||||||
|
Vulkan::SetObjectName(instance.GetDevice(), occlusion_query_buffer.Handle(), "OcclusionQueryBuffer:{:#x}", sizeof(u32)*OCCLUSION_QUERIES_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rasterizer::~Rasterizer() = default;
|
Rasterizer::~Rasterizer() = default;
|
||||||
@ -1272,12 +1275,63 @@ void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32
|
|||||||
(f32)(color & 0xff) / 255.0f, (f32)((color >> 24) & 0xff) / 255.0f})});
|
(f32)(color & 0xff) / 255.0f, (f32)((color >> 24) & 0xff) / 255.0f})});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::StartPredication() {
|
void Rasterizer::StartPredication(VAddr addr, bool draw_if_visible, bool wait_for_result) {
|
||||||
|
if (!instance.IsConditionalRenderingSupported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(!active_predication);
|
||||||
|
ASSERT(occlusion_index_mapping.contains(addr));
|
||||||
|
|
||||||
|
auto index = occlusion_index_mapping[addr];
|
||||||
|
LOG_DEBUG(Render_Vulkan, "addr = {:#x}, index = {}", addr, index);
|
||||||
|
|
||||||
|
scheduler.EndRendering();
|
||||||
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
|
cmdbuf.copyQueryPoolResults(occlusion_query_pool, index, 1, occlusion_query_buffer.Handle(),
|
||||||
|
index*sizeof(u32), sizeof(u32), wait_for_result ? vk::QueryResultFlagBits::eWait
|
||||||
|
: vk::QueryResultFlagBits::ePartial);
|
||||||
|
|
||||||
|
const auto pre_barrier = vk::BufferMemoryBarrier2{
|
||||||
|
.srcStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||||
|
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||||
|
.dstStageMask = vk::PipelineStageFlagBits2::eCopy,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||||
|
.buffer = occlusion_query_buffer.Handle(),
|
||||||
|
.offset = index * sizeof(u32),
|
||||||
|
.size = sizeof(u32),
|
||||||
|
};
|
||||||
|
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||||
|
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
||||||
|
.bufferMemoryBarrierCount = 1,
|
||||||
|
.pBufferMemoryBarriers = &pre_barrier,
|
||||||
|
});
|
||||||
|
|
||||||
|
ScopeMarkerBegin("gfx:{}:predication", fmt::ptr(reinterpret_cast<const void*>(addr)));
|
||||||
|
vk::ConditionalRenderingBeginInfoEXT conditional_rendering_info {
|
||||||
|
.buffer = occlusion_query_buffer.Handle(),
|
||||||
|
.offset = index * sizeof(u32),
|
||||||
|
.flags = draw_if_visible ? vk::ConditionalRenderingFlagBitsEXT::eInverted
|
||||||
|
: vk::ConditionalRenderingFlagsEXT(),
|
||||||
|
};
|
||||||
|
cmdbuf.beginConditionalRenderingEXT(&conditional_rendering_info);
|
||||||
|
|
||||||
|
active_predication = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::EndPredication() {
|
void Rasterizer::EndPredication() {
|
||||||
|
if (!active_predication) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Render_Vulkan, "");
|
||||||
|
|
||||||
|
scheduler.EndRendering();
|
||||||
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
cmdbuf.endConditionalRenderingEXT();
|
||||||
|
ScopeMarkerEnd();
|
||||||
|
active_predication = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::StartOcclusionQuery(VAddr addr) {
|
void Rasterizer::StartOcclusionQuery(VAddr addr) {
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color,
|
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color,
|
||||||
bool from_guest = false);
|
bool from_guest = false);
|
||||||
|
|
||||||
void StartPredication();
|
void StartPredication(VAddr addr, bool discard_if_zero, bool wait_for_result);
|
||||||
void EndPredication();
|
void EndPredication();
|
||||||
void StartOcclusionQuery(VAddr addr);
|
void StartOcclusionQuery(VAddr addr);
|
||||||
void EndOcclusionQuery(VAddr addr);
|
void EndOcclusionQuery(VAddr addr);
|
||||||
@ -130,6 +130,8 @@ private:
|
|||||||
vk::QueryPool occlusion_query_pool;
|
vk::QueryPool occlusion_query_pool;
|
||||||
u32 occlusion_current_index{};
|
u32 occlusion_current_index{};
|
||||||
std::map<VAddr, u32> occlusion_index_mapping;
|
std::map<VAddr, u32> occlusion_index_mapping;
|
||||||
|
VideoCore::Buffer occlusion_query_buffer;
|
||||||
|
bool active_predication;
|
||||||
|
|
||||||
boost::container::static_vector<
|
boost::container::static_vector<
|
||||||
std::pair<VideoCore::ImageId, VideoCore::TextureCache::RenderTargetDesc>, 8>
|
std::pair<VideoCore::ImageId, VideoCore::TextureCache::RenderTargetDesc>, 8>
|
||||||
|
Loading…
Reference in New Issue
Block a user