The current Vulkan resource management has some issues as context that are not active can still use resources that are freed via another context. When this happens incorrect data can be read on the GPU and even crash Blender. When trying to bind something that now contains other memory pointers. This change introduces that contexts are tracked via the device. Context will be registered/unregistered with the device instance. Unbinding of resources must pass the device and the device will check all registered contexts. Binding of resources will happen via the active context only. On user perspective this now allowes: - Opening/switching files - Switching workspaces - Switching render engines Pull Request: https://projects.blender.org/blender/blender/pulls/108968
79 lines
1.6 KiB
C++
79 lines
1.6 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "gpu_context_private.hh"
|
|
|
|
#include "vk_common.hh"
|
|
|
|
namespace blender::gpu {
|
|
class VKContext;
|
|
|
|
/**
|
|
* Class for handing vulkan buffers (allocation/updating/binding).
|
|
*/
|
|
class VKBuffer {
|
|
int64_t size_in_bytes_ = 0;
|
|
VkBuffer vk_buffer_ = VK_NULL_HANDLE;
|
|
VmaAllocation allocation_ = VK_NULL_HANDLE;
|
|
/* Pointer to the virtually mapped memory. */
|
|
void *mapped_memory_ = nullptr;
|
|
|
|
public:
|
|
VKBuffer() = default;
|
|
virtual ~VKBuffer();
|
|
|
|
/** Has this buffer been allocated? */
|
|
bool is_allocated() const;
|
|
|
|
bool create(int64_t size, GPUUsageType usage, VkBufferUsageFlagBits buffer_usage);
|
|
void clear(VKContext &context, uint32_t clear_value);
|
|
void update(const void *data) const;
|
|
void read(void *data) const;
|
|
bool free();
|
|
|
|
int64_t size_in_bytes() const
|
|
{
|
|
return size_in_bytes_;
|
|
}
|
|
|
|
VkBuffer vk_handle() const
|
|
{
|
|
return vk_buffer_;
|
|
}
|
|
|
|
/**
|
|
* Get the reference to the mapped memory.
|
|
*
|
|
* Can only be called when the buffer is (still) mapped.
|
|
*/
|
|
void *mapped_memory_get() const;
|
|
|
|
private:
|
|
/** Check if this buffer is mapped. */
|
|
bool is_mapped() const;
|
|
bool map();
|
|
void unmap();
|
|
};
|
|
|
|
/**
|
|
* Helper struct to enable buffers to be bound with an offset.
|
|
*
|
|
* VKImmediate mode uses a single VKBuffer with multiple vertex layouts. Those layouts are send to
|
|
* the command buffer containing an offset.
|
|
*
|
|
* VKIndexBuffer uses this when it is a subrange of another buffer.
|
|
*/
|
|
struct VKBufferWithOffset {
|
|
VKBuffer &buffer;
|
|
VkDeviceSize offset;
|
|
};
|
|
|
|
} // namespace blender::gpu
|