Vulkan: Incorrect default for missing orco

When orcos are not available in the geometry data it is bound with
a default buffer. This buffer was initialized with only zeros. But
orcos required to read the 0, 0, 0, 1.

Fixes `render/shader/tex_voronoi.blend` render test.

Pull Request: https://projects.blender.org/blender/blender/pulls/126838
This commit is contained in:
Jeroen Bakker
2024-08-27 16:00:00 +02:00
parent e7d43d07a1
commit f19675ffca
5 changed files with 19 additions and 34 deletions

View File

@@ -55,13 +55,6 @@ VKContext::~VKContext()
void VKContext::sync_backbuffer()
{
VKDevice &device = VKBackend::get().device;
if (ghost_context_) {
if (!is_init_) {
is_init_ = true;
device.init_dummy_buffer(*this);
}
}
if (ghost_window_) {
GHOST_VulkanSwapChainData swap_chain_data = {};
GHOST_GetVulkanSwapChainFormat((GHOST_WindowHandle)ghost_window_, &swap_chain_data);

View File

@@ -36,8 +36,6 @@ class VKContext : public Context, NonCopyable {
/* Reusable data. Stored inside context to limit reallocations. */
render_graph::VKResourceAccessInfo access_info_ = {};
bool is_init_ = false;
VKThreadData &thread_data_;
public:

View File

@@ -40,7 +40,7 @@ void VKDevice::deinit()
return;
}
dummy_buffer_.free();
dummy_buffer.free();
samplers_.free();
{
@@ -95,6 +95,7 @@ void VKDevice::init(void *ghost_context)
init_pipeline_cache();
samplers_.init();
init_dummy_buffer();
debug::object_label(vk_handle(), "LogicalDevice");
debug::object_label(queue_get(), "GenericQueue");
@@ -191,16 +192,16 @@ void VKDevice::init_pipeline_cache()
vkCreatePipelineCache(vk_device_, &create_info, vk_allocation_callbacks, &vk_pipeline_cache_);
}
void VKDevice::init_dummy_buffer(VKContext &context)
void VKDevice::init_dummy_buffer()
{
if (dummy_buffer_.is_allocated()) {
return;
}
dummy_buffer_.create(sizeof(float4x4),
GPU_USAGE_DEVICE_ONLY,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
dummy_buffer_.clear(context, 0);
dummy_buffer.create(sizeof(float4x4),
GPU_USAGE_DEVICE_ONLY,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
debug::object_label(dummy_buffer.vk_handle(), "DummyBuffer");
/* Default dummy buffer. Set the 4th element to 1 to fix missing orcos. */
float data[16] = {
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
dummy_buffer.update(static_cast<void *>(data));
}
void VKDevice::init_glsl_patch()

View File

@@ -153,9 +153,6 @@ class VKDevice : public NonCopyable {
/* Workarounds */
VKWorkarounds workarounds_;
/** Buffer to bind to unbound resource locations. */
VKBuffer dummy_buffer_;
std::string glsl_patch_;
Vector<VKThreadData *> thread_data_;
@@ -163,6 +160,8 @@ class VKDevice : public NonCopyable {
render_graph::VKResourceStateTracker resources;
VKDiscardPool orphaned_data;
VKPipelinePool pipelines;
/** Buffer to bind to unbound resource locations. */
VKBuffer dummy_buffer;
/**
* This struct contains the functions pointer to extension provided functions.
@@ -257,12 +256,6 @@ class VKDevice : public NonCopyable {
bool is_initialized() const;
void init(void *ghost_context);
/**
* Initialize a dummy buffer that can be bound for missing attributes.
*
* Dummy buffer can only be initialized after the command buffer of the context is retrieved.
*/
void init_dummy_buffer(VKContext &context);
void reinit();
void deinit();
@@ -314,11 +307,6 @@ class VKDevice : public NonCopyable {
void context_unregister(VKContext &context);
Span<std::reference_wrapper<VKContext>> contexts_get() const;
const VKBuffer &dummy_buffer_get() const
{
return dummy_buffer_;
}
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const;
void debug_print();
@@ -337,6 +325,11 @@ class VKDevice : public NonCopyable {
*/
void init_functions();
/**
* Initialize a dummy buffer that can be bound for missing attributes.
*/
void init_dummy_buffer();
/* During initialization the backend requires access to update the workarounds. */
friend VKBackend;
};

View File

@@ -62,7 +62,7 @@ void VKVertexAttributeObject::bind(
Array<bool> visited_bindings(bindings.size());
visited_bindings.fill(false);
const VKBuffer &dummy = VKBackend::get().device.dummy_buffer_get();
const VKBuffer &dummy = VKBackend::get().device.dummy_buffer;
for (VkVertexInputAttributeDescription attribute : attributes) {
if (visited_bindings[attribute.binding]) {
continue;