Vulkan: Shader interface access mask #120908
|
@ -140,7 +140,8 @@ 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();
|
||||
render_graph::VKResourceAccessInfo resource_access_info = {};
|
||||
context.state_manager_get().apply_bindings(context, resource_access_info);
|
||||
context.bind_compute_pipeline();
|
||||
VKCommandBuffers &command_buffers = context.command_buffers_get();
|
||||
command_buffers.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
||||
|
@ -150,7 +151,8 @@ void VKBackend::compute_dispatch_indirect(StorageBuf *indirect_buf)
|
|||
{
|
||||
BLI_assert(indirect_buf);
|
||||
VKContext &context = *VKContext::get();
|
||||
context.state_manager_get().apply_bindings();
|
||||
render_graph::VKResourceAccessInfo resource_access_info = {};
|
||||
context.state_manager_get().apply_bindings(context, resource_access_info);
|
||||
context.bind_compute_pipeline();
|
||||
VKStorageBuffer &indirect_buffer = *unwrap(indirect_buf);
|
||||
VKCommandBuffers &command_buffers = context.command_buffers_get();
|
||||
|
|
|
@ -29,7 +29,8 @@ void VKBatch::draw_setup()
|
|||
VKIndexBuffer *index_buffer = index_buffer_get();
|
||||
const bool draw_indexed = index_buffer != nullptr;
|
||||
state_manager.apply_state();
|
||||
state_manager.apply_bindings();
|
||||
render_graph::VKResourceAccessInfo resource_access_info = {};
|
||||
state_manager.apply_bindings(context, resource_access_info);
|
||||
/*
|
||||
* The next statements are order dependent. VBOs and IBOs must be uploaded, before resources can
|
||||
* be bound. Uploading device located buffers flush the graphics pipeline and already bound
|
||||
|
|
|
@ -10,7 +10,52 @@
|
|||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
#include "BLI_utility_mixins.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKDescriptorSetTracker;
|
||||
class VKShaderInterface;
|
||||
|
||||
namespace render_graph {
|
||||
struct VKResourceAccessInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the descriptor set, shader interface is needed when adding state manager bindings to a
|
||||
* descriptor set.
|
||||
*
|
||||
* When adding the bindings to the descriptor set we also record the access flag in
|
||||
* resource_access_info.\
|
||||
*
|
||||
* AddToDescriptorSetContext is a convenience structure so we don't need to pass the references to
|
||||
* the descriptor set, shader interface and resource access info to each method call.
|
||||
*/
|
||||
struct AddToDescriptorSetContext : NonCopyable {
|
||||
/** Descriptor set where to bind/add resources to. */
|
||||
VKDescriptorSetTracker &descriptor_set;
|
||||
|
||||
/**
|
||||
* Shader interface of the active shader to query shader binding locations and the used access
|
||||
* flags.
|
||||
*/
|
||||
const VKShaderInterface &shader_interface;
|
||||
|
||||
/**
|
||||
* When adding resources to the descriptor set, its access info should be added to the
|
||||
* resource_access_info. When adding a dispatch/draw node to the render graph, this structure is
|
||||
* passed to make links with the resources and the exact access.
|
||||
*/
|
||||
render_graph::VKResourceAccessInfo &resource_access_info;
|
||||
|
||||
AddToDescriptorSetContext(VKDescriptorSetTracker &descriptor_set,
|
||||
const VKShaderInterface &shader_interface,
|
||||
render_graph::VKResourceAccessInfo &resource_access_info)
|
||||
: descriptor_set(descriptor_set),
|
||||
shader_interface(shader_interface),
|
||||
resource_access_info(resource_access_info)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Super class for resources that can be bound to a shader.
|
||||
|
@ -21,11 +66,17 @@ class VKBindableResource {
|
|||
|
||||
public:
|
||||
/**
|
||||
* Bind the resource to the shader.
|
||||
* Add/bind a resource to a descriptor set (`data.descriptor_set`) and the access info
|
||||
* (`data.resource_access_info`).
|
||||
*
|
||||
* `binding` parameter is the binding as specified in the ShaderCreateInfo.
|
||||
* `bind_type` to make distinction between samples, image load/store, buffer texture binding.
|
||||
*/
|
||||
virtual void bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) = 0;
|
||||
virtual void add_to_descriptor_set(
|
||||
AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state = GPUSamplerState::default_sampler()) = 0;
|
||||
|
||||
protected:
|
||||
void unbind_from_active_context();
|
||||
|
@ -70,10 +121,11 @@ template<shader::ShaderCreateInfo::Resource::BindType BindType> class VKBindSpac
|
|||
/**
|
||||
* Apply registered bindings to the active shader.
|
||||
*/
|
||||
void apply_bindings()
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data)
|
||||
{
|
||||
for (ResourceBinding &binding : bindings_) {
|
||||
binding.resource->bind(binding.binding, BindType, binding.sampler_state);
|
||||
binding.resource->add_to_descriptor_set(
|
||||
data, binding.binding, BindType, binding.sampler_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ void VKImmediate::end()
|
|||
BLI_assert(context.shader == unwrap(shader));
|
||||
VKStateManager &state_manager = context.state_manager_get();
|
||||
state_manager.apply_state();
|
||||
state_manager.apply_bindings();
|
||||
render_graph::VKResourceAccessInfo resource_access_info = {};
|
||||
state_manager.apply_bindings(context, resource_access_info);
|
||||
vertex_attributes_.update_bindings(*this);
|
||||
context.bind_graphics_pipeline(prim_type, vertex_attributes_);
|
||||
vertex_attributes_.bind(context);
|
||||
|
|
|
@ -51,20 +51,22 @@ void VKIndexBuffer::bind_as_ssbo(uint binding)
|
|||
VKContext::get()->state_manager_get().storage_buffer_bind(*this, binding);
|
||||
}
|
||||
|
||||
void VKIndexBuffer::bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
void VKIndexBuffer::add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
{
|
||||
BLI_assert(bind_type == shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER);
|
||||
ensure_updated();
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
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(bind_type, binding);
|
||||
data.shader_interface.descriptor_set_location(bind_type, binding);
|
||||
if (location) {
|
||||
context.descriptor_set_get().bind_as_ssbo(*this, *location);
|
||||
data.descriptor_set.bind_as_ssbo(*this, *location);
|
||||
render_graph::VKBufferAccess buffer_access = {};
|
||||
buffer_access.vk_buffer = buffer_.vk_handle();
|
||||
buffer_access.vk_access_flags = data.shader_interface.access_mask(bind_type, binding);
|
||||
data.resource_access_info.buffers.append(buffer_access);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,10 @@ class VKIndexBuffer : public IndexBuf, public VKBindableResource {
|
|||
|
||||
void bind_as_ssbo(uint binding) override;
|
||||
void bind(VKContext &context);
|
||||
void bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
|
||||
void read(uint32_t *data) const override;
|
||||
|
||||
|
|
|
@ -167,15 +167,18 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
/* Initialize the descriptor set layout. */
|
||||
init_descriptor_set_layout_info(info, resources_len, all_resources, push_constants_storage_type);
|
||||
|
||||
/* Update the descriptor set locations, bind types and access masks. */
|
||||
descriptor_set_locations_ = Array<VKDescriptorSet::Location>(resources_len);
|
||||
descriptor_set_locations_.fill(-1);
|
||||
descriptor_set_bind_types_ = Array<shader::ShaderCreateInfo::Resource::BindType>(resources_len);
|
||||
descriptor_set_bind_types_.fill(shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER);
|
||||
access_masks_ = Array<VkAccessFlags>(resources_len);
|
||||
access_masks_.fill(VK_ACCESS_NONE);
|
||||
uint32_t descriptor_set_location = 0;
|
||||
for (ShaderCreateInfo::Resource &res : all_resources) {
|
||||
const ShaderInput *input = shader_input_get(res);
|
||||
BLI_assert(input);
|
||||
descriptor_set_location_update(input, descriptor_set_location++, res.bind_type);
|
||||
descriptor_set_location_update(input, descriptor_set_location++, res.bind_type, res);
|
||||
}
|
||||
|
||||
/* Post initializing push constants. */
|
||||
|
@ -186,7 +189,8 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
const ShaderInput *push_constant_input = ubo_get(PUSH_CONSTANTS_FALLBACK_NAME);
|
||||
descriptor_set_location_update(push_constant_input,
|
||||
push_constants_fallback_location,
|
||||
shader::ShaderCreateInfo::Resource::UNIFORM_BUFFER);
|
||||
shader::ShaderCreateInfo::Resource::UNIFORM_BUFFER,
|
||||
std::nullopt);
|
||||
}
|
||||
push_constants_layout_.init(
|
||||
info, *this, push_constants_storage_type, push_constant_descriptor_set_location);
|
||||
|
@ -202,12 +206,45 @@ static int32_t shader_input_index(const ShaderInput *shader_inputs,
|
|||
void VKShaderInterface::descriptor_set_location_update(
|
||||
const ShaderInput *shader_input,
|
||||
const VKDescriptorSet::Location location,
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type)
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
std::optional<const shader::ShaderCreateInfo::Resource> resource)
|
||||
{
|
||||
BLI_assert_msg(resource.has_value() ||
|
||||
bind_type == shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER,
|
||||
"Incorrect parameters, when no resource is given, it must be the uniform buffer "
|
||||
"for storing push constants.");
|
||||
BLI_assert_msg(!resource.has_value() || resource->bind_type == bind_type,
|
||||
"Incorrect parameter, bind types do not match.");
|
||||
|
||||
int32_t index = shader_input_index(inputs_, shader_input);
|
||||
BLI_assert(descriptor_set_locations_[index].binding == -1);
|
||||
descriptor_set_locations_[index] = location;
|
||||
descriptor_set_bind_types_[index] = bind_type;
|
||||
|
||||
VkAccessFlags vk_access_flags = VK_ACCESS_NONE;
|
||||
if (resource.has_value()) {
|
||||
switch (resource->bind_type) {
|
||||
case shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
|
||||
vk_access_flags |= VK_ACCESS_UNIFORM_READ_BIT;
|
||||
break;
|
||||
case shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
|
||||
case shader::ShaderCreateInfo::Resource::BindType::IMAGE:
|
||||
if (bool(resource->storagebuf.qualifiers & shader::Qualifier::READ) == true) {
|
||||
vk_access_flags |= VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
if (bool(resource->storagebuf.qualifiers & shader::Qualifier::WRITE) == true) {
|
||||
vk_access_flags |= VK_ACCESS_SHADER_WRITE_BIT;
|
||||
}
|
||||
break;
|
||||
case shader::ShaderCreateInfo::Resource::BindType::SAMPLER:
|
||||
vk_access_flags |= VK_ACCESS_SHADER_READ_BIT;
|
||||
break;
|
||||
};
|
||||
}
|
||||
else if (bind_type == shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
|
||||
access_masks_[index] = VK_ACCESS_UNIFORM_READ_BIT;
|
||||
}
|
||||
access_masks_[index] = vk_access_flags;
|
||||
}
|
||||
|
||||
const VKDescriptorSet::Location VKShaderInterface::descriptor_set_location(
|
||||
|
@ -245,6 +282,25 @@ const std::optional<VKDescriptorSet::Location> VKShaderInterface::descriptor_set
|
|||
return descriptor_set_location(shader_input);
|
||||
}
|
||||
|
||||
const VkAccessFlags VKShaderInterface::access_mask(const ShaderInput *shader_input) const
|
||||
{
|
||||
int32_t index = shader_input_index(inputs_, shader_input);
|
||||
return access_masks_[index];
|
||||
}
|
||||
|
||||
const VkAccessFlags VKShaderInterface::access_mask(
|
||||
const shader::ShaderCreateInfo::Resource::BindType &bind_type, int binding) const
|
||||
{
|
||||
const ShaderInput *shader_input = shader_input_get(bind_type, binding);
|
||||
if (shader_input == nullptr) {
|
||||
return VK_ACCESS_NONE;
|
||||
}
|
||||
if (descriptor_set_bind_type(shader_input) != bind_type) {
|
||||
return VK_ACCESS_NONE;
|
||||
}
|
||||
return access_mask(shader_input);
|
||||
}
|
||||
|
||||
const ShaderInput *VKShaderInterface::shader_input_get(
|
||||
const shader::ShaderCreateInfo::Resource &resource) const
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ class VKShaderInterface : public ShaderInterface {
|
|||
uint32_t image_offset_ = 0;
|
||||
Array<VKDescriptorSet::Location> descriptor_set_locations_;
|
||||
Array<shader::ShaderCreateInfo::Resource::BindType> descriptor_set_bind_types_;
|
||||
Array<VkAccessFlags> access_masks_;
|
||||
VKDescriptorSetLayoutInfo descriptor_set_layout_info_;
|
||||
|
||||
VKPushConstants::Layout push_constants_layout_;
|
||||
|
@ -47,6 +48,17 @@ class VKShaderInterface : public ShaderInterface {
|
|||
const std::optional<VKDescriptorSet::Location> descriptor_set_location(
|
||||
const shader::ShaderCreateInfo::Resource::BindType &bind_type, int binding) const;
|
||||
|
||||
/**
|
||||
* Get the access mask for a binding.
|
||||
*
|
||||
* Is used to build the correct resource accesses in the render graph (dispatch/draw nodes).
|
||||
*
|
||||
* Will return VK_ACCESS_NONE when binding isn't found or not compatible with the given bind
|
||||
* type.
|
||||
*/
|
||||
const VkAccessFlags access_mask(const shader::ShaderCreateInfo::Resource::BindType &bind_type,
|
||||
int binding) const;
|
||||
|
||||
/** Get the Layout of the shader. */
|
||||
const VKPushConstants::Layout &push_constants_layout_get() const
|
||||
{
|
||||
|
@ -85,10 +97,12 @@ class VKShaderInterface : public ShaderInterface {
|
|||
const VKDescriptorSet::Location descriptor_set_location(const ShaderInput *shader_input) const;
|
||||
const shader::ShaderCreateInfo::Resource::BindType descriptor_set_bind_type(
|
||||
const ShaderInput *shader_input) const;
|
||||
const VkAccessFlags access_mask(const ShaderInput *shader_input) const;
|
||||
void descriptor_set_location_update(
|
||||
const ShaderInput *shader_input,
|
||||
const VKDescriptorSet::Location location,
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type);
|
||||
const shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
std::optional<const shader::ShaderCreateInfo::Resource> resource);
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -29,15 +29,19 @@ void VKStateManager::apply_state()
|
|||
}
|
||||
}
|
||||
|
||||
void VKStateManager::apply_bindings()
|
||||
void VKStateManager::apply_bindings(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &resource_access_info)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
if (context.shader) {
|
||||
textures_.apply_bindings();
|
||||
images_.apply_bindings();
|
||||
uniform_buffers_.apply_bindings();
|
||||
storage_buffers_.apply_bindings();
|
||||
VKShader *shader = unwrap(context.shader);
|
||||
if (shader == nullptr) {
|
||||
return;
|
||||
}
|
||||
AddToDescriptorSetContext data(
|
||||
context.descriptor_set_get(), shader->interface_get(), resource_access_info);
|
||||
textures_.add_to_descriptor_set(data);
|
||||
images_.add_to_descriptor_set(data);
|
||||
uniform_buffers_.add_to_descriptor_set(data);
|
||||
storage_buffers_.add_to_descriptor_set(data);
|
||||
}
|
||||
|
||||
void VKStateManager::force_state()
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "BLI_array.hh"
|
||||
|
||||
#include "render_graph/vk_resource_access_info.hh"
|
||||
#include "vk_bindable_resource.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
@ -20,6 +21,7 @@ class VKUniformBuffer;
|
|||
class VKVertexBuffer;
|
||||
class VKStorageBuffer;
|
||||
class VKIndexBuffer;
|
||||
class VKContext;
|
||||
|
||||
class VKStateManager : public StateManager {
|
||||
|
||||
|
@ -37,7 +39,8 @@ class VKStateManager : public StateManager {
|
|||
void issue_barrier(eGPUBarrier barrier_bits) override;
|
||||
|
||||
/** Apply resources to the bindings of the active shader. */
|
||||
void apply_bindings();
|
||||
void apply_bindings(VKContext &context,
|
||||
render_graph::VKResourceAccessInfo &resource_access_info);
|
||||
|
||||
void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override;
|
||||
void texture_unbind(Texture *tex) override;
|
||||
|
|
|
@ -53,19 +53,20 @@ void VKStorageBuffer::bind(int slot)
|
|||
context.state_manager_get().storage_buffer_bind(*this, slot);
|
||||
}
|
||||
|
||||
void VKStorageBuffer::bind(int slot,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
void VKStorageBuffer::add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
VKShader *shader = static_cast<VKShader *>(context.shader);
|
||||
ensure_allocated();
|
||||
const VKShaderInterface &shader_interface = shader->interface_get();
|
||||
const std::optional<VKDescriptorSet::Location> location =
|
||||
shader_interface.descriptor_set_location(bind_type, slot);
|
||||
data.shader_interface.descriptor_set_location(bind_type, binding);
|
||||
if (location) {
|
||||
VKDescriptorSetTracker &descriptor_set = context.descriptor_set_get();
|
||||
descriptor_set.bind(*this, *location);
|
||||
data.descriptor_set.bind(*this, *location);
|
||||
render_graph::VKBufferAccess buffer_access = {};
|
||||
buffer_access.vk_buffer = buffer_.vk_handle();
|
||||
buffer_access.vk_access_flags = data.shader_interface.access_mask(bind_type, binding);
|
||||
data.resource_access_info.buffers.append(buffer_access);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ class VKStorageBuffer : public StorageBuf, public VKBindableResource {
|
|||
|
||||
void update(const void *data) override;
|
||||
void bind(int slot) override;
|
||||
void bind(int slot,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int slot,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) 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;
|
||||
|
|
|
@ -625,25 +625,26 @@ bool VKTexture::allocate()
|
|||
return result == VK_SUCCESS;
|
||||
}
|
||||
|
||||
void VKTexture::bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state)
|
||||
void VKTexture::add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
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(bind_type, binding);
|
||||
data.shader_interface.descriptor_set_location(bind_type, binding);
|
||||
if (location) {
|
||||
VKDescriptorSetTracker &descriptor_set = context.descriptor_set_get();
|
||||
if (bind_type == shader::ShaderCreateInfo::Resource::BindType::IMAGE) {
|
||||
descriptor_set.image_bind(*this, *location);
|
||||
data.descriptor_set.image_bind(*this, *location);
|
||||
}
|
||||
else {
|
||||
VKDevice &device = VKBackend::get().device_get();
|
||||
const VKSampler &sampler = device.samplers().get(sampler_state);
|
||||
descriptor_set.bind(*this, *location, sampler);
|
||||
data.descriptor_set.bind(*this, *location, sampler);
|
||||
}
|
||||
render_graph::VKImageAccess image_access = {};
|
||||
image_access.vk_image = vk_image_handle();
|
||||
image_access.vk_access_flags = data.shader_interface.access_mask(bind_type, *location);
|
||||
data.resource_access_info.images.append(image_access);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,9 +84,10 @@ class VKTexture : public Texture, public VKBindableResource {
|
|||
/* TODO(fclem): Legacy. Should be removed at some point. */
|
||||
uint gl_bindcode_get() const override;
|
||||
|
||||
void bind(int location,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int location,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
|
||||
VkImage vk_image_handle() const
|
||||
{
|
||||
|
|
|
@ -56,9 +56,10 @@ void VKUniformBuffer::clear_to_zero()
|
|||
buffer_.clear(context, 0);
|
||||
}
|
||||
|
||||
void VKUniformBuffer::bind(int slot,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
void VKUniformBuffer::add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int slot,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
{
|
||||
if (!buffer_.is_allocated()) {
|
||||
allocate();
|
||||
|
@ -70,20 +71,19 @@ void VKUniformBuffer::bind(int slot,
|
|||
MEM_SAFE_FREE(data_);
|
||||
}
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
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(bind_type, slot);
|
||||
data.shader_interface.descriptor_set_location(bind_type, slot);
|
||||
if (location) {
|
||||
VKDescriptorSetTracker &descriptor_set = context.descriptor_set_get();
|
||||
/* TODO: move to descriptor set. */
|
||||
if (bind_type == shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
|
||||
descriptor_set.bind(*this, *location);
|
||||
data.descriptor_set.bind(*this, *location);
|
||||
}
|
||||
else {
|
||||
descriptor_set.bind_as_ssbo(*this, *location);
|
||||
data.descriptor_set.bind_as_ssbo(*this, *location);
|
||||
}
|
||||
render_graph::VKBufferAccess buffer_access = {};
|
||||
buffer_access.vk_buffer = buffer_.vk_handle();
|
||||
buffer_access.vk_access_flags = data.shader_interface.access_mask(bind_type, *location);
|
||||
data.resource_access_info.buffers.append(buffer_access);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,10 @@ class VKUniformBuffer : public UniformBuf, public VKBindableResource, NonCopyabl
|
|||
}
|
||||
|
||||
/* Bindable resource */
|
||||
void bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
|
||||
private:
|
||||
void allocate();
|
||||
|
|
|
@ -37,15 +37,13 @@ void VKVertexBuffer::bind_as_texture(uint binding)
|
|||
state_manager.texel_buffer_bind(*this, binding);
|
||||
}
|
||||
|
||||
void VKVertexBuffer::bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
void VKVertexBuffer::add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState /*sampler_state*/)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
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(bind_type, binding);
|
||||
data.shader_interface.descriptor_set_location(bind_type, binding);
|
||||
if (!location) {
|
||||
return;
|
||||
}
|
||||
|
@ -70,13 +68,16 @@ void VKVertexBuffer::bind(int binding,
|
|||
}
|
||||
|
||||
/* TODO: Check if we can move this check inside the descriptor set. */
|
||||
VKDescriptorSetTracker &descriptor_set = context.descriptor_set_get();
|
||||
if (bind_type == shader::ShaderCreateInfo::Resource::BindType::SAMPLER) {
|
||||
descriptor_set.bind(*this, *location);
|
||||
data.descriptor_set.bind(*this, *location);
|
||||
}
|
||||
else {
|
||||
descriptor_set.bind_as_ssbo(*this, *location);
|
||||
data.descriptor_set.bind_as_ssbo(*this, *location);
|
||||
}
|
||||
render_graph::VKBufferAccess buffer_access = {};
|
||||
buffer_access.vk_buffer = buffer_.vk_handle();
|
||||
buffer_access.vk_access_flags = data.shader_interface.access_mask(bind_type, *location);
|
||||
data.resource_access_info.buffers.append(buffer_access);
|
||||
}
|
||||
|
||||
void VKVertexBuffer::wrap_handle(uint64_t /*handle*/)
|
||||
|
|
|
@ -28,9 +28,10 @@ class VKVertexBuffer : public VertBuf, public VKBindableResource {
|
|||
|
||||
void bind_as_ssbo(uint binding) override;
|
||||
void bind_as_texture(uint binding) override;
|
||||
void bind(int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void add_to_descriptor_set(AddToDescriptorSetContext &data,
|
||||
int binding,
|
||||
shader::ShaderCreateInfo::Resource::BindType bind_type,
|
||||
const GPUSamplerState sampler_state) override;
|
||||
void wrap_handle(uint64_t handle) override;
|
||||
|
||||
void update_sub(uint start, uint len, const void *data) override;
|
||||
|
|
Loading…
Reference in New Issue