WIP: Vulkan: Workbench #107886

Closed
Jeroen Bakker wants to merge 88 commits from Jeroen-Bakker:vulkan-draw-manager-workbench into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
9 changed files with 82 additions and 18 deletions
Showing only changes of commit adc1cb6eee - Show all commits

View File

@ -17,6 +17,7 @@
#include "vk_pixel_buffer.hh"
#include "vk_query.hh"
#include "vk_shader.hh"
#include "vk_state_manager.hh"
#include "vk_storage_buffer.hh"
#include "vk_texture.hh"
#include "vk_uniform_buffer.hh"
@ -64,6 +65,7 @@ void VKBackend::samplers_update() {}
void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len)
{
VKContext &context = *VKContext::get();
context.state_manager_get().apply_bindings();
context.bind_compute_pipeline();
VKCommandBuffer &command_buffer = context.command_buffer_get();
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);

View File

@ -9,6 +9,7 @@
#include "vk_context.hh"
#include "vk_index_buffer.hh"
#include "vk_state_manager.hh"
#include "vk_vertex_attribute_object.hh"
#include "vk_vertex_buffer.hh"
@ -22,7 +23,9 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i
/* Finalize graphics pipeline */
VKContext &context = *VKContext::get();
context.state_manager->apply_state();
VKStateManager &state_manager = context.state_manager_get();
state_manager.apply_state();
state_manager.apply_bindings();
VKVertexAttributeObject vao;
vao.update_bindings(context, *this);
context.bind_graphics_pipeline(prim_type, vao);

View File

