mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 14:26:36 +00:00
Re-adjust dispatch draw + masks
This commit is contained in:
@@ -24,6 +24,18 @@
|
||||
|
||||
namespace Vulkan {
|
||||
namespace {
|
||||
constexpr u32 COMPACT_VERTEX_BINDINGS = 8;
|
||||
|
||||
template <u32 N>
|
||||
struct VertexBindings {
|
||||
std::array<VkBuffer, N> buffers;
|
||||
std::array<VkDeviceSize, N> offsets;
|
||||
std::array<VkDeviceSize, N> sizes;
|
||||
std::array<VkDeviceSize, N> strides;
|
||||
u32 first;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
VkBufferCopy MakeBufferCopy(const VideoCommon::BufferCopy& copy) {
|
||||
return VkBufferCopy{
|
||||
.srcOffset = copy.src_offset,
|
||||
@@ -670,36 +682,52 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
|
||||
}
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
|
||||
boost::container::static_vector<VkBuffer, VideoCommon::NUM_VERTEX_BUFFERS> buffer_handles(bindings.buffers.size());
|
||||
for (u32 i = 0; i < bindings.buffers.size(); ++i) {
|
||||
auto handle = bindings.buffers[i]->Handle();
|
||||
if (handle == VK_NULL_HANDLE) {
|
||||
bindings.offsets[i] = 0;
|
||||
bindings.sizes[i] = VK_WHOLE_SIZE;
|
||||
template <u32 N>
|
||||
void BufferCacheRuntime::RecordVertexBuffers(const VideoCommon::HostBindings<Buffer>& bindings,
|
||||
u32 count) {
|
||||
VertexBindings<N> vertex{};
|
||||
vertex.first = bindings.min_index;
|
||||
vertex.count = count;
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
vertex.buffers[i] = bindings.buffers[i]->Handle();
|
||||
vertex.offsets[i] = bindings.offsets[i];
|
||||
vertex.sizes[i] = bindings.sizes[i];
|
||||
vertex.strides[i] = bindings.strides[i];
|
||||
if (vertex.buffers[i] == VK_NULL_HANDLE) {
|
||||
vertex.offsets[i] = 0;
|
||||
vertex.sizes[i] = VK_WHOLE_SIZE;
|
||||
if (!device.HasNullDescriptor()) {
|
||||
ReserveNullBuffer();
|
||||
handle = *null_buffer;
|
||||
vertex.buffers[i] = *null_buffer;
|
||||
}
|
||||
}
|
||||
buffer_handles[i] = handle;
|
||||
}
|
||||
const u32 device_max = device.GetMaxVertexInputBindings();
|
||||
const u32 min_binding = (std::min)(bindings.min_index, device_max);
|
||||
const u32 max_binding = (std::min)(bindings.max_index, device_max);
|
||||
const u32 binding_count = max_binding - min_binding;
|
||||
if (binding_count == 0) {
|
||||
return;
|
||||
}
|
||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||
scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, binding_count, buffer_handles_.data(), bindings_.offsets.data(), bindings_.sizes.data(), bindings_.strides.data());
|
||||
});
|
||||
} else {
|
||||
scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.BindVertexBuffers(bindings_.min_index, binding_count, buffer_handles_.data(), bindings_.offsets.data());
|
||||
scheduler.Record([vertex](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.BindVertexBuffers2EXT(vertex.first, vertex.count, vertex.buffers.data(),
|
||||
vertex.offsets.data(), vertex.sizes.data(),
|
||||
vertex.strides.data());
|
||||
});
|
||||
return;
|
||||
}
|
||||
scheduler.Record([vertex](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.BindVertexBuffers(vertex.first, vertex.count, vertex.buffers.data(),
|
||||
vertex.offsets.data());
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
|
||||
const u32 device_max = device.GetMaxVertexInputBindings();
|
||||
const u32 count = (std::min)(bindings.max_index, device_max) -
|
||||
(std::min)(bindings.min_index, device_max);
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
if (count <= COMPACT_VERTEX_BINDINGS) {
|
||||
RecordVertexBuffers<COMPACT_VERTEX_BINDINGS>(bindings, count);
|
||||
return;
|
||||
}
|
||||
RecordVertexBuffers<VideoCommon::NUM_VERTEX_BUFFERS>(bindings, count);
|
||||
}
|
||||
|
||||
void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, VkBuffer buffer, u32 offset,
|
||||
|
||||
@@ -244,6 +244,9 @@ private:
|
||||
|
||||
VkFormat TexelBufferFormat(VideoCore::Surface::PixelFormat format) const;
|
||||
|
||||
template <u32 N>
|
||||
void RecordVertexBuffers(const VideoCommon::HostBindings<Buffer>& bindings, u32 count);
|
||||
|
||||
void ReserveNullBuffer();
|
||||
vk::Buffer CreateNullBuffer();
|
||||
|
||||
|
||||
@@ -1032,23 +1032,22 @@ void RasterizerVulkan::LoadDiskResources(u64 title_id, std::stop_token stop_load
|
||||
|
||||
void RasterizerVulkan::FlushWork() {
|
||||
#ifdef __ANDROID__
|
||||
static constexpr u32 DRAWS_TO_DISPATCH = 512;
|
||||
static constexpr u32 CHECK_MASK = 3;
|
||||
static constexpr u32 DRAWS_TO_DISPATCH = 1024;
|
||||
#else
|
||||
static constexpr u32 DRAWS_TO_DISPATCH = 4096;
|
||||
static constexpr u32 CHECK_MASK = 7;
|
||||
#endif // __ANDROID__
|
||||
static constexpr u32 CHECK_MASK = 7;
|
||||
|
||||
static_assert(DRAWS_TO_DISPATCH % (CHECK_MASK + 1) == 0);
|
||||
if ((++draw_counter & CHECK_MASK) != CHECK_MASK) {
|
||||
if (++draw_counter >= DRAWS_TO_DISPATCH &&
|
||||
(!scheduler.IsRenderPassActive() ||
|
||||
maxwell3d->dirty.flags[VideoCommon::Dirty::RenderTargets])) {
|
||||
scheduler.Flush();
|
||||
draw_counter = 0;
|
||||
return;
|
||||
}
|
||||
if (draw_counter < DRAWS_TO_DISPATCH) {
|
||||
if ((draw_counter & CHECK_MASK) == CHECK_MASK) {
|
||||
scheduler.DispatchWork();
|
||||
return;
|
||||
}
|
||||
scheduler.Flush();
|
||||
draw_counter = 0;
|
||||
}
|
||||
|
||||
AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_query_cache.h"
|
||||
|
||||
#include "common/make_unique_for_overwrite.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/thread.h"
|
||||
#include "video_core/gpu_logging/gpu_logging.h"
|
||||
@@ -484,7 +485,7 @@ void Scheduler::AcquireNewChunk() {
|
||||
|
||||
if (chunk_reserve.empty()) {
|
||||
// If we don't have anything reserved, we need to make a new chunk.
|
||||
chunk = std::make_unique<CommandChunk>();
|
||||
chunk = Common::make_unique_for_overwrite<CommandChunk>();
|
||||
} else {
|
||||
// Otherwise, we can just take from the reserve.
|
||||
chunk = std::move(chunk_reserve.back());
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
|
||||
size_t command_offset = 0;
|
||||
bool submit = false;
|
||||
alignas(std::max_align_t) std::array<u8, 0x8000> data{};
|
||||
alignas(std::max_align_t) std::array<u8, 0x8000> data;
|
||||
};
|
||||
|
||||
struct State {
|
||||
|
||||
Reference in New Issue
Block a user