Vulkan: Device Context Resource Management #108968
|
@ -225,6 +225,7 @@ set(VULKAN_SRC
|
|||
vulkan/vk_pixel_buffer.cc
|
||||
vulkan/vk_push_constants.cc
|
||||
vulkan/vk_query.cc
|
||||
vulkan/vk_resource_bindable.cc
|
||||
vulkan/vk_resource_tracker.cc
|
||||
vulkan/vk_sampler.cc
|
||||
vulkan/vk_shader.cc
|
||||
|
@ -261,6 +262,7 @@ set(VULKAN_SRC
|
|||
vulkan/vk_pixel_buffer.hh
|
||||
vulkan/vk_push_constants.hh
|
||||
vulkan/vk_query.hh
|
||||
vulkan/vk_resource_bindable.hh
|
||||
vulkan/vk_resource_tracker.hh
|
||||
vulkan/vk_sampler.hh
|
||||
vulkan/vk_shader.hh
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_shader.h"
|
||||
|
@ -101,12 +102,18 @@ GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_U16__GPU_FETCH_INT_TO_FLOAT);
|
|||
|
||||
static void test_vertex_buffer_fetch_mode__GPU_COMP_I32__GPU_FETCH_INT_TO_FLOAT()
|
||||
{
|
||||
if (GPU_backend_type_selection_get() == GPU_BACKEND_VULKAN) {
|
||||
GTEST_SKIP() << "interleaved format not supported yet";
|
||||
}
|
||||
vertex_buffer_fetch_mode<GPU_COMP_I32, GPU_FETCH_INT_TO_FLOAT, int4>(int4(4, 5, 6, 1));
|
||||
}
|
||||
GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_I32__GPU_FETCH_INT_TO_FLOAT);
|
||||
|
||||
static void test_vertex_buffer_fetch_mode__GPU_COMP_U32__GPU_FETCH_INT_TO_FLOAT()
|
||||
{
|
||||
if (GPU_backend_type_selection_get() == GPU_BACKEND_VULKAN) {
|
||||
GTEST_SKIP() << "interleaved format not supported yet";
|
||||
}
|
||||
vertex_buffer_fetch_mode<GPU_COMP_U32, GPU_FETCH_INT_TO_FLOAT, uint4>(uint4(4, 5, 6, 1));
|
||||
}
|
||||
GPU_TEST(vertex_buffer_fetch_mode__GPU_COMP_U32__GPU_FETCH_INT_TO_FLOAT);
|
||||
|
|
|
@ -77,6 +77,15 @@ void VKDescriptorSetTracker::bind_as_ssbo(VKIndexBuffer &buffer,
|
|||
binding.buffer_size = buffer.size_get();
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::bind_as_ssbo(VKUniformBuffer &buffer,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
binding.vk_buffer = buffer.vk_handle();
|
||||
binding.buffer_size = buffer.size_in_bytes();
|
||||
}
|
||||
|
||||
void VKDescriptorSetTracker::image_bind(VKTexture &texture,
|
||||
const VKDescriptorSet::Location location)
|
||||
{
|
||||
|
|
|
@ -162,6 +162,7 @@ class VKDescriptorSetTracker : protected VKResourceTracker<VKDescriptorSet> {
|
|||
|
||||
void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind_as_ssbo(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location);
|
||||
void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
|
||||
/* TODO: bind as image */
|
||||
|
|
|
@ -196,13 +196,10 @@ void VKDevice::context_unregister(VKContext &context)
|
|||
{
|
||||
contexts_.remove(contexts_.first_index_of(std::reference_wrapper(context)));
|
||||
}
|
||||
|
||||
void VKDevice::unbind(VKUniformBuffer &uniform_buffer) const
|
||||
const Vector<std::reference_wrapper<VKContext>> &VKDevice::contexts_get() const
|
||||
{
|
||||
for (const VKContext &context : contexts_) {
|
||||
context.state_manager_get().uniform_buffer_unbind(&uniform_buffer);
|
||||
}
|
||||
}
|
||||
return contexts_;
|
||||
};
|
||||
|
||||
void VKDevice::unbind(VKTexture &texture) const
|
||||
{
|
||||
|
@ -212,28 +209,6 @@ void VKDevice::unbind(VKTexture &texture) const
|
|||
}
|
||||
}
|
||||
|
||||
void VKDevice::unbind(VKStorageBuffer &storage_buffer) const
|
||||
{
|
||||
for (VKContext &context : contexts_) {
|
||||
context.state_manager_get().storage_buffer_unbind(&storage_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void VKDevice::unbind(VKVertexBuffer &vertex_buffer) const
|
||||
{
|
||||
for (VKContext &context : contexts_) {
|
||||
context.state_manager_get().texel_buffer_unbind(&vertex_buffer);
|
||||
context.state_manager_get().storage_buffer_unbind(&vertex_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void VKDevice::unbind(VKIndexBuffer &index_buffer) const
|
||||
{
|
||||
for (VKContext &context : contexts_) {
|
||||
context.state_manager_get().storage_buffer_unbind(&index_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -132,32 +132,13 @@ class VKDevice : public NonCopyable {
|
|||
|
||||
void context_register(VKContext &context);
|
||||
void context_unregister(VKContext &context);
|
||||
|
||||
/**
|
||||
* Unbind given uniform buffer from registered contexts.
|
||||
*/
|
||||
void unbind(VKUniformBuffer &uniform_buffer) const;
|
||||
const Vector<std::reference_wrapper<VKContext>> &contexts_get() const;
|
||||
|
||||
/**
|
||||
* Unbind given texture from registered contexts.
|
||||
*/
|
||||
void unbind(VKTexture &texture) const;
|
||||
|
||||
/**
|
||||
* Unbind given storage buffer from registered contexts.
|
||||
*/
|
||||
void unbind(VKStorageBuffer &storage_buffer) const;
|
||||
|
||||
/**
|
||||
* Unbind given vertex_buffer from registered contexts.
|
||||
*/
|
||||
void unbind(VKVertexBuffer &vertex_buffer) const;
|
||||
|
||||
/**
|
||||
* Unbind given index_buffer from registered contexts.
|
||||
*/
|
||||
void unbind(VKIndexBuffer &index_buffer) const;
|
||||
|
||||
/** \} */
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,11 +13,6 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKIndexBuffer::~VKIndexBuffer()
|
||||
{
|
||||
VKBackend::get().device_get().unbind(*this);
|
||||
}
|
||||
|
||||
void VKIndexBuffer::ensure_updated()
|
||||
{
|
||||
if (is_subrange_) {
|
||||
|
@ -47,10 +42,10 @@ void VKIndexBuffer::bind(VKContext &context)
|
|||
|
||||
void VKIndexBuffer::bind_as_ssbo(uint binding)
|
||||
{
|
||||
VKContext::get()->state_manager_get().storage_buffer_bind(this, binding);
|
||||
VKContext::get()->state_manager_get().storage_buffer_bind(*this, binding);
|
||||
}
|
||||
|
||||
void VKIndexBuffer::bind(uint binding, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
void VKIndexBuffer::bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
{
|
||||
BLI_assert(bind_type == shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
ensure_updated();
|
||||
|
|
|
@ -11,19 +11,19 @@
|
|||
#include "gpu_index_buffer_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_resource_bindable.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKIndexBuffer : public IndexBuf {
|
||||
class VKIndexBuffer : public IndexBuf, public VKBindableResource {
|
||||
VKBuffer buffer_;
|
||||
|
||||
public:
|
||||
~VKIndexBuffer();
|
||||
void upload_data() override;
|
||||
|
||||
void bind_as_ssbo(uint binding) override;
|
||||
void bind(VKContext &context);
|
||||
void bind(uint binding, shader::ShaderCreateInfo::Resource::BindType bind_type);
|
||||
void bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type) override;
|
||||
|
||||
void read(uint32_t *data) const override;
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#include "vk_resource_bindable.hh"
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_device.hh"
|
||||
#include "vk_state_manager.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKBindableResource::~VKBindableResource()
|
||||
{
|
||||
unbind_from_all_contexts();
|
||||
}
|
||||
|
||||
void VKBindableResource::unbind_from_active_context()
|
||||
{
|
||||
const VKContext *context = VKContext::get();
|
||||
if (context != nullptr) {
|
||||
VKStateManager &state_manager = context->state_manager_get();
|
||||
state_manager.unbind_from_all_namespaces(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void VKBindableResource::unbind_from_all_contexts()
|
||||
{
|
||||
for (const VKContext &context : VKBackend::get().device_get().contexts_get()) {
|
||||
VKStateManager &state_manager = context.state_manager_get();
|
||||
state_manager.unbind_from_all_namespaces(*this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
|
@ -0,0 +1,92 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_array.hh"
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/**
|
||||
* Super class for resources that can be bound to a shader.
|
||||
*/
|
||||
class VKBindableResource {
|
||||
protected:
|
||||
virtual ~VKBindableResource();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Bind the resource to the shader.
|
||||
*/
|
||||
virtual void bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type) = 0;
|
||||
|
||||
protected:
|
||||
void unbind_from_active_context();
|
||||
|
||||
private:
|
||||
void unbind_from_all_contexts();
|
||||
};
|
||||
|
||||
/**
|
||||
* Blender binds resources at context level (VKStateManager). The bindings are organized in
|
||||
* namespaces.
|
||||
*/
|
||||
template<shader::ShaderCreateInfo::Resource::BindType BindType, int MaxBindings = 16>
|
||||
class VKBindingNamespace {
|
||||
Array<VKBindableResource *> bindings_ = Array<VKBindableResource *>(MaxBindings);
|
||||
|
||||
public:
|
||||
VKBindingNamespace()
|
||||
{
|
||||
bindings_.fill(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a binding to this namespace.
|
||||
*/
|
||||
void bind(int binding, VKBindableResource &resource)
|
||||
{
|
||||
bindings_[binding] = &resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply registered bindings to the active shader.
|
||||
*/
|
||||
void apply_bindings()
|
||||
{
|
||||
for (int binding : IndexRange(MaxBindings)) {
|
||||
if (bindings_[binding] != nullptr) {
|
||||
bindings_[binding]->bind(binding, BindType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the given resource from this namespace.
|
||||
*/
|
||||
void unbind(VKBindableResource &resource)
|
||||
{
|
||||
for (int binding : IndexRange(MaxBindings)) {
|
||||
if (bindings_[binding] == &resource) {
|
||||
bindings_[binding] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all bindings from this namespace.
|
||||
*/
|
||||
void unbind_all()
|
||||
{
|
||||
bindings_.fill(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
|
@ -23,14 +23,8 @@ VKStateManager::VKStateManager()
|
|||
{
|
||||
sampler_.create();
|
||||
constexpr int max_bindings = 16;
|
||||
image_bindings_ = Array<ImageBinding>(max_bindings);
|
||||
image_bindings_.fill(ImageBinding());
|
||||
texture_bindings_ = Array<TextureBinding>(max_bindings);
|
||||
texture_bindings_.fill(TextureBinding());
|
||||
uniform_buffer_bindings_ = Array<UniformBufferBinding>(max_bindings);
|
||||
uniform_buffer_bindings_.fill(UniformBufferBinding());
|
||||
storage_buffer_bindings_ = Array<StorageBufferBinding>(max_bindings);
|
||||
storage_buffer_bindings_.fill(StorageBufferBinding());
|
||||
}
|
||||
|
||||
void VKStateManager::apply_state()
|
||||
|
@ -47,11 +41,6 @@ void VKStateManager::apply_bindings()
|
|||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
if (context.shader) {
|
||||
for (int binding : IndexRange(image_bindings_.size())) {
|
||||
if (image_bindings_[binding].texture) {
|
||||
image_bindings_[binding].texture->image_bind(binding);
|
||||
}
|
||||
}
|
||||
|
||||
for (int binding : IndexRange(texture_bindings_.size())) {
|
||||
if (texture_bindings_[binding].texture) {
|
||||
|
@ -63,27 +52,9 @@ void VKStateManager::apply_bindings()
|
|||
}
|
||||
}
|
||||
|
||||
for (int binding : IndexRange(uniform_buffer_bindings_.size())) {
|
||||
if (uniform_buffer_bindings_[binding].buffer) {
|
||||
uniform_buffer_bindings_[binding].buffer->bind(
|
||||
binding, shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
for (int binding : IndexRange(storage_buffer_bindings_.size())) {
|
||||
if (storage_buffer_bindings_[binding].storage_buffer) {
|
||||
storage_buffer_bindings_[binding].storage_buffer->bind(
|
||||
binding, shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
}
|
||||
else if (storage_buffer_bindings_[binding].vertex_buffer) {
|
||||
storage_buffer_bindings_[binding].vertex_buffer->bind(
|
||||
binding, shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
}
|
||||
else if (storage_buffer_bindings_[binding].index_buffer) {
|
||||
storage_buffer_bindings_[binding].index_buffer->bind(
|
||||
binding, shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
}
|
||||
}
|
||||
image_bindings_.apply_bindings();
|
||||
uniform_buffer_bindings_.apply_bindings();
|
||||
storage_buffer_bindings_.apply_bindings();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,38 +103,35 @@ void VKStateManager::texture_unbind_all()
|
|||
void VKStateManager::image_bind(Texture *tex, int binding)
|
||||
{
|
||||
VKTexture *texture = unwrap(tex);
|
||||
image_bindings_[binding].texture = texture;
|
||||
image_bindings_.bind(binding, *texture);
|
||||
}
|
||||
|
||||
void VKStateManager::image_unbind(Texture *tex)
|
||||
{
|
||||
VKTexture *texture = unwrap(tex);
|
||||
for (ImageBinding &binding : image_bindings_) {
|
||||
if (binding.texture == texture) {
|
||||
binding.texture = nullptr;
|
||||
}
|
||||
}
|
||||
image_bindings_.unbind(*texture);
|
||||
}
|
||||
|
||||
void VKStateManager::image_unbind_all()
|
||||
{
|
||||
for (ImageBinding &binding : image_bindings_) {
|
||||
binding.texture = nullptr;
|
||||
}
|
||||
image_bindings_.unbind_all();
|
||||
}
|
||||
|
||||
void VKStateManager::uniform_buffer_bind(VKUniformBuffer *uniform_buffer, int slot)
|
||||
{
|
||||
uniform_buffer_bindings_[slot].buffer = uniform_buffer;
|
||||
uniform_buffer_bindings_.bind(slot, *uniform_buffer);
|
||||
}
|
||||
|
||||
void VKStateManager::uniform_buffer_unbind(VKUniformBuffer *uniform_buffer)
|
||||
{
|
||||
for (UniformBufferBinding &binding : uniform_buffer_bindings_) {
|
||||
if (binding.buffer == uniform_buffer) {
|
||||
binding.buffer = nullptr;
|
||||
}
|
||||
}
|
||||
uniform_buffer_bindings_.unbind(*uniform_buffer);
|
||||
}
|
||||
|
||||
void VKStateManager::unbind_from_all_namespaces(VKBindableResource &resource)
|
||||
{
|
||||
uniform_buffer_bindings_.unbind(resource);
|
||||
storage_buffer_bindings_.unbind(resource);
|
||||
image_bindings_.unbind(resource);
|
||||
}
|
||||
|
||||
void VKStateManager::texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot)
|
||||
|
@ -182,52 +150,14 @@ void VKStateManager::texel_buffer_unbind(VKVertexBuffer *vertex_buffer)
|
|||
}
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_bind(VKStorageBuffer *storage_buffer, int slot)
|
||||
void VKStateManager::storage_buffer_bind(VKBindableResource &resource, int slot)
|
||||
{
|
||||
storage_buffer_bindings_[slot].storage_buffer = storage_buffer;
|
||||
storage_buffer_bindings_[slot].vertex_buffer = nullptr;
|
||||
storage_buffer_bindings_[slot].index_buffer = nullptr;
|
||||
storage_buffer_bindings_.bind(slot, resource);
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_bind(VKVertexBuffer *vertex_buffer, int slot)
|
||||
void VKStateManager::storage_buffer_unbind(VKBindableResource &resource)
|
||||
{
|
||||
storage_buffer_bindings_[slot].storage_buffer = nullptr;
|
||||
storage_buffer_bindings_[slot].vertex_buffer = vertex_buffer;
|
||||
storage_buffer_bindings_[slot].index_buffer = nullptr;
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_bind(VKIndexBuffer *index_buffer, int slot)
|
||||
{
|
||||
storage_buffer_bindings_[slot].storage_buffer = nullptr;
|
||||
storage_buffer_bindings_[slot].vertex_buffer = nullptr;
|
||||
storage_buffer_bindings_[slot].index_buffer = index_buffer;
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_unbind(VKStorageBuffer *storage_buffer)
|
||||
{
|
||||
for (StorageBufferBinding &binding : storage_buffer_bindings_) {
|
||||
if (binding.storage_buffer == storage_buffer) {
|
||||
binding.storage_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_unbind(VKVertexBuffer *vertex_buffer)
|
||||
{
|
||||
for (StorageBufferBinding &binding : storage_buffer_bindings_) {
|
||||
if (binding.vertex_buffer == vertex_buffer) {
|
||||
binding.vertex_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VKStateManager::storage_buffer_unbind(VKIndexBuffer *index_buffer)
|
||||
{
|
||||
for (StorageBufferBinding &binding : storage_buffer_bindings_) {
|
||||
if (binding.index_buffer == index_buffer) {
|
||||
binding.index_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
storage_buffer_bindings_.unbind(resource);
|
||||
}
|
||||
|
||||
void VKStateManager::texture_unpack_row_length_set(uint len)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "BLI_array.hh"
|
||||
|
||||
#include "vk_resource_bindable.hh"
|
||||
#include "vk_sampler.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
@ -35,18 +36,12 @@ class VKStateManager : public StateManager {
|
|||
struct ImageBinding {
|
||||
VKTexture *texture = nullptr;
|
||||
};
|
||||
struct UniformBufferBinding {
|
||||
VKUniformBuffer *buffer = nullptr;
|
||||
};
|
||||
struct StorageBufferBinding {
|
||||
VKStorageBuffer *storage_buffer = nullptr;
|
||||
VKVertexBuffer *vertex_buffer = nullptr;
|
||||
VKIndexBuffer *index_buffer = nullptr;
|
||||
};
|
||||
Array<ImageBinding> image_bindings_;
|
||||
Array<TextureBinding> texture_bindings_;
|
||||
Array<UniformBufferBinding> uniform_buffer_bindings_;
|
||||
Array<StorageBufferBinding> storage_buffer_bindings_;
|
||||
VKBindingNamespace<shader::ShaderCreateInfo::Resource::BindType::IMAGE> image_bindings_;
|
||||
VKBindingNamespace<shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER>
|
||||
uniform_buffer_bindings_;
|
||||
VKBindingNamespace<shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER>
|
||||
storage_buffer_bindings_;
|
||||
|
||||
public:
|
||||
VKStateManager();
|
||||
|
@ -73,12 +68,10 @@ class VKStateManager : public StateManager {
|
|||
void texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot);
|
||||
void texel_buffer_unbind(VKVertexBuffer *vertex_buffer);
|
||||
|
||||
void storage_buffer_bind(VKStorageBuffer *storage_buffer, int slot);
|
||||
void storage_buffer_bind(VKVertexBuffer *vertex_buffer, int slot);
|
||||
void storage_buffer_bind(VKIndexBuffer *index_buffer, int slot);
|
||||
void storage_buffer_unbind(VKStorageBuffer *storage_buffer);
|
||||
void storage_buffer_unbind(VKVertexBuffer *vertex_buffer);
|
||||
void storage_buffer_unbind(VKIndexBuffer *index_buffer);
|
||||
void storage_buffer_bind(VKBindableResource &resource, int slot);
|
||||
void storage_buffer_unbind(VKBindableResource &resource);
|
||||
|
||||
void unbind_from_all_namespaces(VKBindableResource &bindable_resource);
|
||||
|
||||
void texture_unpack_row_length_set(uint len) override;
|
||||
|
||||
|
|
|
@ -19,11 +19,6 @@ VKStorageBuffer::VKStorageBuffer(int size, GPUUsageType usage, const char *name)
|
|||
{
|
||||
}
|
||||
|
||||
VKStorageBuffer::~VKStorageBuffer()
|
||||
{
|
||||
unbind();
|
||||
}
|
||||
|
||||
void VKStorageBuffer::update(const void *data)
|
||||
{
|
||||
ensure_allocated();
|
||||
|
@ -50,7 +45,7 @@ void VKStorageBuffer::allocate()
|
|||
void VKStorageBuffer::bind(int slot)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
context.state_manager_get().storage_buffer_bind(this, slot);
|
||||
context.state_manager_get().storage_buffer_bind(*this, slot);
|
||||
}
|
||||
|
||||
void VKStorageBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
|
@ -68,7 +63,7 @@ void VKStorageBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindTyp
|
|||
|
||||
void VKStorageBuffer::unbind()
|
||||
{
|
||||
VKBackend::get().device_get().unbind(*this);
|
||||
unbind_from_active_context();
|
||||
}
|
||||
|
||||
void VKStorageBuffer::clear(uint32_t clear_value)
|
||||
|
|
|
@ -14,21 +14,21 @@
|
|||
#include "gpu_vertex_buffer_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_resource_bindable.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VertBuf;
|
||||
|
||||
class VKStorageBuffer : public StorageBuf {
|
||||
class VKStorageBuffer : public StorageBuf, public VKBindableResource {
|
||||
GPUUsageType usage_;
|
||||
VKBuffer buffer_;
|
||||
|
||||
public:
|
||||
VKStorageBuffer(int size, GPUUsageType usage, const char *name);
|
||||
virtual ~VKStorageBuffer();
|
||||
|
||||
void update(const void *data) override;
|
||||
void bind(int slot) override;
|
||||
void bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type);
|
||||
void bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type) override;
|
||||
void unbind() override;
|
||||
void clear(uint32_t clear_value) override;
|
||||
void copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) override;
|
||||
|
|
|
@ -483,7 +483,7 @@ void VKTexture::bind(int unit, VKSampler &sampler)
|
|||
}
|
||||
}
|
||||
|
||||
void VKTexture::image_bind(int binding)
|
||||
void VKTexture::bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
{
|
||||
if (!is_allocated()) {
|
||||
allocate();
|
||||
|
@ -492,8 +492,7 @@ void VKTexture::image_bind(int binding)
|
|||
VKShader *shader = static_cast<VKShader *>(context.shader);
|
||||
const VKShaderInterface &shader_interface = shader->interface_get();
|
||||
const std::optional<VKDescriptorSet::Location> location =
|
||||
shader_interface.descriptor_set_location(shader::ShaderCreateInfo::Resource::BindType::IMAGE,
|
||||
binding);
|
||||
shader_interface.descriptor_set_location(bind_type, binding);
|
||||
if (location) {
|
||||
VKDescriptorSetTracker &descriptor_set = shader->pipeline_get().descriptor_set_get();
|
||||
descriptor_set.image_bind(*this, *location);
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
|
||||
#include "vk_context.hh"
|
||||
#include "vk_image_view.hh"
|
||||
#include "vk_resource_bindable.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKSampler;
|
||||
|
||||
class VKTexture : public Texture {
|
||||
class VKTexture : public Texture, public VKBindableResource {
|
||||
VkImage vk_image_ = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation_ = VK_NULL_HANDLE;
|
||||
|
||||
|
@ -61,7 +62,7 @@ class VKTexture : public Texture {
|
|||
uint gl_bindcode_get() const override;
|
||||
|
||||
void bind(int unit, VKSampler &sampler);
|
||||
void image_bind(int location);
|
||||
void bind(int location, shader::ShaderCreateInfo::Resource::BindType bind_type) override;
|
||||
|
||||
VkImage vk_image_handle() const
|
||||
{
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKUniformBuffer::~VKUniformBuffer()
|
||||
{
|
||||
unbind();
|
||||
}
|
||||
|
||||
void VKUniformBuffer::update(const void *data)
|
||||
{
|
||||
if (!buffer_.is_allocated()) {
|
||||
|
@ -55,25 +50,36 @@ void VKUniformBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindTyp
|
|||
shader_interface.descriptor_set_location(bind_type, slot);
|
||||
if (location) {
|
||||
VKDescriptorSetTracker &descriptor_set = shader->pipeline_get().descriptor_set_get();
|
||||
descriptor_set.bind(*this, *location);
|
||||
/* TODO: move to descriptor set. */
|
||||
if (bind_type == shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
|
||||
descriptor_set.bind(*this, *location);
|
||||
}
|
||||
else {
|
||||
descriptor_set.bind_as_ssbo(*this, *location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VKUniformBuffer::bind(int slot)
|
||||
{
|
||||
/* Uniform buffers can be bound without an shader. */
|
||||
VKContext &context = *VKContext::get();
|
||||
context.state_manager_get().uniform_buffer_bind(this, slot);
|
||||
}
|
||||
|
||||
void VKUniformBuffer::bind_as_ssbo(int slot)
|
||||
{
|
||||
bind(slot, shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
VKContext &context = *VKContext::get();
|
||||
context.state_manager_get().storage_buffer_bind(*this, slot);
|
||||
}
|
||||
|
||||
void VKUniformBuffer::unbind()
|
||||
{
|
||||
VKBackend::get().device_get().unbind(*this);
|
||||
const VKContext *context = VKContext::get();
|
||||
if (context != nullptr) {
|
||||
VKStateManager &state_manager = context->state_manager_get();
|
||||
state_manager.uniform_buffer_unbind(this);
|
||||
state_manager.storage_buffer_unbind(*this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -13,21 +13,24 @@
|
|||
#include "gpu_uniform_buffer_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_resource_bindable.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKUniformBuffer : public UniformBuf, NonCopyable {
|
||||
class VKUniformBuffer : public UniformBuf, public VKBindableResource, NonCopyable {
|
||||
VKBuffer buffer_;
|
||||
|
||||
public:
|
||||
VKUniformBuffer(int size, const char *name) : UniformBuf(size, name) {}
|
||||
~VKUniformBuffer();
|
||||
|
||||
void update(const void *data) override;
|
||||
void clear_to_zero() override;
|
||||
void bind(int slot) override;
|
||||
void bind_as_ssbo(int slot) override;
|
||||
void bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type);
|
||||
|
||||
/**
|
||||
* Unbind uniform buffer from active context.
|
||||
*/
|
||||
void unbind() override;
|
||||
|
||||
VkBuffer vk_handle() const
|
||||
|
@ -40,6 +43,9 @@ class VKUniformBuffer : public UniformBuf, NonCopyable {
|
|||
return size_in_bytes_;
|
||||
}
|
||||
|
||||
/* Bindable resource */
|
||||
void bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type) override;
|
||||
|
||||
private:
|
||||
void allocate();
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@ void VKVertexBuffer::bind_as_ssbo(uint binding)
|
|||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
VKStateManager &state_manager = context.state_manager_get();
|
||||
state_manager.storage_buffer_bind(this, binding);
|
||||
state_manager.storage_buffer_bind(*this, binding);
|
||||
}
|
||||
|
||||
void VKVertexBuffer::bind_as_texture(uint binding)
|
||||
|
@ -36,7 +36,7 @@ void VKVertexBuffer::bind_as_texture(uint binding)
|
|||
state_manager.texel_buffer_bind(this, binding);
|
||||
}
|
||||
|
||||
void VKVertexBuffer::bind(uint binding, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
void VKVertexBuffer::bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
VKShader *shader = static_cast<VKShader *>(context.shader);
|
||||
|
@ -117,10 +117,8 @@ void VKVertexBuffer::resize_data()
|
|||
|
||||
void VKVertexBuffer::release_data()
|
||||
{
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
device.unbind(*this);
|
||||
|
||||
if (vk_buffer_view_ != VK_NULL_HANDLE) {
|
||||
const VKDevice &device = VKBackend::get().device_get();
|
||||
VK_ALLOCATION_CALLBACKS;
|
||||
vkDestroyBufferView(device.device_get(), vk_buffer_view_, vk_allocation_callbacks);
|
||||
vk_buffer_view_ = VK_NULL_HANDLE;
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
#include "gpu_vertex_buffer_private.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_resource_bindable.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKVertexBuffer : public VertBuf {
|
||||
class VKVertexBuffer : public VertBuf, public VKBindableResource {
|
||||
VKBuffer buffer_;
|
||||
/** When a vertex buffer is used as a UNIFORM_TEXEL_BUFFER the buffer requires a buffer view. */
|
||||
VkBufferView vk_buffer_view_ = VK_NULL_HANDLE;
|
||||
|
@ -24,7 +25,7 @@ class VKVertexBuffer : public VertBuf {
|
|||
|
||||
void bind_as_ssbo(uint binding) override;
|
||||
void bind_as_texture(uint binding) override;
|
||||
void bind(uint binding, shader::ShaderCreateInfo::Resource::BindType bind_type);
|
||||
void bind(int binding, shader::ShaderCreateInfo::Resource::BindType bind_type) override;
|
||||
void wrap_handle(uint64_t handle) override;
|
||||
|
||||
void update_sub(uint start, uint len, const void *data) override;
|
||||
|
|
Loading…
Reference in New Issue