In Vulkan multiple commands can be in flight simultaneously. These commands can share resources like descriptor sets or push constants. When between commands these resources are updated a new version of the resources should be created. When a resource is updated it should check the submission id of the command buffer. If this is different than last known by the resources, the previous resources should be freed. If the submission id is the same than previously it has to create a new version of the resource to not intervene with other commands that uses the resource before the update. When the resource wasn't updated between multiple usages in the same submission id it could reuse the previous resource. This PR introduces a `ResourceTracker` and a `SubmissionTracker`. A submission tracker can check if the command buffer is submitted. In this case all resources of the resource tracker should be freed. Unmodified resources in the same submission can be shared. A resource tracker will keep track of all resources that are in flight. After the resources are used (submission + execution) have finished the resources can be cleared. Pull Request: blender/blender#105183
176 lines
3.6 KiB
C++
176 lines
3.6 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2022 Blender Foundation. All rights reserved. */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "gpu_capabilities_private.hh"
|
|
#include "gpu_platform_private.hh"
|
|
|
|
#include "vk_batch.hh"
|
|
#include "vk_context.hh"
|
|
#include "vk_drawlist.hh"
|
|
#include "vk_fence.hh"
|
|
#include "vk_framebuffer.hh"
|
|
#include "vk_index_buffer.hh"
|
|
#include "vk_pixel_buffer.hh"
|
|
#include "vk_query.hh"
|
|
#include "vk_shader.hh"
|
|
#include "vk_storage_buffer.hh"
|
|
#include "vk_texture.hh"
|
|
#include "vk_uniform_buffer.hh"
|
|
#include "vk_vertex_buffer.hh"
|
|
|
|
#include "vk_backend.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
void VKBackend::init_platform()
|
|
{
|
|
BLI_assert(!GPG.initialized);
|
|
|
|
eGPUDeviceType device = GPU_DEVICE_ANY;
|
|
eGPUOSType os = GPU_OS_ANY;
|
|
eGPUDriverType driver = GPU_DRIVER_ANY;
|
|
eGPUSupportLevel support_level = GPU_SUPPORT_LEVEL_SUPPORTED;
|
|
|
|
#ifdef _WIN32
|
|
os = GPU_OS_WIN;
|
|
#elif defined(__APPLE__)
|
|
os = GPU_OS_MAC;
|
|
#else
|
|
os = GPU_OS_UNIX;
|
|
#endif
|
|
|
|
GPG.init(device, os, driver, support_level, GPU_BACKEND_VULKAN, "", "", "");
|
|
}
|
|
|
|
void VKBackend::platform_exit()
|
|
{
|
|
BLI_assert(GPG.initialized);
|
|
GPG.clear();
|
|
}
|
|
|
|
void VKBackend::delete_resources()
|
|
{
|
|
}
|
|
|
|
void VKBackend::samplers_update()
|
|
{
|
|
}
|
|
|
|
void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len)
|
|
{
|
|
VKContext &context = *VKContext::get();
|
|
VKShader *shader = static_cast<VKShader *>(context.shader);
|
|
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
|
VKPipeline &pipeline = shader->pipeline_get();
|
|
VKDescriptorSetTracker &descriptor_set = pipeline.descriptor_set_get();
|
|
VKPushConstants &push_constants = pipeline.push_constants_get();
|
|
|
|
push_constants.update(context);
|
|
descriptor_set.update(context);
|
|
command_buffer.bind(*descriptor_set.active_descriptor_set(),
|
|
shader->vk_pipeline_layout_get(),
|
|
VK_PIPELINE_BIND_POINT_COMPUTE);
|
|
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);
|
|
}
|
|
|
|
void VKBackend::compute_dispatch_indirect(StorageBuf * /*indirect_buf*/)
|
|
{
|
|
}
|
|
|
|
Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context)
|
|
{
|
|
return new VKContext(ghost_window, ghost_context);
|
|
}
|
|
|
|
Batch *VKBackend::batch_alloc()
|
|
{
|
|
return new VKBatch();
|
|
}
|
|
|
|
DrawList *VKBackend::drawlist_alloc(int /*list_length*/)
|
|
{
|
|
return new VKDrawList();
|
|
}
|
|
|
|
Fence *VKBackend::fence_alloc()
|
|
{
|
|
return new VKFence();
|
|
}
|
|
|
|
FrameBuffer *VKBackend::framebuffer_alloc(const char *name)
|
|
{
|
|
return new VKFrameBuffer(name);
|
|
}
|
|
|
|
IndexBuf *VKBackend::indexbuf_alloc()
|
|
{
|
|
return new VKIndexBuffer();
|
|
}
|
|
|
|
PixelBuffer *VKBackend::pixelbuf_alloc(uint size)
|
|
{
|
|
return new VKPixelBuffer(size);
|
|
}
|
|
|
|
QueryPool *VKBackend::querypool_alloc()
|
|
{
|
|
return new VKQueryPool();
|
|
}
|
|
|
|
Shader *VKBackend::shader_alloc(const char *name)
|
|
{
|
|
return new VKShader(name);
|
|
}
|
|
|
|
Texture *VKBackend::texture_alloc(const char *name)
|
|
{
|
|
return new VKTexture(name);
|
|
}
|
|
|
|
UniformBuf *VKBackend::uniformbuf_alloc(int size, const char *name)
|
|
{
|
|
return new VKUniformBuffer(size, name);
|
|
}
|
|
|
|
StorageBuf *VKBackend::storagebuf_alloc(int size, GPUUsageType usage, const char *name)
|
|
{
|
|
return new VKStorageBuffer(size, usage, name);
|
|
}
|
|
|
|
VertBuf *VKBackend::vertbuf_alloc()
|
|
{
|
|
return new VKVertexBuffer();
|
|
}
|
|
|
|
void VKBackend::render_begin()
|
|
{
|
|
}
|
|
|
|
void VKBackend::render_end()
|
|
{
|
|
}
|
|
|
|
void VKBackend::render_step()
|
|
{
|
|
}
|
|
|
|
shaderc::Compiler &VKBackend::get_shaderc_compiler()
|
|
{
|
|
return shaderc_compiler_;
|
|
}
|
|
|
|
void VKBackend::capabilities_init(VKContext & /*context*/)
|
|
{
|
|
/* Reset all capabilities from previous context. */
|
|
GCaps = {};
|
|
GCaps.compute_shader_support = true;
|
|
GCaps.shader_storage_buffer_objects_support = true;
|
|
GCaps.shader_image_load_store_support = true;
|
|
}
|
|
|
|
} // namespace blender::gpu
|