Vulkan: Shader Interface Attribute Extraction. #107333
|
@ -203,17 +203,22 @@ class VKPushConstants : VKResourceTracker<VKUniformBuffer> {
|
|||
const T *input_data)
|
||||
{
|
||||
const Layout::PushConstant *push_constant_layout = layout_->find(location);
|
||||
BLI_assert(push_constant_layout);
|
||||
if (push_constant_layout == nullptr) {
|
||||
/* Legacy code can still try to update push constants when they don't exist. For example
|
||||
* `immDrawPixelsTexSetup` will bind an image slot manually. This works in OpenGL, but in
|
||||
* vulkan images aren't stored as push constants. */
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *bytes = static_cast<uint8_t *>(data_);
|
||||
T *dst = static_cast<T *>(static_cast<void *>(&bytes[push_constant_layout->offset]));
|
||||
const bool is_tightly_std140_packed = (comp_len % 4) == 0;
|
||||
if (layout_->storage_type_get() == StorageType::PUSH_CONSTANTS || array_size == 0 ||
|
||||
is_tightly_std140_packed) {
|
||||
BLI_assert_msg(push_constant_layout->offset + comp_len * array_size * sizeof(T) <=
|
||||
layout_->size_in_bytes(),
|
||||
push_constant_layout->array_size == 0 || is_tightly_std140_packed) {
|
||||
const size_t copy_size_in_bytes = comp_len * max_ii(array_size, 1) * sizeof(T);
|
||||
BLI_assert_msg(push_constant_layout->offset + copy_size_in_bytes <= layout_->size_in_bytes(),
|
||||
"Tried to write outside the push constant allocated memory.");
|
||||
memcpy(dst, input_data, comp_len * array_size * sizeof(T));
|
||||
memcpy(dst, input_data, copy_size_in_bytes);
|
||||
is_dirty_ = true;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -984,12 +984,14 @@ void VKShader::unbind()
|
|||
|
||||
void VKShader::uniform_float(int location, int comp_len, int array_size, const float *data)
|
||||
{
|
||||
pipeline_get().push_constants_get().push_constant_set(location, comp_len, array_size, data);
|
||||
VKPushConstants &push_constants = pipeline_get().push_constants_get();
|
||||
push_constants.push_constant_set(location, comp_len, array_size, data);
|
||||
}
|
||||
|
||||
void VKShader::uniform_int(int location, int comp_len, int array_size, const int *data)
|
||||
{
|
||||
pipeline_get().push_constants_get().push_constant_set(location, comp_len, array_size, data);
|
||||
VKPushConstants &push_constants = pipeline_get().push_constants_get();
|
||||
push_constants.push_constant_set(location, comp_len, array_size, data);
|
||||
}
|
||||
|
||||
std::string VKShader::resources_declare(const shader::ShaderCreateInfo &info) const
|
||||
|
@ -1183,6 +1185,7 @@ std::string VKShader::geometry_layout_declare(const shader::ShaderCreateInfo &in
|
|||
}
|
||||
ss << "\n";
|
||||
|
||||
location = 0;
|
||||
for (const StageInterfaceInfo *iface : info.geometry_out_interfaces_) {
|
||||
bool has_matching_input_iface = find_interface_by_name(info.vertex_out_interfaces_,
|
||||
iface->instance_name) != nullptr;
|
||||
|
|
|
@ -17,7 +17,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
|
||||
using namespace blender::gpu::shader;
|
||||
|
||||
attr_len_ = 0;
|
||||
attr_len_ = info.vertex_inputs_.size();
|
||||
uniform_len_ = info.push_constants_.size();
|
||||
ssbo_len_ = 0;
|
||||
ubo_len_ = 0;
|
||||
|
@ -58,7 +58,7 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
/* Make sure that the image slots don't overlap with the sampler slots. */
|
||||
image_offset_++;
|
||||
|
||||
int32_t input_tot_len = ubo_len_ + uniform_len_ + ssbo_len_;
|
||||
int32_t input_tot_len = attr_len_ + ubo_len_ + uniform_len_ + ssbo_len_;
|
||||
inputs_ = static_cast<ShaderInput *>(
|
||||
MEM_calloc_arrayN(input_tot_len, sizeof(ShaderInput), __func__));
|
||||
ShaderInput *input = inputs_;
|
||||
|
@ -66,6 +66,20 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
name_buffer_ = (char *)MEM_mallocN(names_size, "name_buffer");
|
||||
uint32_t name_buffer_offset = 0;
|
||||
|
||||
/* Attributes */
|
||||
for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) {
|
||||
copy_input_name(input, attr.name, name_buffer_, name_buffer_offset);
|
||||
input->location = input->binding = attr.index;
|
||||
if (input->location != -1) {
|
||||
enabled_attr_mask_ |= (1 << input->location);
|
||||
|
||||
/* Used in `GPU_shader_get_attribute_info`. */
|
||||
attr_types_[input->location] = uint8_t(attr.type);
|
||||
}
|
||||
|
||||
input++;
|
||||
}
|
||||
|
||||
/* Uniform blocks */
|
||||
for (const ShaderCreateInfo::Resource &res : all_resources) {
|
||||
if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
|
||||
|
@ -131,7 +145,9 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info)
|
|||
}
|
||||
|
||||
/* Determine the descriptor set locations after the inputs have been sorted. */
|
||||
descriptor_set_locations_ = Array<VKDescriptorSet::Location>(input_tot_len);
|
||||
/* Note: input_tot_len is sometimes more than we need. */
|
||||
const uint32_t resources_len = input_tot_len;
|
||||
descriptor_set_locations_ = Array<VKDescriptorSet::Location>(resources_len);
|
||||
uint32_t descriptor_set_location = 0;
|
||||
for (ShaderCreateInfo::Resource &res : all_resources) {
|
||||
const ShaderInput *input = shader_input_get(res);
|
||||
|
|
Loading…
Reference in New Issue