Fix: Vulkan: Validation error on Qualcomm
!146956 introduced buffer streaming and is used to improve the performance of text rendering. However the solution didn't check the minimum allowed offset for storage buffers. This PR will use the correct offset. This was only visible on Qualcomm devices as other systems don't limit this offset. Detected when looking into: #147023 Pull Request: https://projects.blender.org/blender/blender/pulls/147192
This commit is contained in:
@@ -470,7 +470,8 @@ void VKContext::specialization_constants_set(
|
||||
shader::SpecializationConstants{};
|
||||
}
|
||||
|
||||
std::unique_ptr<VKStreamingBuffer> &VKContext::get_or_create_streaming_buffer(VKBuffer &buffer)
|
||||
std::unique_ptr<VKStreamingBuffer> &VKContext::get_or_create_streaming_buffer(
|
||||
VKBuffer &buffer, VkDeviceSize min_offset_alignment)
|
||||
{
|
||||
for (std::unique_ptr<VKStreamingBuffer> &streaming_buffer : streaming_buffers_) {
|
||||
if (streaming_buffer->vk_buffer_dst() == buffer.vk_handle()) {
|
||||
@@ -478,7 +479,7 @@ std::unique_ptr<VKStreamingBuffer> &VKContext::get_or_create_streaming_buffer(VK
|
||||
}
|
||||
}
|
||||
|
||||
streaming_buffers_.append(std::make_unique<VKStreamingBuffer>(buffer));
|
||||
streaming_buffers_.append(std::make_unique<VKStreamingBuffer>(buffer, min_offset_alignment));
|
||||
return streaming_buffers_.last();
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ class VKContext : public Context, NonCopyable {
|
||||
|
||||
void specialization_constants_set(const shader::SpecializationConstants *constants_state);
|
||||
|
||||
std::unique_ptr<VKStreamingBuffer> &get_or_create_streaming_buffer(VKBuffer &buffer);
|
||||
std::unique_ptr<VKStreamingBuffer> &get_or_create_streaming_buffer(
|
||||
VKBuffer &buffer, VkDeviceSize min_offset_alignment);
|
||||
|
||||
private:
|
||||
void swap_buffer_draw_handler(const GHOST_VulkanSwapChainData &data);
|
||||
|
||||
@@ -38,8 +38,9 @@ void VKStorageBuffer::update(const void *data)
|
||||
ensure_allocated();
|
||||
|
||||
if (usage_ == GPU_USAGE_STREAM) {
|
||||
VKContext &context = *VKContext::get();
|
||||
VKStreamingBuffer &streaming_buffer = *context.get_or_create_streaming_buffer(buffer_);
|
||||
const VKDevice &device = VKBackend::get().device;
|
||||
VKStreamingBuffer &streaming_buffer = *context.get_or_create_streaming_buffer(
|
||||
buffer_, device.physical_device_properties_get().limits.minStorageBufferOffsetAlignment);
|
||||
offset_ = streaming_buffer.update(context, data, usage_size_in_bytes_);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#include "vk_context.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
VKStreamingBuffer::VKStreamingBuffer(VKBuffer &buffer)
|
||||
: vk_buffer_dst_(buffer.vk_handle()), vk_buffer_size_(buffer.size_in_bytes())
|
||||
|
||||
VKStreamingBuffer::VKStreamingBuffer(VKBuffer &buffer, VkDeviceSize min_offset_alignment)
|
||||
: min_offset_alignment_(min_offset_alignment),
|
||||
vk_buffer_dst_(buffer.vk_handle()),
|
||||
vk_buffer_size_(buffer.size_in_bytes())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,7 +48,13 @@ VkDeviceSize VKStreamingBuffer::update(VKContext &context, const void *data, siz
|
||||
VKBuffer &host_buffer = *host_buffer_.value().get();
|
||||
|
||||
VkDeviceSize start_offset = offset_;
|
||||
/* Advance the offset to the next possible offset considering the minimum allowed offset
|
||||
* alignment. */
|
||||
offset_ += data_size;
|
||||
if (min_offset_alignment_ > 1) {
|
||||
offset_ = ceil_to_multiple_ul(offset_, min_offset_alignment_);
|
||||
}
|
||||
|
||||
memcpy(
|
||||
static_cast<void *>(static_cast<uint8_t *>(host_buffer.mapped_memory_get()) + start_offset),
|
||||
data,
|
||||
|
||||
@@ -26,6 +26,9 @@ class VKContext;
|
||||
class VKStreamingBuffer {
|
||||
/** Current host buffer storing the data to be uploaded. */
|
||||
std::optional<std::unique_ptr<VKBuffer>> host_buffer_;
|
||||
/** Minimum alignment for streaming. Needs to be set to
|
||||
* `VkPhysicalDeviceLimits.min*OffsetAlignment` */
|
||||
VkDeviceSize min_offset_alignment_;
|
||||
/** Device buffer that is being updated. */
|
||||
VkBuffer vk_buffer_dst_;
|
||||
/** Size of 'vk_buffer_dst_' */
|
||||
@@ -39,7 +42,7 @@ class VKStreamingBuffer {
|
||||
render_graph::NodeHandle copy_buffer_handle_ = 0;
|
||||
|
||||
public:
|
||||
VKStreamingBuffer(VKBuffer &buffer);
|
||||
VKStreamingBuffer(VKBuffer &buffer, VkDeviceSize min_offset_alligment);
|
||||
~VKStreamingBuffer();
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user