WIP: Vulkan: Workbench #107886
|
@ -17,6 +17,7 @@
|
||||||
#include "vk_pixel_buffer.hh"
|
#include "vk_pixel_buffer.hh"
|
||||||
#include "vk_query.hh"
|
#include "vk_query.hh"
|
||||||
#include "vk_shader.hh"
|
#include "vk_shader.hh"
|
||||||
|
#include "vk_state_manager.hh"
|
||||||
#include "vk_storage_buffer.hh"
|
#include "vk_storage_buffer.hh"
|
||||||
#include "vk_texture.hh"
|
#include "vk_texture.hh"
|
||||||
#include "vk_uniform_buffer.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)
|
void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len)
|
||||||
{
|
{
|
||||||
VKContext &context = *VKContext::get();
|
VKContext &context = *VKContext::get();
|
||||||
|
context.state_manager_get().apply_bindings();
|
||||||
context.bind_compute_pipeline();
|
context.bind_compute_pipeline();
|
||||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||||
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "vk_context.hh"
|
#include "vk_context.hh"
|
||||||
#include "vk_index_buffer.hh"
|
#include "vk_index_buffer.hh"
|
||||||
|
#include "vk_state_manager.hh"
|
||||||
#include "vk_vertex_attribute_object.hh"
|
#include "vk_vertex_attribute_object.hh"
|
||||||
#include "vk_vertex_buffer.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 */
|
/* Finalize graphics pipeline */
|
||||||
VKContext &context = *VKContext::get();
|
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;
|
VKVertexAttributeObject vao;
|
||||||
vao.update_bindings(context, *this);
|
vao.update_bindings(context, *this);
|
||||||
context.bind_graphics_pipeline(prim_type, vao);
|
context.bind_graphics_pipeline(prim_type, vao);
|
||||||
|
|
|
@ -58,15 +58,6 @@ void VKDescriptorSetTracker::bind_as_ssbo(VKVertexBuffer &buffer,
|
||||||
binding.buffer_size = buffer.size_used_get();
|
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,
|
void VKDescriptorSetTracker::bind(VKUniformBuffer &buffer,
|
||||||
const VKDescriptorSet::Location location)
|
const VKDescriptorSet::Location location)
|
||||||
{
|
{
|
||||||
|
@ -103,6 +94,15 @@ void VKDescriptorSetTracker::bind(VKTexture &texture,
|
||||||
binding.vk_sampler = sampler.vk_handle();
|
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(
|
VKDescriptorSetTracker::Binding &VKDescriptorSetTracker::ensure_location(
|
||||||
const VKDescriptorSet::Location location)
|
const VKDescriptorSet::Location location)
|
||||||
{
|
{
|
||||||
|
|
|
@ -156,13 +156,14 @@ class VKDescriptorSetTracker : protected VKResourceTracker<VKDescriptorSet> {
|
||||||
VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout) {}
|
VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout) {}
|
||||||
|
|
||||||
void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location);
|
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_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location);
|
||||||
void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location);
|
void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location);
|
||||||
void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
|
void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location);
|
||||||
/* TODO: bind as image */
|
/* TODO: bind as image */
|
||||||
void image_bind(VKTexture &texture, VKDescriptorSet::Location location);
|
void image_bind(VKTexture &texture, VKDescriptorSet::Location location);
|
||||||
void bind(VKTexture &texture, VKDescriptorSet::Location location, VKSampler &sampler);
|
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.
|
* Some shaders don't need any descriptor sets so we don't need to bind them.
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "vk_immediate.hh"
|
#include "vk_immediate.hh"
|
||||||
#include "vk_data_conversion.hh"
|
#include "vk_data_conversion.hh"
|
||||||
|
#include "vk_state_manager.hh"
|
||||||
|
|
||||||
namespace blender::gpu {
|
namespace blender::gpu {
|
||||||
|
|
||||||
|
@ -47,7 +48,9 @@ void VKImmediate::end()
|
||||||
|
|
||||||
VKContext &context = *VKContext::get();
|
VKContext &context = *VKContext::get();
|
||||||
BLI_assert(context.shader == unwrap(shader));
|
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);
|
vertex_attributes_.update_bindings(*this);
|
||||||
context.bind_graphics_pipeline(prim_type, vertex_attributes_);
|
context.bind_graphics_pipeline(prim_type, vertex_attributes_);
|
||||||
vertex_attributes_.bind(context);
|
vertex_attributes_.bind(context);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "vk_pipeline.hh"
|
#include "vk_pipeline.hh"
|
||||||
#include "vk_shader.hh"
|
#include "vk_shader.hh"
|
||||||
#include "vk_texture.hh"
|
#include "vk_texture.hh"
|
||||||
|
#include "vk_vertex_buffer.hh"
|
||||||
|
|
||||||
#include "GPU_capabilities.h"
|
#include "GPU_capabilities.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ VKStateManager::VKStateManager()
|
||||||
texture_bindings_.fill(ImageBinding());
|
texture_bindings_.fill(ImageBinding());
|
||||||
uniform_buffer_bindings_ = Array<UniformBufferBinding>(max_bindings);
|
uniform_buffer_bindings_ = Array<UniformBufferBinding>(max_bindings);
|
||||||
uniform_buffer_bindings_.fill(UniformBufferBinding());
|
uniform_buffer_bindings_.fill(UniformBufferBinding());
|
||||||
|
uniform_texel_buffer_bindings_ = Array<UniformTexelBufferBinding>(max_bindings);
|
||||||
|
uniform_texel_buffer_bindings_.fill(UniformTexelBufferBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKStateManager::apply_state()
|
void VKStateManager::apply_state()
|
||||||
|
@ -34,7 +37,13 @@ void VKStateManager::apply_state()
|
||||||
VKShader &shader = unwrap(*context.shader);
|
VKShader &shader = unwrap(*context.shader);
|
||||||
VKPipeline &pipeline = shader.pipeline_get();
|
VKPipeline &pipeline = shader.pipeline_get();
|
||||||
pipeline.state_manager_get().set_state(state, mutable_state);
|
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())) {
|
for (int binding : IndexRange(image_bindings_.size())) {
|
||||||
if (image_bindings_[binding].texture == nullptr) {
|
if (image_bindings_[binding].texture == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -42,13 +51,20 @@ void VKStateManager::apply_state()
|
||||||
image_bindings_[binding].texture->image_bind(binding);
|
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) {
|
if (texture_bindings_[binding].texture == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
texture_bindings_[binding].texture->bind(binding, sampler_);
|
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())) {
|
for (int binding : IndexRange(uniform_buffer_bindings_.size())) {
|
||||||
if (uniform_buffer_bindings_[binding].buffer == nullptr) {
|
if (uniform_buffer_bindings_[binding].buffer == nullptr) {
|
||||||
continue;
|
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)
|
void VKStateManager::texture_unpack_row_length_set(uint len)
|
||||||
{
|
{
|
||||||
texture_unpack_row_length_ = len;
|
texture_unpack_row_length_ = len;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
namespace blender::gpu {
|
namespace blender::gpu {
|
||||||
class VKTexture;
|
class VKTexture;
|
||||||
class VKUniformBuffer;
|
class VKUniformBuffer;
|
||||||
|
class VKVertexBuffer;
|
||||||
|
|
||||||
class VKStateManager : public StateManager {
|
class VKStateManager : public StateManager {
|
||||||
/* Dummy sampler for now.*/
|
/* Dummy sampler for now.*/
|
||||||
|
@ -29,9 +30,13 @@ class VKStateManager : public StateManager {
|
||||||
struct UniformBufferBinding {
|
struct UniformBufferBinding {
|
||||||
VKUniformBuffer *buffer = nullptr;
|
VKUniformBuffer *buffer = nullptr;
|
||||||
};
|
};
|
||||||
|
struct UniformTexelBufferBinding {
|
||||||
|
VKVertexBuffer *vertex_buffer = nullptr;
|
||||||
|
};
|
||||||
Array<ImageBinding> image_bindings_;
|
Array<ImageBinding> image_bindings_;
|
||||||
Array<ImageBinding> texture_bindings_;
|
Array<ImageBinding> texture_bindings_;
|
||||||
Array<UniformBufferBinding> uniform_buffer_bindings_;
|
Array<UniformBufferBinding> uniform_buffer_bindings_;
|
||||||
|
Array<UniformTexelBufferBinding> uniform_texel_buffer_bindings_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VKStateManager();
|
VKStateManager();
|
||||||
|
@ -41,6 +46,9 @@ class VKStateManager : public StateManager {
|
||||||
|
|
||||||
void issue_barrier(eGPUBarrier barrier_bits) override;
|
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_bind(Texture *tex, GPUSamplerState sampler, int unit) override;
|
||||||
void texture_unbind(Texture *tex) override;
|
void texture_unbind(Texture *tex) override;
|
||||||
void texture_unbind_all() 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_bind(VKUniformBuffer *uniform_buffer, int slot);
|
||||||
void uniform_buffer_unbind(VKUniformBuffer *uniform_buffer);
|
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;
|
void texture_unpack_row_length_set(uint len) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "vk_data_conversion.hh"
|
#include "vk_data_conversion.hh"
|
||||||
#include "vk_shader.hh"
|
#include "vk_shader.hh"
|
||||||
#include "vk_shader_interface.hh"
|
#include "vk_shader_interface.hh"
|
||||||
|
#include "vk_state_manager.hh"
|
||||||
#include "vk_vertex_buffer.hh"
|
#include "vk_vertex_buffer.hh"
|
||||||
|
|
||||||
namespace blender::gpu {
|
namespace blender::gpu {
|
||||||
|
@ -37,9 +38,15 @@ void VKVertexBuffer::bind_as_ssbo(uint binding)
|
||||||
|
|
||||||
void VKVertexBuffer::bind_as_texture(uint binding)
|
void VKVertexBuffer::bind_as_texture(uint binding)
|
||||||
{
|
{
|
||||||
if (!buffer_.is_allocated()) {
|
VKContext &context = *VKContext::get();
|
||||||
allocate();
|
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();
|
VKContext &context = *VKContext::get();
|
||||||
VKShader *shader = static_cast<VKShader *>(context.shader);
|
VKShader *shader = static_cast<VKShader *>(context.shader);
|
||||||
|
@ -47,8 +54,8 @@ void VKVertexBuffer::bind_as_texture(uint binding)
|
||||||
const std::optional<VKDescriptorSet::Location> location =
|
const std::optional<VKDescriptorSet::Location> location =
|
||||||
shader_interface.descriptor_set_location(
|
shader_interface.descriptor_set_location(
|
||||||
shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding);
|
shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding);
|
||||||
BLI_assert_msg(location, "Locations to texel buffers should always exist.");
|
BLI_assert_msg(location, "Locations to Texel buffers should always exist.");
|
||||||
shader->pipeline_get().descriptor_set_get().bind_as_texture(*this, *location);
|
shader->pipeline_get().descriptor_set_get().bind(*this, *location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
|
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
|
||||||
|
@ -92,6 +99,11 @@ void VKVertexBuffer::resize_data()
|
||||||
|
|
||||||
void VKVertexBuffer::release_data()
|
void VKVertexBuffer::release_data()
|
||||||
{
|
{
|
||||||
|
if (should_unbind_) {
|
||||||
|
VKContext &context = *VKContext::get();
|
||||||
|
context.state_manager_get().texel_buffer_unbind(this);
|
||||||
|
}
|
||||||
|
|
||||||
MEM_SAFE_FREE(data);
|
MEM_SAFE_FREE(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,14 @@ class VKTexture;
|
||||||
|
|
||||||
class VKVertexBuffer : public VertBuf {
|
class VKVertexBuffer : public VertBuf {
|
||||||
VKBuffer buffer_;
|
VKBuffer buffer_;
|
||||||
|
bool should_unbind_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~VKVertexBuffer();
|
~VKVertexBuffer();
|
||||||
|
|
||||||
void bind_as_ssbo(uint binding) override;
|
void bind_as_ssbo(uint binding) override;
|
||||||
void bind_as_texture(uint binding) override;
|
void bind_as_texture(uint binding) override;
|
||||||
|
void bind(uint binding);
|
||||||
void wrap_handle(uint64_t handle) override;
|
void wrap_handle(uint64_t handle) override;
|
||||||
|
|
||||||
void update_sub(uint start, uint len, const void *data) override;
|
void update_sub(uint start, uint len, const void *data) override;
|
||||||
|
|
Loading…
Reference in New Issue