mirror of https://github.com/xemu-project/xemu.git
119 lines
3.6 KiB
C
119 lines
3.6 KiB
C
/*
|
|
* Geforce NV2A PGRAPH Vulkan Renderer
|
|
*
|
|
* Copyright (c) 2024 Matt Borgerson
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "renderer.h"
|
|
|
|
static void create_command_pool(PGRAPHState *pg)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
QueueFamilyIndices indices =
|
|
pgraph_vk_find_queue_families(r->physical_device);
|
|
|
|
VkCommandPoolCreateInfo create_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
|
.queueFamilyIndex = indices.queue_family,
|
|
};
|
|
VK_CHECK(
|
|
vkCreateCommandPool(r->device, &create_info, NULL, &r->command_pool));
|
|
}
|
|
|
|
static void destroy_command_pool(PGRAPHState *pg)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
vkDestroyCommandPool(r->device, r->command_pool, NULL);
|
|
}
|
|
|
|
static void create_command_buffers(PGRAPHState *pg)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
VkCommandBufferAllocateInfo alloc_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
|
.commandPool = r->command_pool,
|
|
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
|
.commandBufferCount = ARRAY_SIZE(r->command_buffers),
|
|
};
|
|
VK_CHECK(
|
|
vkAllocateCommandBuffers(r->device, &alloc_info, r->command_buffers));
|
|
|
|
r->command_buffer = r->command_buffers[0];
|
|
r->aux_command_buffer = r->command_buffers[1];
|
|
}
|
|
|
|
static void destroy_command_buffers(PGRAPHState *pg)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
vkFreeCommandBuffers(r->device, r->command_pool,
|
|
ARRAY_SIZE(r->command_buffers), r->command_buffers);
|
|
|
|
r->command_buffer = VK_NULL_HANDLE;
|
|
r->aux_command_buffer = VK_NULL_HANDLE;
|
|
}
|
|
|
|
VkCommandBuffer pgraph_vk_begin_single_time_commands(PGRAPHState *pg)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
assert(!r->in_aux_command_buffer);
|
|
r->in_aux_command_buffer = true;
|
|
|
|
VkCommandBufferBeginInfo begin_info = {
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
|
};
|
|
VK_CHECK(vkBeginCommandBuffer(r->aux_command_buffer, &begin_info));
|
|
|
|
return r->aux_command_buffer;
|
|
}
|
|
|
|
void pgraph_vk_end_single_time_commands(PGRAPHState *pg, VkCommandBuffer cmd)
|
|
{
|
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
|
|
|
assert(r->in_aux_command_buffer);
|
|
|
|
VK_CHECK(vkEndCommandBuffer(cmd));
|
|
|
|
VkSubmitInfo submit_info = {
|
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
|
.commandBufferCount = 1,
|
|
.pCommandBuffers = &cmd,
|
|
};
|
|
VK_CHECK(vkQueueSubmit(r->queue, 1, &submit_info, VK_NULL_HANDLE));
|
|
nv2a_profile_inc_counter(NV2A_PROF_QUEUE_SUBMIT_AUX);
|
|
VK_CHECK(vkQueueWaitIdle(r->queue));
|
|
|
|
r->in_aux_command_buffer = false;
|
|
}
|
|
|
|
void pgraph_vk_init_command_buffers(PGRAPHState *pg)
|
|
{
|
|
create_command_pool(pg);
|
|
create_command_buffers(pg);
|
|
}
|
|
|
|
void pgraph_vk_finalize_command_buffers(PGRAPHState *pg)
|
|
{
|
|
destroy_command_buffers(pg);
|
|
destroy_command_pool(pg);
|
|
} |