Create compute command buffer.
This commit is contained in:
@@ -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);
|
||||
|
||||
/**
|
||||
|
@@ -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.
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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();
|
||||
};
|
||||
|
@@ -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_;
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user