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;
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = vk.num_swapchain_images;
vkAllocateCommandBuffers(vulkan->device, &info, vk.cmd);
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 = 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,25 +75,44 @@ 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)
{
glFinish();
glXMakeContextCurrent(g_x11_dpy, None, None, NULL);
if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL))
switch (g_api)
{
if (glx->g_hw_ctx)
glXDestroyContext(g_x11_dpy, glx->g_hw_ctx);
glXDestroyContext(g_x11_dpy, glx->g_ctx);
glx->g_ctx = NULL;
glx->g_hw_ctx = NULL;
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
if (glx->g_ctx)
{
glFinish();
glXMakeContextCurrent(g_x11_dpy, None, None, NULL);
if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL))
{
if (glx->g_hw_ctx)
glXDestroyContext(g_x11_dpy, glx->g_hw_ctx);
glXDestroyContext(g_x11_dpy, glx->g_ctx);
glx->g_ctx = NULL;
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)
{
glXDestroyWindow(g_x11_dpy, glx->g_glx_win);
if (glx->g_glx_win)
glXDestroyWindow(g_x11_dpy, glx->g_glx_win);
glx->g_glx_win = 0;
/* Save last used monitor for later. */
@ -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,24 +170,45 @@ static void gfx_ctx_glx_swap_interval(void *data, unsigned interval)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
glx->g_interval = interval;
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx->g_interval = interval;
if (g_pglSwapIntervalEXT)
{
RARCH_LOG("[GLX]: glXSwapIntervalEXT(%u)\n", glx->g_interval);
g_pglSwapIntervalEXT(g_x11_dpy, glx->g_glx_win, glx->g_interval);
}
else if (g_pglSwapInterval)
{
RARCH_LOG("[GLX]: glXSwapInterval(%u)\n", glx->g_interval);
if (g_pglSwapInterval(glx->g_interval) != 0)
RARCH_WARN("[GLX]: glXSwapInterval() failed.\n");
}
else if (g_pglSwapIntervalSGI)
{
RARCH_LOG("[GLX]: glXSwapIntervalSGI(%u)\n", glx->g_interval);
if (g_pglSwapIntervalSGI(glx->g_interval) != 0)
RARCH_WARN("[GLX]: glXSwapIntervalSGI() failed.\n");
if (g_pglSwapIntervalEXT)
{
RARCH_LOG("[GLX]: glXSwapIntervalEXT(%u)\n", glx->g_interval);
g_pglSwapIntervalEXT(g_x11_dpy, glx->g_glx_win, glx->g_interval);
}
else if (g_pglSwapInterval)
{
RARCH_LOG("[GLX]: glXSwapInterval(%u)\n", glx->g_interval);
if (g_pglSwapInterval(glx->g_interval) != 0)
RARCH_WARN("[GLX]: glXSwapInterval() failed.\n");
}
else if (g_pglSwapIntervalSGI)
{
RARCH_LOG("[GLX]: glXSwapIntervalSGI(%u)\n", glx->g_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;
}
}
@ -157,16 +216,77 @@ static void gfx_ctx_glx_swap_buffers(void *data)
{
gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)data;
if (glx->g_is_double)
glXSwapBuffers(g_x11_dpy, glx->g_glx_win);
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,42 +328,59 @@ static void *gfx_ctx_glx_init(void *data)
if ((major * 1000 + minor) < 1003)
goto error;
glx_create_context_attribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
switch (g_api)
{
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glx_create_context_attribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
#ifdef GL_DEBUG
glx->g_debug = true;
glx->g_debug = true;
#else
glx->g_debug = hw_render->debug_context;
glx->g_debug = hw_render->debug_context;
#endif
/* Have to use ContextAttribs */
/* Have to use ContextAttribs */
#ifdef HAVE_OPENGLES2
glx->g_core_es = true;
glx->g_core_es_core = true;
glx->g_core_es = true;
glx->g_core_es_core = true;
#else
glx->g_core_es = (g_major * 1000 + g_minor) >= 3001;
glx->g_core_es_core = (g_major * 1000 + g_minor) >= 3002;
glx->g_core_es = (g_major * 1000 + g_minor) >= 3001;
glx->g_core_es_core = (g_major * 1000 + g_minor) >= 3002;
#endif
if ((glx->g_core_es || glx->g_debug) && !glx_create_context_attribs)
goto error;
if ((glx->g_core_es || glx->g_debug) && !glx_create_context_attribs)
goto error;
fbcs = glXChooseFBConfig(g_x11_dpy, DefaultScreen(g_x11_dpy),
visual_attribs, &nelements);
fbcs = glXChooseFBConfig(g_x11_dpy, DefaultScreen(g_x11_dpy),
visual_attribs, &nelements);
if (!fbcs)
goto error;
if (!fbcs)
goto error;
if (!nelements)
{
XFree(fbcs);
goto error;
if (!nelements)
{
XFree(fbcs);
goto error;
}
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;
}
glx->g_fbc = fbcs[0];
XFree(fbcs);
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;
vi = glXGetVisualFromFBConfig(g_x11_dpy, glx->g_fbc);
if (!vi)
goto error;
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);
glx->g_glx_win = glXCreateWindow(g_x11_dpy, glx->g_fbc, 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,114 +538,152 @@ static bool gfx_ctx_glx_set_video_mode(void *data,
x11_event_queue_check(&event);
if (!glx->g_ctx)
switch (g_api)
{
if (glx->g_core_es || glx->g_debug)
{
int attribs[16];
int *aptr = attribs;
if (glx->g_core_es)
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
if (!glx->g_ctx)
{
*aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB;
*aptr++ = g_major;
*aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB;
*aptr++ = g_minor;
if (glx->g_core_es_core)
if (glx->g_core_es || glx->g_debug)
{
/* Technically, we don't have core/compat until 3.2.
* Version 3.1 is either compat or not depending on
* GL_ARB_compatibility.
*/
*aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB;
int attribs[16];
int *aptr = attribs;
if (glx->g_core_es)
{
*aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB;
*aptr++ = g_major;
*aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB;
*aptr++ = g_minor;
if (glx->g_core_es_core)
{
/* Technically, we don't have core/compat until 3.2.
* Version 3.1 is either compat or not depending on
* GL_ARB_compatibility.
*/
*aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB;
#ifdef HAVE_OPENGLES2
*aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT;
*aptr++ = GLX_CONTEXT_ES_PROFILE_BIT_EXT;
#else
*aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
*aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
#endif
}
}
if (glx->g_debug)
{
*aptr++ = GLX_CONTEXT_FLAGS_ARB;
*aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB;
}
*aptr = None;
glx->g_ctx = glx_create_context_attribs(g_x11_dpy,
glx->g_fbc, NULL, True, attribs);
if (glx->g_use_hw_ctx)
{
RARCH_LOG("[GLX]: Creating shared HW context.\n");
glx->g_hw_ctx = glx_create_context_attribs(g_x11_dpy,
glx->g_fbc, glx->g_ctx, True, attribs);
if (!glx->g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
}
}
else
{
glx->g_ctx = glXCreateNewContext(g_x11_dpy, glx->g_fbc,
GLX_RGBA_TYPE, 0, True);
if (glx->g_use_hw_ctx)
{
glx->g_hw_ctx = glXCreateNewContext(g_x11_dpy, glx->g_fbc,
GLX_RGBA_TYPE, glx->g_ctx, True);
if (!glx->g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
}
}
if (!glx->g_ctx)
{
RARCH_ERR("[GLX]: Failed to create new context.\n");
goto error;
}
}
if (glx->g_debug)
else
{
*aptr++ = GLX_CONTEXT_FLAGS_ARB;
*aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB;
video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL);
RARCH_LOG("[GLX]: Using cached GL context.\n");
}
*aptr = None;
glx->g_ctx = glx_create_context_attribs(g_x11_dpy,
glx->g_fbc, NULL, True, attribs);
glXMakeContextCurrent(g_x11_dpy,
glx->g_glx_win, glx->g_glx_win, glx->g_ctx);
break;
if (glx->g_use_hw_ctx)
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
{
RARCH_LOG("[GLX]: Creating shared HW context.\n");
glx->g_hw_ctx = glx_create_context_attribs(g_x11_dpy,
glx->g_fbc, glx->g_ctx, True, attribs);
bool quit, resize;
unsigned width, height;
x11_check_window(glx, &quit, &resize, &width, &height, 0);
if (!glx->g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
/* 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;
}
}
else
{
glx->g_ctx = glXCreateNewContext(g_x11_dpy, glx->g_fbc,
GLX_RGBA_TYPE, 0, True);
if (glx->g_use_hw_ctx)
{
glx->g_hw_ctx = glXCreateNewContext(g_x11_dpy, glx->g_fbc,
GLX_RGBA_TYPE, glx->g_ctx, True);
if (!glx->g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
}
}
#endif
break;
if (!glx->g_ctx)
{
RARCH_ERR("[GLX]: Failed to create new context.\n");
goto error;
}
}
else
{
video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL);
RARCH_LOG("[GLX]: Using cached GL context.\n");
case GFX_CTX_NONE:
default:
break;
}
glXMakeContextCurrent(g_x11_dpy,
glx->g_glx_win, glx->g_glx_win, glx->g_ctx);
XSync(g_x11_dpy, False);
x11_install_quit_atom();
glXGetConfig(g_x11_dpy, vi, GLX_DOUBLEBUFFER, &val);
glx->g_is_double = val;
if (glx->g_is_double)
switch (g_api)
{
const char *swap_func = NULL;
case GFX_CTX_OPENGL_API:
case GFX_CTX_OPENGL_ES_API:
glXGetConfig(g_x11_dpy, vi, GLX_DOUBLEBUFFER, &val);
glx->g_is_double = val;
g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
g_pglSwapIntervalSGI = (int (*)(int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
g_pglSwapInterval = (int (*)(int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");
if (glx->g_is_double)
{
const char *swap_func = NULL;
if (g_pglSwapIntervalEXT)
swap_func = "glXSwapIntervalEXT";
else if (g_pglSwapInterval)
swap_func = "glXSwapIntervalMESA";
else if (g_pglSwapIntervalSGI)
swap_func = "glXSwapIntervalSGI";
g_pglSwapIntervalEXT = (void (*)(Display*, GLXDrawable, int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
g_pglSwapIntervalSGI = (int (*)(int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI");
g_pglSwapInterval = (int (*)(int))
glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");
if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI)
RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
else
RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func);
if (g_pglSwapIntervalEXT)
swap_func = "glXSwapIntervalEXT";
else if (g_pglSwapInterval)
swap_func = "glXSwapIntervalMESA";
else if (g_pglSwapIntervalSGI)
swap_func = "glXSwapIntervalSGI";
if (!g_pglSwapInterval && !g_pglSwapIntervalEXT && !g_pglSwapIntervalSGI)
RARCH_WARN("[GLX]: Cannot find swap interval call.\n");
else
RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func);
}
else
RARCH_WARN("[GLX]: Context is not double buffered!.\n");
break;
case GFX_CTX_NONE:
default:
break;
}
else
RARCH_WARN("[GLX]: Context is not double buffered!.\n");
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)
{
return glXGetProcAddress((const GLubyte*)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;
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);
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);