Vulkan: Add Vulkan backend to GLX context.

Also fixes some snags with libretro-test-vulkan.
This commit is contained in:
Hans-Kristian Arntzen 2016-02-19 21:37:24 +01:00
parent 1b5cc1ca9c
commit 88ec0f522b
6 changed files with 482 additions and 274 deletions

View File

@ -42,11 +42,11 @@ struct vulkan_data
VkPipelineLayout pipeline_layout;
VkRenderPass render_pass;
VkPipeline pipeline;
VkCommandPool cmd_pool;
struct retro_vulkan_image images[MAX_SYNC];
VkDeviceMemory image_memory[MAX_SYNC];
VkFramebuffer framebuffers[MAX_SYNC];
VkCommandPool cmd_pool[MAX_SYNC];
VkCommandBuffer cmd[MAX_SYNC];
};
static struct vulkan_data vk;
@ -178,14 +178,14 @@ static void vulkan_test_render(void)
update_ubo();
VkCommandBuffer cmd = vk.cmd[vk.index];
vkResetCommandBuffer(cmd, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
vkResetCommandPool(vulkan->device, vk.cmd_pool[vk.index], 0);
VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(cmd, &begin_info);
VkImageMemoryBarrier prepare_rendering = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
prepare_rendering.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
prepare_rendering.srcAccessMask = 0;
prepare_rendering.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
prepare_rendering.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
prepare_rendering.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -237,15 +237,6 @@ static void vulkan_test_render(void)
scissor.extent.height = BASE_HEIGHT;
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkCmdSetLineWidth(cmd, 1.0f);
vkCmdSetDepthBias(cmd, 0.0f, 0.0f, 0.0f);
vkCmdSetDepthBounds(cmd, 0.0f, 1.0f);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT, 0xff);
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT, 0xff);
vkCmdSetStencilReference(cmd, VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT, 0);
static const float blend_const[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
vkCmdSetBlendConstants(cmd, blend_const);
VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(cmd, 0, 1, &vk.vbo.buffer, &offset);
@ -431,6 +422,7 @@ static void init_pipeline(void)
raster.depthClampEnable = false;
raster.rasterizerDiscardEnable = false;
raster.depthBiasEnable = false;
raster.lineWidth = 1.0f;
VkPipelineColorBlendAttachmentState blend_attachment = { 0 };
blend_attachment.blendEnable = false;
@ -456,13 +448,6 @@ static void init_pipeline(void)
static const VkDynamicState dynamics[] = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_LINE_WIDTH,
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
};
VkPipelineDynamicStateCreateInfo dynamic = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
dynamic.pDynamicStates = dynamics;
@ -542,7 +527,7 @@ static void init_swapchain(void)
image.extent.height = BASE_HEIGHT;
image.extent.depth = 1;
image.samples = VK_SAMPLE_COUNT_1_BIT;
image.tiling = VK_IMAGE_TILING_LINEAR; /* Workaround. */
image.tiling = VK_IMAGE_TILING_OPTIMAL;
image.usage =
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
@ -559,7 +544,7 @@ static void init_swapchain(void)
vkGetImageMemoryRequirements(device, vk.images[i].create_info.image, &mem_reqs);
alloc.allocationSize = mem_reqs.size;
alloc.memoryTypeIndex = find_memory_type_from_requirements(
mem_reqs.memoryTypeBits, 0);
mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkAllocateMemory(device, &alloc, NULL, &vk.image_memory[i]);
vkBindImageMemory(device, vk.images[i].create_info.image, vk.image_memory[i], 0);
@ -597,13 +582,15 @@ static void init_command(void)
VkCommandBufferAllocateInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
pool_info.queueFamilyIndex = vulkan->queue_index;
pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
vkCreateCommandPool(vulkan->device, &pool_info, NULL, &vk.cmd_pool);
info.commandPool = vk.cmd_pool;
for (unsigned i = 0; i < vk.num_swapchain_images; i++)
{
vkCreateCommandPool(vulkan->device, &pool_info, NULL, &vk.cmd_pool[i]);
info.commandPool = vk.cmd_pool[i];
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = vk.num_swapchain_images;
vkAllocateCommandBuffers(vulkan->device, &info, vk.cmd);
info.commandBufferCount = 1;
vkAllocateCommandBuffers(vulkan->device, &info, &vk.cmd[i]);
}
}
static void vulkan_test_init(void)
@ -660,8 +647,11 @@ static void vulkan_test_deinit(void)
vkDestroyBuffer(device, vk.vbo.buffer, NULL);
vkDestroyPipelineCache(device, vk.pipeline_cache, NULL);
vkFreeCommandBuffers(device, vk.cmd_pool, vk.num_swapchain_images, vk.cmd);
vkDestroyCommandPool(device, vk.cmd_pool, NULL);
for (unsigned i = 0; i < vk.num_swapchain_images; i++)
{
vkFreeCommandBuffers(device, vk.cmd_pool[i], 1, &vk.cmd[i]);
vkDestroyCommandPool(device, vk.cmd_pool[i], NULL);
}
memset(&vk, 0, sizeof(vk));
}

