1
1

Create compute command buffer.

This commit is contained in:
2023-02-06 15:59:15 +01:00
parent 6078fe34f9
commit ec40ef19c7
10 changed files with 75 additions and 17 deletions

View File

@@ -1201,6 +1201,7 @@ void GHOST_GetVulkanHandles(GHOST_ContextHandle context,
void *r_instance,
void *r_physical_device,
void *r_device,
void *r_compute_command_buffer,
uint32_t *r_graphic_queue_family);
/**

View File

@@ -40,7 +40,7 @@ class GHOST_IContext {
virtual unsigned int getDefaultFramebuffer() = 0;
virtual GHOST_TSuccess getVulkanHandles(void *, void *, void *, uint32_t *) = 0;
virtual GHOST_TSuccess getVulkanHandles(void *, void *, void *, void *, uint32_t *) = 0;
/**
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.

View File

@@ -1203,10 +1203,12 @@ void GHOST_GetVulkanHandles(GHOST_ContextHandle contexthandle,
void *r_instance,
void *r_physical_device,
void *r_device,
void *r_compute_command_buffer,
uint32_t *r_graphic_queue_family)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
context->getVulkanHandles(r_instance, r_physical_device, r_device, r_graphic_queue_family);
context->getVulkanHandles(
r_instance, r_physical_device, r_device, r_compute_command_buffer, r_graphic_queue_family);
}
void GHOST_GetVulkanBackbuffer(GHOST_WindowHandle windowhandle,

View File

@@ -142,6 +142,7 @@ class GHOST_Context : public GHOST_IContext {
virtual GHOST_TSuccess getVulkanHandles(void * /*r_instance*/,
void * /*r_physical_device*/,
void * /*r_device*/,
void * /*r_compute_command_buffer*/,
uint32_t * /*r_graphic_queue_family*/) override
{
return GHOST_kFailure;

View File

@@ -192,6 +192,9 @@ GHOST_TSuccess GHOST_ContextVK::destroySwapchain()
if (m_render_pass != VK_NULL_HANDLE) {
vkDestroyRenderPass(m_device, m_render_pass, NULL);
}
if (m_compute_command_buffer != VK_NULL_HANDLE) {
vkFreeCommandBuffers(m_device, m_command_pool, 1, &m_compute_command_buffer);
}
for (auto command_buffer : m_command_buffers) {
vkFreeCommandBuffers(m_device, m_command_pool, 1, &command_buffer);
}
@@ -311,11 +314,13 @@ GHOST_TSuccess GHOST_ContextVK::getVulkanBackbuffer(void *image,
GHOST_TSuccess GHOST_ContextVK::getVulkanHandles(void *r_instance,
void *r_physical_device,
void *r_device,
void *r_compute_command_buffer,
uint32_t *r_graphic_queue_family)
{
*((VkInstance *)r_instance) = m_instance;
*((VkPhysicalDevice *)r_physical_device) = m_physical_device;
*((VkDevice *)r_device) = m_device;
*((VkCommandBuffer *)r_compute_command_buffer) = m_compute_command_buffer;
*r_graphic_queue_family = m_queue_family_graphic;
return GHOST_kSuccess;
@@ -619,16 +624,34 @@ static GHOST_TSuccess selectPresentMode(VkPhysicalDevice device,
return GHOST_kFailure;
}
GHOST_TSuccess GHOST_ContextVK::createCommandBuffers()
GHOST_TSuccess GHOST_ContextVK::createCommandPools()
{
m_command_buffers.resize(m_swapchain_image_views.size());
VkCommandPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = m_queue_family_graphic;
VK_CHECK(vkCreateCommandPool(m_device, &poolInfo, NULL, &m_command_pool));
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_ContextVK::createComputeCommandBuffer()
{
assert(m_command_pool != VK_NULL_HANDLE);
VkCommandBufferAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
alloc_info.commandPool = m_command_pool;
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
alloc_info.commandBufferCount = 1;
VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, &m_compute_command_buffer));
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffers()
{
assert(m_command_pool != VK_NULL_HANDLE);
m_command_buffers.resize(m_swapchain_image_views.size());
VkCommandBufferAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
@@ -637,7 +660,6 @@ GHOST_TSuccess GHOST_ContextVK::createCommandBuffers()
alloc_info.commandBufferCount = static_cast<uint32_t>(m_command_buffers.size());
VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, m_command_buffers.data()));
return GHOST_kSuccess;
}
@@ -776,7 +798,7 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain()
VK_CHECK(vkCreateFence(m_device, &fence_info, NULL, &m_in_flight_fences[i]));
}
createCommandBuffers();
createGraphicsCommandBuffers();
return GHOST_kSuccess;
}
@@ -976,6 +998,9 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
VK_CHECK(vkCreateDevice(m_physical_device, &device_create_info, NULL, &m_device));
createCommandPools();
createComputeCommandBuffer();
vkGetDeviceQueue(m_device, m_queue_family_graphic, 0, &m_graphic_queue);
if (use_window_surface) {

View File

@@ -113,6 +113,7 @@ class GHOST_ContextVK : public GHOST_Context {
GHOST_TSuccess getVulkanHandles(void *r_instance,
void *r_physical_device,
void *r_device,
void *r_compute_command_buffer,
uint32_t *r_graphic_queue_family);
/**
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.
@@ -182,6 +183,7 @@ class GHOST_ContextVK : public GHOST_Context {
std::vector<VkImage> m_swapchain_images;
std::vector<VkImageView> m_swapchain_image_views;
std::vector<VkFramebuffer> m_swapchain_framebuffers;
VkCommandBuffer m_compute_command_buffer;
std::vector<VkCommandBuffer> m_command_buffers;
VkRenderPass m_render_pass;
VkExtent2D m_render_extent;
@@ -200,6 +202,8 @@ class GHOST_ContextVK : public GHOST_Context {
GHOST_TSuccess pickPhysicalDevice(std::vector<const char *> required_exts);
GHOST_TSuccess createSwapchain();
GHOST_TSuccess destroySwapchain();
GHOST_TSuccess createCommandBuffers();
GHOST_TSuccess createCommandPools();
GHOST_TSuccess createGraphicsCommandBuffers();
GHOST_TSuccess createComputeCommandBuffer();
GHOST_TSuccess recordCommandBuffers();
};

View File

@@ -24,13 +24,14 @@ VKContext::VKContext(void *ghost_window, void *ghost_context)
&instance_,
&physical_device_,
&device_,
&compute_command_buffer_,
&graphic_queue_family_);
/* Initialize the memory allocator. */
VmaAllocatorCreateInfo info = {};
/* Should use same vulkan version as GHOST, but set to 1.0 for now. Raising it to 1.2 requires
* correct extensions and functions to be found, which doesn't out-of-the-box. We should fix this,
* but to continue the development at hand we lower the API to 1.0.*/
* correct extensions and functions to be found, which doesn't out-of-the-box. We should fix
* this, but to continue the development at hand we lower the API to 1.0.*/
info.vulkanApiVersion = VK_API_VERSION_1_0;
info.physicalDevice = physical_device_;
info.device = device_;

View File

@@ -27,6 +27,7 @@ class VKContext : public Context {
VkInstance instance_ = VK_NULL_HANDLE;
VkPhysicalDevice physical_device_ = VK_NULL_HANDLE;
VkDevice device_ = VK_NULL_HANDLE;
VkCommandBuffer compute_command_buffer_ = VK_NULL_HANDLE;
uint32_t graphic_queue_family_ = 0;
/** Allocator used for texture and buffers and other resources. */
@@ -59,6 +60,11 @@ class VKContext : public Context {
{
return device_;
}
VkCommandBuffer compute_command_buffer_get() const
{
return compute_command_buffer_;
}
const uint32_t *queue_family_ptr_get() const
{

View File

@@ -605,8 +605,8 @@ VKShader::~VKShader()
for (VkDescriptorSetLayout &layout : layouts_) {
vkDestroyDescriptorSetLayout(device, layout, nullptr);
}
if (pipeline_ != VK_NULL_HANDLE) {
vkDestroyPipeline(device, pipeline_, nullptr);
if (compute_pipeline_ != VK_NULL_HANDLE) {
vkDestroyPipeline(device, compute_pipeline_, nullptr);
}
}
@@ -661,9 +661,8 @@ bool VKShader::finalize(const shader::ShaderCreateInfo *info)
/* TODO we might need to move the actual pipeline construction to a later stage as the graphics
* pipeline requires more data before it can be constructed.*/
const bool is_graphics_shader = vertex_module_ != VK_NULL_HANDLE;
bool result;
if (is_graphics_shader) {
if (is_graphics_shader()) {
BLI_assert((fragment_module_ != VK_NULL_HANDLE && info->tf_type_ == GPU_SHADER_TFB_NONE) ||
(fragment_module_ == VK_NULL_HANDLE && info->tf_type_ != GPU_SHADER_TFB_NONE));
BLI_assert(compute_module_ == VK_NULL_HANDLE);
@@ -729,8 +728,8 @@ bool VKShader::bake_compute_pipeline(VkDevice vk_device)
pipeline_info.layout = pipeline_layout_;
pipeline_info.stage.pName = "main";
if (vkCreateComputePipelines(vk_device, nullptr, 1, &pipeline_info, nullptr, &pipeline_) !=
VK_SUCCESS) {
if (vkCreateComputePipelines(
vk_device, nullptr, 1, &pipeline_info, nullptr, &compute_pipeline_) != VK_SUCCESS) {
return false;
}
@@ -850,6 +849,15 @@ void VKShader::transform_feedback_disable()
void VKShader::bind()
{
VKContext *context = VKContext::get();
if (is_compute_shader()) {
vkCmdBindPipeline(
context->compute_command_buffer_get(), VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipeline_);
}
else {
BLI_assert_unreachable();
}
}
void VKShader::unbind()

View File

@@ -26,7 +26,7 @@ class VKShader : public Shader {
bool compilation_failed_ = false;
Vector<VkDescriptorSetLayout> layouts_;
VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE;
VkPipeline pipeline_ = VK_NULL_HANDLE;
VkPipeline compute_pipeline_ = VK_NULL_HANDLE;
public:
VKShader(const char *name);
@@ -69,6 +69,16 @@ class VKShader : public Shader {
bool finalize_pipeline_layout(VkDevice vk_device, const shader::ShaderCreateInfo &info);
bool finalize_graphics_pipeline(VkDevice vk_device);
bool bake_compute_pipeline(VkDevice vk_device);
bool is_graphics_shader() const
{
return !is_compute_shader();
}
bool is_compute_shader() const
{
return compute_module_ != VK_NULL_HANDLE;
}
};
} // namespace blender::gpu