@ -58,15 +58,6 @@ void VKDescriptorSetTracker::bind_as_ssbo(VKVertexBuffer &buffer,
binding.buffer_size = buffer.size_used_get();
}
void VKDescriptorSetTracker::bind_as_texture(VKVertexBuffer &buffer,
const VKDescriptorSet::Location location)
{
Binding &binding = ensure_location(location);
binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
binding.vk_buffer = buffer.vk_handle();
binding.buffer_size = buffer.size_used_get();
}
void VKDescriptorSetTracker::bind(VKUniformBuffer &buffer,
const VKDescriptorSet::Location location)
{
@ -103,6 +94,15 @@ void VKDescriptorSetTracker::bind(VKTexture &texture,
binding.vk_sampler = sampler.vk_handle();
}
void VKDescriptorSetTracker::bind(VKVertexBuffer &vertex_buffer,
const VKDescriptorSet::Location location)
{
Binding &binding = ensure_location(location);
binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
binding.vk_buffer = vertex_buffer.vk_handle();
binding.buffer_size = vertex_buffer.size_alloc_get();
}
VKDescriptorSetTracker::Binding &VKDescriptorSetTracker::ensure_location(
const VKDescriptorSet::Location location)
{

View File

@ -156,13 +156,14 @@ class VKDescriptorSetTracker : protected VKResourceTracker<VKDescriptorSet> {
VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout) {}
void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location);
void bind_as_texture(VKVertexBuffer &buffer, VKDescriptorSet::Location location);
void bind_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location);
void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location);
void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
/* TODO: bind as image */
void image_bind(VKTexture &texture, VKDescriptorSet::Location location);
void bind(VKTexture &texture, VKDescriptorSet::Location location, VKSampler &sampler);
/* Bind as uniform texel buffer. */
void bind(VKVertexBuffer &vertex_buffer, VKDescriptorSet::Location location);
/**
* Some shaders don't need any descriptor sets so we don't need to bind them.

View File

@ -9,6 +9,7 @@
#include "vk_immediate.hh"
#include "vk_data_conversion.hh"
#include "vk_state_manager.hh"
namespace blender::gpu {
@ -47,7 +48,9 @@ void VKImmediate::end()
VKContext &context = *VKContext::get();
BLI_assert(context.shader == unwrap(shader));
context.state_manager->apply_state();
VKStateManager &state_manager = context.state_manager_get();
state_manager.apply_state();
state_manager.apply_bindings();
vertex_attributes_.update_bindings(*this);
context.bind_graphics_pipeline(prim_type, vertex_attributes_);
vertex_attributes_.bind(context);

View File

@ -10,6 +10,7 @@
#include "vk_pipeline.hh"
#include "vk_shader.hh"
#include "vk_texture.hh"
#include "vk_vertex_buffer.hh"
#include "GPU_capabilities.h"
@ -25,6 +26,8 @@ VKStateManager::VKStateManager()
texture_bindings_.fill(ImageBinding());
uniform_buffer_bindings_ = Array<UniformBufferBinding>(max_bindings);
uniform_buffer_bindings_.fill(UniformBufferBinding());
uniform_texel_buffer_bindings_ = Array<UniformTexelBufferBinding>(max_bindings);
uniform_texel_buffer_bindings_.fill(UniformTexelBufferBinding());
}
void VKStateManager::apply_state()
@ -34,7 +37,13 @@ void VKStateManager::apply_state()
VKShader &shader = unwrap(*context.shader);
VKPipeline &pipeline = shader.pipeline_get();
pipeline.state_manager_get().set_state(state, mutable_state);
}
}
void VKStateManager::apply_bindings()
{
VKContext &context = *VKContext::get();
if (context.shader) {
for (int binding : IndexRange(image_bindings_.size())) {
if (image_bindings_[binding].texture == nullptr) {
continue;
@ -42,13 +51,20 @@ void VKStateManager::apply_state()
image_bindings_[binding].texture->image_bind(binding);
}
for (int binding : IndexRange(image_bindings_.size())) {
for (int binding : IndexRange(texture_bindings_.size())) {
if (texture_bindings_[binding].texture == nullptr) {
continue;
}
texture_bindings_[binding].texture->bind(binding, sampler_);
}
for (int binding : IndexRange(uniform_texel_buffer_bindings_.size())) {
if (uniform_texel_buffer_bindings_[binding].vertex_buffer == nullptr) {
continue;
}
uniform_texel_buffer_bindings_[binding].vertex_buffer->bind(binding);
}
for (int binding : IndexRange(uniform_buffer_bindings_.size())) {
if (uniform_buffer_bindings_[binding].buffer == nullptr) {
continue;
@ -141,6 +157,20 @@ void VKStateManager::uniform_buffer_unbind(VKUniformBuffer *uniform_buffer)
}
}
void VKStateManager::texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot)
{
uniform_texel_buffer_bindings_[slot].vertex_buffer = vertex_buffer;
}
void VKStateManager::texel_buffer_unbind(VKVertexBuffer *vertex_buffer)
{
for (UniformTexelBufferBinding &binding : uniform_texel_buffer_bindings_) {
if (binding.vertex_buffer == vertex_buffer) {
binding.vertex_buffer = nullptr;
}
}
}
void VKStateManager::texture_unpack_row_length_set(uint len)
{
texture_unpack_row_length_ = len;

View File

@ -16,6 +16,7 @@
namespace blender::gpu {
class VKTexture;
class VKUniformBuffer;
class VKVertexBuffer;
class VKStateManager : public StateManager {
/* Dummy sampler for now.*/
@ -29,9 +30,13 @@ class VKStateManager : public StateManager {
struct UniformBufferBinding {
VKUniformBuffer *buffer = nullptr;
};
struct UniformTexelBufferBinding {
VKVertexBuffer *vertex_buffer = nullptr;
};
Array<ImageBinding> image_bindings_;
Array<ImageBinding> texture_bindings_;
Array<UniformBufferBinding> uniform_buffer_bindings_;
Array<UniformTexelBufferBinding> uniform_texel_buffer_bindings_;
public:
VKStateManager();
@ -41,6 +46,9 @@ class VKStateManager : public StateManager {
void issue_barrier(eGPUBarrier barrier_bits) override;
/** Apply resources to the bindings of the active shader.*/
void apply_bindings();
void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override;
void texture_unbind(Texture *tex) override;
void texture_unbind_all() override;
@ -52,6 +60,9 @@ class VKStateManager : public StateManager {
void uniform_buffer_bind(VKUniformBuffer *uniform_buffer, int slot);
void uniform_buffer_unbind(VKUniformBuffer *uniform_buffer);
void texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot);
void texel_buffer_unbind(VKVertexBuffer *vertex_buffer);
void texture_unpack_row_length_set(uint len) override;
/**

View File

@ -10,6 +10,7 @@
#include "vk_data_conversion.hh"
#include "vk_shader.hh"
#include "vk_shader_interface.hh"
#include "vk_state_manager.hh"
#include "vk_vertex_buffer.hh"
namespace blender::gpu {
@ -37,9 +38,15 @@ void VKVertexBuffer::bind_as_ssbo(uint binding)
void VKVertexBuffer::bind_as_texture(uint binding)
{
if (!buffer_.is_allocated()) {
allocate();
}
VKContext &context = *VKContext::get();
VKStateManager &state_manager = context.state_manager_get();
state_manager.texel_buffer_bind(this, binding);
should_unbind_ = true;
}
void VKVertexBuffer::bind(uint binding)
{
upload_data();
VKContext &context = *VKContext::get();
VKShader *shader = static_cast<VKShader *>(context.shader);
@ -47,8 +54,8 @@ void VKVertexBuffer::bind_as_texture(uint binding)
const std::optional<VKDescriptorSet::Location> location =
shader_interface.descriptor_set_location(
shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding);
BLI_assert_msg(location, "Locations to texel buffers should always exist.");
shader->pipeline_get().descriptor_set_get().bind_as_texture(*this, *location);
BLI_assert_msg(location, "Locations to Texel buffers should always exist.");
shader->pipeline_get().descriptor_set_get().bind(*this, *location);
}
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
@ -92,6 +99,11 @@ void VKVertexBuffer::resize_data()
void VKVertexBuffer::release_data()
{
if (should_unbind_) {
VKContext &context = *VKContext::get();
context.state_manager_get().texel_buffer_unbind(this);
}
MEM_SAFE_FREE(data);
}

View File

@ -16,12 +16,14 @@ class VKTexture;
class VKVertexBuffer : public VertBuf {
VKBuffer buffer_;
bool should_unbind_ = false;
public:
~VKVertexBuffer();
void bind_as_ssbo(uint binding) override;
void bind_as_texture(uint binding) override;
void bind(uint binding);
void wrap_handle(uint64_t handle) override;
void update_sub(uint start, uint len, const void *data) override;