View File

@ -6,7 +6,7 @@ unsigned char triangle_frag_spv[] = {
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x01, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
@ -17,7 +17,8 @@ unsigned char triangle_frag_spv[] = {
0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
@ -34,4 +35,4 @@ unsigned char triangle_frag_spv[] = {
0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
0x38, 0x00, 0x01, 0x00
};
unsigned int triangle_frag_spv_len = 400;
unsigned int triangle_frag_spv_len = 412;

View File

@ -1,34 +1,30 @@
unsigned char triangle_vert_spv[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x01, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50,
0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00,
0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x55, 0x42, 0x4f, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4d, 0x56, 0x50, 0x00, 0x05, 0x00, 0x03, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
0x15, 0x00, 0x00, 0x00, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00,
0x05, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x56,
0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x44, 0x00, 0x05, 0x00, 0x06, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x49, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
0x36, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x08, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65,
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50,
0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00,
0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50,
0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x55, 0x42, 0x4f, 0x00,
0x06, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4d, 0x56, 0x50, 0x00, 0x05, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x76, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00,
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
@ -45,50 +41,43 @@ unsigned char triangle_vert_spv[] = {
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x1a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3b, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x3b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00,
0x1f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
0x19, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
0x3e, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00,
0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
0x14, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
0x05, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x3e, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
};
unsigned int triangle_vert_spv_len = 1088;
unsigned int triangle_vert_spv_len = 960;

View File

@ -1168,7 +1168,7 @@ void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk,
vk->fpDestroySwapchainKHR(vk->context.device,
vk->swapchain, NULL);
if (destroy_surface)
if (destroy_surface && vk->vk_surface != VK_NULL_HANDLE)
vk->fpDestroySurfaceKHR(vk->context.instance,
vk->vk_surface, NULL);

View File

@ -24,6 +24,10 @@
#include "../common/gl_common.h"
#include "../common/x11_common.h"
#ifdef HAVE_VULKAN
#include "../common/vulkan_common.h"
#endif
static int (*g_pglSwapInterval)(int);
static int (*g_pglSwapIntervalSGI)(int);
static void (*g_pglSwapIntervalEXT)(Display*, GLXDrawable, int);
@ -46,10 +50,14 @@ typedef struct gfx_ctx_glx_data
XF86VidModeModeInfo g_desktop_mode;
#ifdef HAVE_VULKAN
gfx_ctx_vulkan_data_t vk;
#endif
} gfx_ctx_glx_data_t;
static unsigned g_major;
static unsigned g_minor;
static enum gfx_ctx_api g_api;
static PFNGLXCREATECONTEXTATTRIBSARBPROC glx_create_context_attribs;
@ -67,9 +75,14 @@ static void ctx_glx_destroy_resources(gfx_ctx_glx_data_t *glx)
x11_input_ctx_destroy();
if (g_x11_dpy && glx->g_ctx)
if (g_x11_dpy)
{
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
if (glx->g_ctx)
{
glFinish();
glXMakeContextCurrent(g_x11_dpy, None, None, NULL);
@ -82,9 +95,23 @@ static void ctx_glx_destroy_resources(gfx_ctx_glx_data_t *glx)
glx->g_hw_ctx = NULL;
}
}
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
vulkan_context_destroy(&glx->vk, g_x11_win != 0);
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
}
if (g_x11_win)
{
if (glx->g_glx_win)
glXDestroyWindow(g_x11_dpy, glx->g_glx_win);
glx->g_glx_win = 0;
@ -118,13 +145,24 @@ static void ctx_glx_destroy_resources(gfx_ctx_glx_data_t *glx)
static void gfx_ctx_glx_destroy(void *data)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
if (!glx)
return;
(void)data;
ctx_glx_destroy_resources(glx);
switch (g_api)
{
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
if (glx->vk.context.queue_lock)
slock_free(glx->vk.context.queue_lock);
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
free(data);
}
@ -132,6 +170,10 @@ static void gfx_ctx_glx_swap_interval(void *data, unsigned interval)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx->g_interval = interval;
if (g_pglSwapIntervalEXT)
@ -151,22 +193,100 @@ static void gfx_ctx_glx_swap_interval(void *data, unsigned interval)
if (g_pglSwapIntervalSGI(glx->g_interval) != 0)
RARCH_WARN("[GLX]: glXSwapIntervalSGI() failed.\n");
}
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
if (glx->g_interval != interval)
{
glx->g_interval = interval;
if (glx->vk.swapchain)
glx->vk.need_new_swapchain = true;
}
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
}
static void gfx_ctx_glx_swap_buffers(void *data)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
if (glx->g_is_double)
glXSwapBuffers(g_x11_dpy, glx->g_glx_win);
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
vulkan_present(&glx->vk, glx->vk.context.current_swapchain_index);
vulkan_acquire_next_image(&glx->vk);
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
}
static void gfx_ctx_glx_check_window(void *data, bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
(void)glx;
x11_check_window(data, quit, resize, width, height, frame_count);
switch (g_api)
{
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
glx->vk.need_new_swapchain = *resize;
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
}
static bool gfx_ctx_glx_set_resize(void *data,
unsigned width, unsigned height)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
(void)data;
(void)width;
(void)height;
switch (g_api)
{
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
if (vulkan_create_swapchain(&glx->vk, width, height, glx->g_interval))
glx->vk.context.invalid_swapchain = true;
else
{
RARCH_ERR("[X/Vulkan]: Failed to update swapchain.\n");
return false;
}
glx->vk.need_new_swapchain = false;
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
return false;
}
@ -208,6 +328,10 @@ static void *gfx_ctx_glx_init(void *data)
if ((major * 1000 + minor) < 1003)
goto error;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx_create_context_attribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
@ -244,6 +368,19 @@ static void *gfx_ctx_glx_init(void *data)
glx->g_fbc = fbcs[0];
XFree(fbcs);
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
/* Use XCB WSI since it's the most supported WSI over legacy Xlib. */
if (!vulkan_context_init(&glx->vk, VULKAN_WSI_XCB))
goto error;
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
return glx;
error:
@ -277,9 +414,29 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
windowed_full = settings->video.windowed_fullscreen;
true_full = false;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
vi = glXGetVisualFromFBConfig(g_x11_dpy, glx->g_fbc);
if (!vi)
goto error;
break;
case GFX_CTX_NONE:
default:
{
/* For default case, just try to obtain a visual from template. */
XVisualInfo template;
int nvisuals = 0;
memset(&template, 0, sizeof(template));
template.screen = DefaultScreen(g_x11_dpy);
vi = XGetVisualInfo(g_x11_dpy, VisualScreenMask, &template, &nvisuals);
if (!vi || nvisuals < 1)
goto error;
break;
}
}
swa.colormap = g_x11_cmap = XCreateColormap(g_x11_dpy,
RootWindow(g_x11_dpy, vi->screen), vi->visual, AllocNone);
@ -331,7 +488,17 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
(true_full ? CWOverrideRedirect : 0), &swa);
XSetWindowBackground(g_x11_dpy, g_x11_win, 0);
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx->g_glx_win = glXCreateWindow(g_x11_dpy, glx->g_fbc, g_x11_win, 0);
break;
case GFX_CTX_NONE:
default:
break;
}
x11_set_window_attr(g_x11_dpy, g_x11_win);
@ -371,6 +538,10 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
x11_event_queue_check(&event);
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
if (!glx->g_ctx)
{
if (glx->g_core_es || glx->g_debug)
@ -447,10 +618,38 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
glXMakeContextCurrent(g_x11_dpy,
glx->g_glx_win, glx->g_glx_win, glx->g_ctx);
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
{
bool quit, resize;
unsigned width, height;
x11_check_window(glx, &quit, &resize, &width, &height, 0);
/* Use XCB surface since it's the most supported WSI.
* We can obtain the XCB connection directly from X11. */
if (!vulkan_surface_create(&glx->vk, VULKAN_WSI_XCB,
g_x11_dpy, &g_x11_win,
width, height, glx->g_interval))
goto error;
}
#endif
break;
case GFX_CTX_NONE:
default:
break;
}
XSync(g_x11_dpy, False);
x11_install_quit_atom();
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glXGetConfig(g_x11_dpy, vi, GLX_DOUBLEBUFFER, &val);
glx->g_is_double = val;
@ -479,6 +678,12 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
}
else
RARCH_WARN("[GLX]: Context is not double buffered!.\n");
break;
case GFX_CTX_NONE:
default:
break;
}
gfx_ctx_glx_swap_interval(data, glx->g_interval);
@ -509,7 +714,6 @@ error:
return false;
}
static void gfx_ctx_glx_input_driver(void *data,
const input_driver_t **input, void **input_data)
{
@ -539,7 +743,18 @@ static bool gfx_ctx_glx_has_windowed(void *data)
static gfx_ctx_proc_t gfx_ctx_glx_get_proc_address(const char *symbol)
{
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
return glXGetProcAddress((const GLubyte*)symbol);
case GFX_CTX_NONE:
default:
break;
}
return NULL;
}
static bool gfx_ctx_glx_bind_api(void *data, enum gfx_ctx_api api,
@ -549,6 +764,15 @@ static bool gfx_ctx_glx_bind_api(void *data, enum gfx_ctx_api api,
g_major = major;
g_minor = minor;
g_api = api;
#ifdef HAVE_VULKAN
if (api == GFX_CTX_VULKAN_API)
{
g_api = api;
return true;
}
#endif
#ifdef HAVE_OPENGLES2
Display *dpy = XOpenDisplay(NULL);
@ -561,8 +785,10 @@ static bool gfx_ctx_glx_bind_api(void *data, enum gfx_ctx_api api,
g_major = 2; /* ES 2.0. */
g_minor = 0;
}
g_api = GFX_CTX_OPENGL_ES_API;
return ret;
#else
g_api = GFX_CTX_OPENGL_API;
return api == GFX_CTX_OPENGL_API;
#endif
}
@ -579,17 +805,31 @@ static void gfx_ctx_glx_bind_hw_render(void *data, bool enable)
if (!glx)
return;
(void)data;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx->g_use_hw_ctx = enable;
if (!g_x11_dpy || !glx->g_glx_win)
return;
glXMakeContextCurrent(g_x11_dpy, glx->g_glx_win,
glx->g_glx_win, enable ? glx->g_hw_ctx : glx->g_ctx);
break;
case GFX_CTX_NONE:
default:
break;
}
}
#ifdef HAVE_VULKAN
static void *gfx_ctx_glx_get_context_data(void *data)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
return &glx->vk.context;
}
#endif
const gfx_ctx_driver_t gfx_ctx_glx = {
gfx_ctx_glx_init,
gfx_ctx_glx_destroy,
@ -603,7 +843,7 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
x11_get_metrics,
NULL,
x11_update_window_title,
x11_check_window,
gfx_ctx_glx_check_window,
gfx_ctx_glx_set_resize,
x11_has_focus,
gfx_ctx_glx_suppress_screensaver,
@ -617,5 +857,10 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
"glx",
gfx_ctx_glx_bind_hw_render,
#ifdef HAVE_VULKAN
gfx_ctx_glx_get_context_data,
#else
NULL
#endif
};

View File

@ -143,25 +143,8 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
(void)version;
if (string_is_equal(interface, "wl_compositor"))
{
unsigned num = 1;
switch (wl_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
case GFX_CTX_OPENVG_API:
break;
case GFX_CTX_VULKAN_API:
num = 3;
break;
case GFX_CTX_NONE:
default:
break;
}
wl->compositor = (struct wl_compositor*)wl_registry_bind(reg,
id, &wl_compositor_interface, num);
}
id, &wl_compositor_interface, 3);
else if (string_is_equal(interface, "wl_shell"))
wl->shell = (struct wl_shell*)
wl_registry_bind(reg, id, &wl_shell_interface, 1);