mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 16:02:26 +00:00
forced sync2 + better barriers
This commit is contained in:
parent
72112271c0
commit
253cc12ee7
@ -118,6 +118,25 @@ public:
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<vk::BufferMemoryBarrier2> GetBarrier(vk::AccessFlagBits2 dst_acess_mask,
|
||||||
|
vk::PipelineStageFlagBits2 dst_stage) {
|
||||||
|
if (dst_acess_mask == access_mask && stage == dst_stage) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto barrier = vk::BufferMemoryBarrier2{
|
||||||
|
.srcStageMask = stage,
|
||||||
|
.srcAccessMask = access_mask,
|
||||||
|
.dstStageMask = dst_stage,
|
||||||
|
.dstAccessMask = dst_acess_mask,
|
||||||
|
.buffer = buffer.buffer,
|
||||||
|
.size = size_bytes,
|
||||||
|
};
|
||||||
|
access_mask = dst_acess_mask;
|
||||||
|
stage = dst_stage;
|
||||||
|
return barrier;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VAddr cpu_addr = 0;
|
VAddr cpu_addr = 0;
|
||||||
bool is_picked{};
|
bool is_picked{};
|
||||||
@ -128,6 +147,8 @@ public:
|
|||||||
const Vulkan::Instance* instance{};
|
const Vulkan::Instance* instance{};
|
||||||
MemoryUsage usage;
|
MemoryUsage usage;
|
||||||
UniqueBuffer buffer;
|
UniqueBuffer buffer;
|
||||||
|
vk::AccessFlagBits2 access_mask{vk::AccessFlagBits2::eNone};
|
||||||
|
vk::PipelineStageFlagBits2 stage{vk::PipelineStageFlagBits2::eNone};
|
||||||
struct BufferView {
|
struct BufferView {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 size;
|
u32 size;
|
||||||
|
@ -248,11 +248,11 @@ std::pair<Buffer*, u32> BufferCache::ObtainBuffer(VAddr device_addr, u32 size, b
|
|||||||
return {&buffer, buffer.Offset(device_addr)};
|
return {&buffer, buffer.Offset(device_addr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<const Buffer*, u32> BufferCache::ObtainTempBuffer(VAddr gpu_addr, u32 size) {
|
std::pair<Buffer*, u32> BufferCache::ObtainTempBuffer(VAddr gpu_addr, u32 size) {
|
||||||
const u64 page = gpu_addr >> CACHING_PAGEBITS;
|
const u64 page = gpu_addr >> CACHING_PAGEBITS;
|
||||||
const BufferId buffer_id = page_table[page];
|
const BufferId buffer_id = page_table[page];
|
||||||
if (buffer_id) {
|
if (buffer_id) {
|
||||||
const Buffer& buffer = slot_buffers[buffer_id];
|
Buffer& buffer = slot_buffers[buffer_id];
|
||||||
if (buffer.IsInBounds(gpu_addr, size)) {
|
if (buffer.IsInBounds(gpu_addr, size)) {
|
||||||
return {&buffer, buffer.Offset(gpu_addr)};
|
return {&buffer, buffer.Offset(gpu_addr)};
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
bool is_texel_buffer = false);
|
bool is_texel_buffer = false);
|
||||||
|
|
||||||
/// Obtains a temporary buffer for usage in texture cache.
|
/// Obtains a temporary buffer for usage in texture cache.
|
||||||
[[nodiscard]] std::pair<const Buffer*, u32> ObtainTempBuffer(VAddr gpu_addr, u32 size);
|
[[nodiscard]] std::pair<Buffer*, u32> ObtainTempBuffer(VAddr gpu_addr, u32 size);
|
||||||
|
|
||||||
/// Return true when a region is registered on the cache
|
/// Return true when a region is registered on the cache
|
||||||
[[nodiscard]] bool IsRegionRegistered(VAddr addr, size_t size);
|
[[nodiscard]] bool IsRegionRegistered(VAddr addr, size_t size);
|
||||||
|
@ -104,6 +104,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
|
|||||||
boost::container::static_vector<vk::DescriptorBufferInfo, 16> buffer_infos;
|
boost::container::static_vector<vk::DescriptorBufferInfo, 16> buffer_infos;
|
||||||
boost::container::static_vector<vk::DescriptorImageInfo, 16> image_infos;
|
boost::container::static_vector<vk::DescriptorImageInfo, 16> image_infos;
|
||||||
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
||||||
|
boost::container::small_vector<vk::BufferMemoryBarrier2, 16> buffer_barriers;
|
||||||
Shader::PushData push_data{};
|
Shader::PushData push_data{};
|
||||||
u32 binding{};
|
u32 binding{};
|
||||||
|
|
||||||
@ -183,6 +184,13 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
|
|||||||
}
|
}
|
||||||
buffer_view = vk_buffer->View(offset_aligned, size + adjust, desc.is_written,
|
buffer_view = vk_buffer->View(offset_aligned, size + adjust, desc.is_written,
|
||||||
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
|
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
|
||||||
|
|
||||||
|
if (auto barrier =
|
||||||
|
vk_buffer->GetBarrier(desc.is_written ? vk::AccessFlagBits2::eShaderWrite
|
||||||
|
: vk::AccessFlagBits2::eShaderRead,
|
||||||
|
vk::PipelineStageFlagBits2::eComputeShader)) {
|
||||||
|
buffer_barriers.emplace_back(*barrier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
set_writes.push_back({
|
set_writes.push_back({
|
||||||
.dstSet = VK_NULL_HANDLE,
|
.dstSet = VK_NULL_HANDLE,
|
||||||
@ -242,6 +250,15 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
|
if (!buffer_barriers.empty()) {
|
||||||
|
auto dependencies = vk::DependencyInfo{
|
||||||
|
.bufferMemoryBarrierCount = u32(buffer_barriers.size()),
|
||||||
|
.pBufferMemoryBarriers = buffer_barriers.data(),
|
||||||
|
};
|
||||||
|
cmdbuf.pipelineBarrier2(dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0u, sizeof(push_data),
|
cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0u, sizeof(push_data),
|
||||||
&push_data);
|
&push_data);
|
||||||
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, set_writes);
|
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, set_writes);
|
||||||
|
@ -359,7 +359,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
|
|||||||
boost::container::static_vector<vk::DescriptorBufferInfo, 32> buffer_infos;
|
boost::container::static_vector<vk::DescriptorBufferInfo, 32> buffer_infos;
|
||||||
boost::container::static_vector<vk::DescriptorImageInfo, 32> image_infos;
|
boost::container::static_vector<vk::DescriptorImageInfo, 32> image_infos;
|
||||||
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
||||||
boost::container::small_vector<vk::BufferMemoryBarrier, 16> buffer_barriers;
|
boost::container::small_vector<vk::BufferMemoryBarrier2, 16> buffer_barriers;
|
||||||
Shader::PushData push_data{};
|
Shader::PushData push_data{};
|
||||||
u32 binding{};
|
u32 binding{};
|
||||||
|
|
||||||
@ -425,15 +425,11 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
|
|||||||
}
|
}
|
||||||
buffer_view = vk_buffer->View(offset_aligned, size + adjust, tex_buffer.is_written,
|
buffer_view = vk_buffer->View(offset_aligned, size + adjust, tex_buffer.is_written,
|
||||||
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
|
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
|
||||||
|
const auto dst_access = tex_buffer.is_written ? vk::AccessFlagBits2::eShaderWrite
|
||||||
if (buffer_cache.IsRegionGpuModified(address, size)) {
|
: vk::AccessFlagBits2::eShaderRead;
|
||||||
buffer_barriers.push_back(vk::BufferMemoryBarrier{
|
if (auto barrier = vk_buffer->GetBarrier(
|
||||||
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
|
dst_access, vk::PipelineStageFlagBits2::eVertexShader)) {
|
||||||
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
|
buffer_barriers.emplace_back(*barrier);
|
||||||
.buffer = vk_buffer->Handle(),
|
|
||||||
.offset = offset,
|
|
||||||
.size = size,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_writes.push_back({
|
set_writes.push_back({
|
||||||
@ -501,10 +497,11 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
|
|||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
|
||||||
if (!buffer_barriers.empty()) {
|
if (!buffer_barriers.empty()) {
|
||||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader |
|
auto dependencies = vk::DependencyInfo{
|
||||||
vk::PipelineStageFlagBits::eComputeShader,
|
.bufferMemoryBarrierCount = u32(buffer_barriers.size()),
|
||||||
vk::PipelineStageFlagBits::eFragmentShader,
|
.pBufferMemoryBarriers = buffer_barriers.data(),
|
||||||
vk::DependencyFlagBits::eByRegion, {}, buffer_barriers, {});
|
};
|
||||||
|
cmdbuf.pipelineBarrier2(dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_writes.empty()) {
|
if (!set_writes.empty()) {
|
||||||
|
@ -228,6 +228,7 @@ bool Instance::CreateDevice() {
|
|||||||
const bool maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
|
const bool maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
|
||||||
add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
||||||
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
|
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
|
||||||
|
add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Required by Vulkan spec if supported.
|
// Required by Vulkan spec if supported.
|
||||||
|
@ -314,6 +314,7 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
|
|||||||
|
|
||||||
// Update tracked image usage
|
// Update tracked image usage
|
||||||
image.info.usage.depth_target = true;
|
image.info.usage.depth_target = true;
|
||||||
|
image.info.usage.stencil = has_stencil;
|
||||||
|
|
||||||
return RegisterImageView(image_id, view_info);
|
return RegisterImageView(image_id, view_info);
|
||||||
}
|
}
|
||||||
@ -383,18 +384,13 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
|
|||||||
|
|
||||||
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent
|
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent
|
||||||
// RAW hazard
|
// RAW hazard
|
||||||
if (buffer_cache.IsRegionGpuModified(image_addr, image_size)) {
|
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eTransferRead,
|
||||||
const vk::BufferMemoryBarrier post_barrier{
|
vk::PipelineStageFlagBits2::eTransfer)) {
|
||||||
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
|
auto dependencies = vk::DependencyInfo{
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
.bufferMemoryBarrierCount = 1,
|
||||||
.buffer = buffer,
|
.pBufferMemoryBarriers = &barrier.value(),
|
||||||
.offset = offset,
|
|
||||||
.size = image_size,
|
|
||||||
};
|
};
|
||||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader |
|
cmdbuf.pipelineBarrier2(dependencies);
|
||||||
vk::PipelineStageFlagBits::eComputeShader,
|
|
||||||
vk::PipelineStageFlagBits::eTransfer,
|
|
||||||
vk::DependencyFlagBits::eByRegion, {}, post_barrier, {});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user