mirror of
https://github.com/libretro/RetroArch
synced 2025-04-15 23:42:30 +00:00
Merge branch 'master' of git://github.com/libretro/RetroArch
This commit is contained in:
commit
4259ea3d06
@ -173,25 +173,27 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
VkFormat format,
|
VkFormat format,
|
||||||
const void *initial, const VkComponentMapping *swizzle, enum vk_texture_type type)
|
const void *initial, const VkComponentMapping *swizzle, enum vk_texture_type type)
|
||||||
{
|
{
|
||||||
VkDevice device = vk->context->device;
|
|
||||||
struct vk_texture tex;
|
struct vk_texture tex;
|
||||||
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
|
||||||
|
|
||||||
VkImageViewCreateInfo view = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
|
||||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
|
||||||
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT };
|
|
||||||
VkMemoryRequirements mem_reqs;
|
VkMemoryRequirements mem_reqs;
|
||||||
VkSubresourceLayout layout;
|
VkSubresourceLayout layout;
|
||||||
|
VkDevice device = vk->context->device;
|
||||||
|
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||||
|
VkImageViewCreateInfo view = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||||
|
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||||
|
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT };
|
||||||
|
VkCommandBufferAllocateInfo cmd_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
||||||
|
VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||||
|
VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||||
|
|
||||||
memset(&tex, 0, sizeof(tex));
|
memset(&tex, 0, sizeof(tex));
|
||||||
|
|
||||||
info.imageType = VK_IMAGE_TYPE_2D;
|
info.imageType = VK_IMAGE_TYPE_2D;
|
||||||
info.format = format;
|
info.format = format;
|
||||||
info.extent.width = width;
|
info.extent.width = width;
|
||||||
info.extent.height = height;
|
info.extent.height = height;
|
||||||
info.extent.depth = 1;
|
info.extent.depth = 1;
|
||||||
info.mipLevels = 1;
|
info.mipLevels = 1;
|
||||||
info.arrayLayers = 1;
|
info.arrayLayers = 1;
|
||||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
if (type == VULKAN_TEXTURE_STREAMED)
|
if (type == VULKAN_TEXTURE_STREAMED)
|
||||||
@ -309,7 +311,7 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
old->memory_size >= mem_reqs.size &&
|
old->memory_size >= mem_reqs.size &&
|
||||||
old->memory_type == alloc.memoryTypeIndex)
|
old->memory_type == alloc.memoryTypeIndex)
|
||||||
{
|
{
|
||||||
tex.memory = old->memory;
|
tex.memory = old->memory;
|
||||||
tex.memory_size = old->memory_size;
|
tex.memory_size = old->memory_size;
|
||||||
tex.memory_type = old->memory_type;
|
tex.memory_type = old->memory_type;
|
||||||
|
|
||||||
@ -333,17 +335,17 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
|
|
||||||
vkBindImageMemory(device, tex.image, tex.memory, 0);
|
vkBindImageMemory(device, tex.image, tex.memory, 0);
|
||||||
|
|
||||||
view.image = tex.image;
|
view.image = tex.image;
|
||||||
view.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
view.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
view.format = format;
|
view.format = format;
|
||||||
if (swizzle)
|
if (swizzle)
|
||||||
view.components = *swizzle;
|
view.components = *swizzle;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
view.components.r = VK_COMPONENT_SWIZZLE_R;
|
view.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||||
view.components.g = VK_COMPONENT_SWIZZLE_G;
|
view.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||||
view.components.b = VK_COMPONENT_SWIZZLE_B;
|
view.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||||
view.components.a = VK_COMPONENT_SWIZZLE_A;
|
view.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||||
}
|
}
|
||||||
view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
view.subresourceRange.levelCount = 1;
|
view.subresourceRange.levelCount = 1;
|
||||||
@ -354,27 +356,27 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
vkGetImageSubresourceLayout(device, tex.image, &subresource, &layout);
|
vkGetImageSubresourceLayout(device, tex.image, &subresource, &layout);
|
||||||
tex.stride = layout.rowPitch;
|
tex.stride = layout.rowPitch;
|
||||||
tex.offset = layout.offset;
|
tex.offset = layout.offset;
|
||||||
tex.size = layout.size;
|
tex.size = layout.size;
|
||||||
tex.layout = info.initialLayout;
|
tex.layout = info.initialLayout;
|
||||||
|
|
||||||
tex.width = width;
|
tex.width = width;
|
||||||
tex.height = height;
|
tex.height = height;
|
||||||
tex.format = format;
|
tex.format = format;
|
||||||
tex.type = type;
|
tex.type = type;
|
||||||
|
|
||||||
if (initial && type == VULKAN_TEXTURE_STREAMED)
|
if (initial && type == VULKAN_TEXTURE_STREAMED)
|
||||||
{
|
{
|
||||||
unsigned bpp = vulkan_format_to_bpp(tex.format);
|
|
||||||
unsigned stride = tex.width * bpp;
|
|
||||||
unsigned x, y;
|
unsigned x, y;
|
||||||
uint8_t *dst;
|
uint8_t *dst = NULL;
|
||||||
const uint8_t *src;
|
const uint8_t *src = NULL;
|
||||||
void *ptr;
|
void *ptr = NULL;
|
||||||
|
unsigned bpp = vulkan_format_to_bpp(tex.format);
|
||||||
|
unsigned stride = tex.width * bpp;
|
||||||
|
|
||||||
vkMapMemory(device, tex.memory, tex.offset, tex.size, 0, &ptr);
|
vkMapMemory(device, tex.memory, tex.offset, tex.size, 0, &ptr);
|
||||||
|
|
||||||
dst = (uint8_t*)ptr;
|
dst = (uint8_t*)ptr;
|
||||||
src = (const uint8_t*)initial;
|
src = (const uint8_t*)initial;
|
||||||
for (y = 0; y < tex.height; y++, dst += tex.stride, src += stride)
|
for (y = 0; y < tex.height; y++, dst += tex.stride, src += stride)
|
||||||
memcpy(dst, src, width * bpp);
|
memcpy(dst, src, width * bpp);
|
||||||
|
|
||||||
@ -382,22 +384,18 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
}
|
}
|
||||||
else if (initial && type == VULKAN_TEXTURE_STATIC)
|
else if (initial && type == VULKAN_TEXTURE_STATIC)
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
|
||||||
VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
|
||||||
VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
|
||||||
VkImageCopy region;
|
VkImageCopy region;
|
||||||
|
|
||||||
VkCommandBuffer staging;
|
VkCommandBuffer staging;
|
||||||
unsigned bpp = vulkan_format_to_bpp(tex.format);
|
unsigned bpp = vulkan_format_to_bpp(tex.format);
|
||||||
struct vk_texture tmp = vulkan_create_texture(vk, NULL,
|
struct vk_texture tmp = vulkan_create_texture(vk, NULL,
|
||||||
width, height, format, initial, NULL, VULKAN_TEXTURE_STAGING);
|
width, height, format, initial, NULL, VULKAN_TEXTURE_STAGING);
|
||||||
|
|
||||||
info.commandPool = vk->staging_pool;
|
cmd_info.commandPool = vk->staging_pool;
|
||||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
cmd_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
info.commandBufferCount = 1;
|
cmd_info.commandBufferCount = 1;
|
||||||
vkAllocateCommandBuffers(vk->context->device, &info, &staging);
|
vkAllocateCommandBuffers(vk->context->device, &cmd_info, &staging);
|
||||||
|
|
||||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
vkBeginCommandBuffer(staging, &begin_info);
|
vkBeginCommandBuffer(staging, &begin_info);
|
||||||
|
|
||||||
vulkan_image_layout_transition(vk, staging, tmp.image,
|
vulkan_image_layout_transition(vk, staging, tmp.image,
|
||||||
@ -413,12 +411,12 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
|
||||||
memset(®ion, 0, sizeof(region));
|
memset(®ion, 0, sizeof(region));
|
||||||
region.extent.width = width;
|
region.extent.width = width;
|
||||||
region.extent.height = height;
|
region.extent.height = height;
|
||||||
region.extent.depth = 1;
|
region.extent.depth = 1;
|
||||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
region.srcSubresource.layerCount = 1;
|
region.srcSubresource.layerCount = 1;
|
||||||
region.dstSubresource = region.srcSubresource;
|
region.dstSubresource = region.srcSubresource;
|
||||||
|
|
||||||
vkCmdCopyImage(staging,
|
vkCmdCopyImage(staging,
|
||||||
tmp.image, VK_IMAGE_LAYOUT_GENERAL,
|
tmp.image, VK_IMAGE_LAYOUT_GENERAL,
|
||||||
@ -426,19 +424,23 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
1, ®ion);
|
1, ®ion);
|
||||||
|
|
||||||
vulkan_image_layout_transition(vk, staging, tex.image,
|
vulkan_image_layout_transition(vk, staging, tex.image,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
VK_ACCESS_SHADER_READ_BIT,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
|
||||||
vkEndCommandBuffer(staging);
|
vkEndCommandBuffer(staging);
|
||||||
submit_info.commandBufferCount = 1;
|
submit_info.commandBufferCount = 1;
|
||||||
submit_info.pCommandBuffers = &staging;
|
submit_info.pCommandBuffers = &staging;
|
||||||
|
|
||||||
slock_lock(vk->context->queue_lock);
|
slock_lock(vk->context->queue_lock);
|
||||||
vkQueueSubmit(vk->context->queue, 1, &submit_info, VK_NULL_HANDLE);
|
vkQueueSubmit(vk->context->queue, 1, &submit_info, VK_NULL_HANDLE);
|
||||||
/* TODO: Very crude, but texture uploads only happen during init,
|
|
||||||
* so waiting for GPU to complete transfer and blocking isn't a big deal. */
|
/* TODO: Very crude, but texture uploads only happen
|
||||||
|
* during init, so waiting for GPU to complete transfer
|
||||||
|
* and blocking isn't a big deal. */
|
||||||
vkQueueWaitIdle(vk->context->queue);
|
vkQueueWaitIdle(vk->context->queue);
|
||||||
slock_unlock(vk->context->queue_lock);
|
slock_unlock(vk->context->queue_lock);
|
||||||
|
|
||||||
@ -474,33 +476,34 @@ static void vulkan_write_quad_descriptors(VkDevice device,
|
|||||||
VkDescriptorImageInfo image_info;
|
VkDescriptorImageInfo image_info;
|
||||||
VkDescriptorBufferInfo buffer_info;
|
VkDescriptorBufferInfo buffer_info;
|
||||||
|
|
||||||
image_info.sampler = sampler;
|
image_info.sampler = sampler;
|
||||||
image_info.imageView = texture->view;
|
image_info.imageView = texture->view;
|
||||||
image_info.imageLayout = texture->layout;
|
image_info.imageLayout = texture->layout;
|
||||||
|
|
||||||
buffer_info.buffer = buffer;
|
buffer_info.buffer = buffer;
|
||||||
buffer_info.offset = offset;
|
buffer_info.offset = offset;
|
||||||
buffer_info.range = range;
|
buffer_info.range = range;
|
||||||
|
|
||||||
write.dstSet = set;
|
write.dstSet = set;
|
||||||
write.dstBinding = 0;
|
write.dstBinding = 0;
|
||||||
write.descriptorCount = 1;
|
write.descriptorCount = 1;
|
||||||
write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
write.pBufferInfo = &buffer_info;
|
write.pBufferInfo = &buffer_info;
|
||||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||||
|
|
||||||
write.dstSet = set;
|
write.dstSet = set;
|
||||||
write.dstBinding = 1;
|
write.dstBinding = 1;
|
||||||
write.descriptorCount = 1;
|
write.descriptorCount = 1;
|
||||||
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
write.pImageInfo = &image_info;
|
write.pImageInfo = &image_info;
|
||||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vulkan_transition_texture(vk_t *vk, struct vk_texture *texture)
|
void vulkan_transition_texture(vk_t *vk, struct vk_texture *texture)
|
||||||
{
|
{
|
||||||
/* Transition to GENERAL layout for linear streamed textures.
|
/* Transition to GENERAL layout for linear streamed textures.
|
||||||
* We're using linear textures here, so only GENERAL layout is supported.
|
* We're using linear textures here, so only
|
||||||
|
* GENERAL layout is supported.
|
||||||
*/
|
*/
|
||||||
if (texture->layout == VK_IMAGE_LAYOUT_PREINITIALIZED)
|
if (texture->layout == VK_IMAGE_LAYOUT_PREINITIALIZED)
|
||||||
{
|
{
|
||||||
@ -517,7 +520,9 @@ static void vulkan_check_dynamic_state(vk_t *vk)
|
|||||||
{
|
{
|
||||||
if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||||
{
|
{
|
||||||
const VkRect2D sci = {{ vk->vp.x, vk->vp.y }, { vk->vp.width, vk->vp.height }};
|
const VkRect2D sci = {
|
||||||
|
{ vk->vp.x, vk->vp.y },
|
||||||
|
{ vk->vp.width, vk->vp.height }};
|
||||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||||
vkCmdSetScissor(vk->cmd, 0, 1, &sci);
|
vkCmdSetScissor(vk->cmd, 0, 1, &sci);
|
||||||
|
|
||||||
@ -531,7 +536,8 @@ void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
|||||||
|
|
||||||
if (call->pipeline != vk->tracker.pipeline)
|
if (call->pipeline != vk->tracker.pipeline)
|
||||||
{
|
{
|
||||||
vkCmdBindPipeline(vk->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, call->pipeline);
|
vkCmdBindPipeline(vk->cmd,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS, call->pipeline);
|
||||||
vk->tracker.pipeline = call->pipeline;
|
vk->tracker.pipeline = call->pipeline;
|
||||||
|
|
||||||
/* Changing pipeline invalidates dynamic state. */
|
/* Changing pipeline invalidates dynamic state. */
|
||||||
@ -544,9 +550,9 @@ void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
|||||||
{
|
{
|
||||||
VkDescriptorSet set;
|
VkDescriptorSet set;
|
||||||
|
|
||||||
if (memcmp(call->mvp, &vk->tracker.mvp, sizeof(*call->mvp)) ||
|
if (memcmp(call->mvp, &vk->tracker.mvp, sizeof(*call->mvp))
|
||||||
call->texture->view != vk->tracker.view ||
|
|| (call->texture->view != vk->tracker.view)
|
||||||
call->sampler != vk->tracker.sampler)
|
|| (call->sampler != vk->tracker.sampler))
|
||||||
{
|
{
|
||||||
/* Upload UBO */
|
/* Upload UBO */
|
||||||
struct vk_buffer_range range;
|
struct vk_buffer_range range;
|
||||||
@ -555,7 +561,8 @@ void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
|||||||
return;
|
return;
|
||||||
memcpy(range.data, call->mvp, sizeof(*call->mvp));
|
memcpy(range.data, call->mvp, sizeof(*call->mvp));
|
||||||
|
|
||||||
set = vulkan_descriptor_manager_alloc(vk->context->device, &vk->chain->descriptor_manager);
|
set = vulkan_descriptor_manager_alloc(
|
||||||
|
vk->context->device, &vk->chain->descriptor_manager);
|
||||||
vulkan_write_quad_descriptors(vk->context->device,
|
vulkan_write_quad_descriptors(vk->context->device,
|
||||||
set,
|
set,
|
||||||
range.buffer,
|
range.buffer,
|
||||||
@ -588,11 +595,12 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
|||||||
|
|
||||||
if (quad->pipeline != vk->tracker.pipeline)
|
if (quad->pipeline != vk->tracker.pipeline)
|
||||||
{
|
{
|
||||||
vkCmdBindPipeline(vk->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, quad->pipeline);
|
vkCmdBindPipeline(vk->cmd,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS, quad->pipeline);
|
||||||
vk->tracker.pipeline = quad->pipeline;
|
vk->tracker.pipeline = quad->pipeline;
|
||||||
|
|
||||||
/* Changing pipeline invalidates dynamic state. */
|
/* Changing pipeline invalidates dynamic state. */
|
||||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
vulkan_check_dynamic_state(vk);
|
vulkan_check_dynamic_state(vk);
|
||||||
@ -605,9 +613,9 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
|||||||
sizeof(*quad->mvp), &range))
|
sizeof(*quad->mvp), &range))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (memcmp(quad->mvp, &vk->tracker.mvp, sizeof(*quad->mvp)) ||
|
if (memcmp(quad->mvp, &vk->tracker.mvp, sizeof(*quad->mvp))
|
||||||
quad->texture->view != vk->tracker.view ||
|
|| quad->texture->view != vk->tracker.view
|
||||||
quad->sampler != vk->tracker.sampler)
|
|| quad->sampler != vk->tracker.sampler)
|
||||||
{
|
{
|
||||||
/* Upload UBO */
|
/* Upload UBO */
|
||||||
struct vk_buffer_range range;
|
struct vk_buffer_range range;
|
||||||
@ -616,7 +624,9 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
|||||||
return;
|
return;
|
||||||
memcpy(range.data, quad->mvp, sizeof(*quad->mvp));
|
memcpy(range.data, quad->mvp, sizeof(*quad->mvp));
|
||||||
|
|
||||||
set = vulkan_descriptor_manager_alloc(vk->context->device, &vk->chain->descriptor_manager);
|
set = vulkan_descriptor_manager_alloc(vk->context->device,
|
||||||
|
&vk->chain->descriptor_manager);
|
||||||
|
|
||||||
vulkan_write_quad_descriptors(vk->context->device,
|
vulkan_write_quad_descriptors(vk->context->device,
|
||||||
set,
|
set,
|
||||||
range.buffer,
|
range.buffer,
|
||||||
@ -629,9 +639,9 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
|||||||
vk->pipelines.layout, 0,
|
vk->pipelines.layout, 0,
|
||||||
1, &set, 0, NULL);
|
1, &set, 0, NULL);
|
||||||
|
|
||||||
vk->tracker.view = quad->texture->view;
|
vk->tracker.view = quad->texture->view;
|
||||||
vk->tracker.sampler = quad->sampler;
|
vk->tracker.sampler = quad->sampler;
|
||||||
vk->tracker.mvp = *quad->mvp;
|
vk->tracker.mvp = *quad->mvp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,20 +665,25 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad)
|
|||||||
vkCmdDraw(vk->cmd, 6, 1, 0, 0);
|
vkCmdDraw(vk->cmd, 6, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vulkan_image_layout_transition(vk_t *vk, VkCommandBuffer cmd, VkImage image,
|
void vulkan_image_layout_transition(
|
||||||
VkImageLayout old_layout, VkImageLayout new_layout,
|
vk_t *vk,
|
||||||
VkAccessFlags srcAccess, VkAccessFlags dstAccess,
|
VkCommandBuffer cmd, VkImage image,
|
||||||
VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages)
|
VkImageLayout old_layout,
|
||||||
|
VkImageLayout new_layout,
|
||||||
|
VkAccessFlags srcAccess,
|
||||||
|
VkAccessFlags dstAccess,
|
||||||
|
VkPipelineStageFlags srcStages,
|
||||||
|
VkPipelineStageFlags dstStages)
|
||||||
{
|
{
|
||||||
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
|
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
|
||||||
|
|
||||||
barrier.srcAccessMask = srcAccess;
|
barrier.srcAccessMask = srcAccess;
|
||||||
barrier.dstAccessMask = dstAccess;
|
barrier.dstAccessMask = dstAccess;
|
||||||
barrier.oldLayout = old_layout;
|
barrier.oldLayout = old_layout;
|
||||||
barrier.newLayout = new_layout;
|
barrier.newLayout = new_layout;
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.image = image;
|
barrier.image = image;
|
||||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
barrier.subresourceRange.levelCount = 1;
|
barrier.subresourceRange.levelCount = 1;
|
||||||
barrier.subresourceRange.layerCount = 1;
|
barrier.subresourceRange.layerCount = 1;
|
||||||
@ -688,25 +703,28 @@ struct vk_buffer vulkan_create_buffer(const struct vulkan_context *context,
|
|||||||
struct vk_buffer buffer;
|
struct vk_buffer buffer;
|
||||||
VkMemoryRequirements mem_reqs;
|
VkMemoryRequirements mem_reqs;
|
||||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||||
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||||
|
|
||||||
info.size = size;
|
info.size = size;
|
||||||
info.usage = usage;
|
info.usage = usage;
|
||||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
vkCreateBuffer(context->device, &info, NULL, &buffer.buffer);
|
vkCreateBuffer(context->device, &info, NULL, &buffer.buffer);
|
||||||
|
|
||||||
vkGetBufferMemoryRequirements(context->device, buffer.buffer, &mem_reqs);
|
vkGetBufferMemoryRequirements(context->device, buffer.buffer, &mem_reqs);
|
||||||
|
|
||||||
alloc.allocationSize = mem_reqs.size;
|
alloc.allocationSize = mem_reqs.size;
|
||||||
alloc.memoryTypeIndex = vulkan_find_memory_type(&context->memory_properties,
|
alloc.memoryTypeIndex = vulkan_find_memory_type(
|
||||||
|
&context->memory_properties,
|
||||||
mem_reqs.memoryTypeBits,
|
mem_reqs.memoryTypeBits,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||||
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
vkAllocateMemory(context->device, &alloc, NULL, &buffer.memory);
|
vkAllocateMemory(context->device, &alloc, NULL, &buffer.memory);
|
||||||
vkBindBufferMemory(context->device, buffer.buffer, buffer.memory, 0);
|
vkBindBufferMemory(context->device, buffer.buffer, buffer.memory, 0);
|
||||||
|
|
||||||
buffer.size = alloc.allocationSize;
|
buffer.size = alloc.allocationSize;
|
||||||
|
|
||||||
vkMapMemory(context->device, buffer.memory, 0, buffer.size, 0, &buffer.mapped);
|
vkMapMemory(context->device,
|
||||||
|
buffer.memory, 0, buffer.size, 0, &buffer.mapped);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,14 +736,18 @@ void vulkan_destroy_buffer(VkDevice device, struct vk_buffer *buffer)
|
|||||||
memset(buffer, 0, sizeof(*buffer));
|
memset(buffer, 0, sizeof(*buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vk_descriptor_pool *vulkan_alloc_descriptor_pool(VkDevice device,
|
static struct vk_descriptor_pool *vulkan_alloc_descriptor_pool(
|
||||||
|
VkDevice device,
|
||||||
const struct vk_descriptor_manager *manager)
|
const struct vk_descriptor_manager *manager)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
|
VkDescriptorPoolCreateInfo pool_info = {
|
||||||
VkDescriptorSetAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
|
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
|
||||||
|
VkDescriptorSetAllocateInfo alloc_info = {
|
||||||
|
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
|
||||||
|
|
||||||
struct vk_descriptor_pool *pool = (struct vk_descriptor_pool*)calloc(1, sizeof(*pool));
|
struct vk_descriptor_pool *pool =
|
||||||
|
(struct vk_descriptor_pool*)calloc(1, sizeof(*pool));
|
||||||
if (!pool)
|
if (!pool)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -745,7 +767,8 @@ static struct vk_descriptor_pool *vulkan_alloc_descriptor_pool(VkDevice device,
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorSet vulkan_descriptor_manager_alloc(VkDevice device, struct vk_descriptor_manager *manager)
|
VkDescriptorSet vulkan_descriptor_manager_alloc(
|
||||||
|
VkDevice device, struct vk_descriptor_manager *manager)
|
||||||
{
|
{
|
||||||
if (manager->count < VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS)
|
if (manager->count < VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS)
|
||||||
return manager->current->sets[manager->count++];
|
return manager->current->sets[manager->count++];
|
||||||
@ -753,7 +776,7 @@ VkDescriptorSet vulkan_descriptor_manager_alloc(VkDevice device, struct vk_descr
|
|||||||
while (manager->current->next)
|
while (manager->current->next)
|
||||||
{
|
{
|
||||||
manager->current = manager->current->next;
|
manager->current = manager->current->next;
|
||||||
manager->count = 0;
|
manager->count = 0;
|
||||||
return manager->current->sets[manager->count++];
|
return manager->current->sets[manager->count++];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +784,7 @@ VkDescriptorSet vulkan_descriptor_manager_alloc(VkDevice device, struct vk_descr
|
|||||||
retro_assert(manager->current->next);
|
retro_assert(manager->current->next);
|
||||||
|
|
||||||
manager->current = manager->current->next;
|
manager->current = manager->current->next;
|
||||||
manager->count = 0;
|
manager->count = 0;
|
||||||
return manager->current->sets[manager->count++];
|
return manager->current->sets[manager->count++];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,22 +794,26 @@ void vulkan_descriptor_manager_restart(struct vk_descriptor_manager *manager)
|
|||||||
manager->count = 0;
|
manager->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vk_descriptor_manager vulkan_create_descriptor_manager(VkDevice device,
|
struct vk_descriptor_manager vulkan_create_descriptor_manager(
|
||||||
const VkDescriptorPoolSize *sizes, unsigned num_sizes, VkDescriptorSetLayout set_layout)
|
VkDevice device,
|
||||||
|
const VkDescriptorPoolSize *sizes,
|
||||||
|
unsigned num_sizes,
|
||||||
|
VkDescriptorSetLayout set_layout)
|
||||||
{
|
{
|
||||||
struct vk_descriptor_manager manager;
|
struct vk_descriptor_manager manager;
|
||||||
memset(&manager, 0, sizeof(manager));
|
memset(&manager, 0, sizeof(manager));
|
||||||
retro_assert(num_sizes <= VULKAN_MAX_DESCRIPTOR_POOL_SIZES);
|
retro_assert(num_sizes <= VULKAN_MAX_DESCRIPTOR_POOL_SIZES);
|
||||||
memcpy(manager.sizes, sizes, num_sizes * sizeof(*sizes));
|
memcpy(manager.sizes, sizes, num_sizes * sizeof(*sizes));
|
||||||
manager.num_sizes = num_sizes;
|
manager.num_sizes = num_sizes;
|
||||||
manager.set_layout = set_layout;
|
manager.set_layout = set_layout;
|
||||||
|
|
||||||
manager.head = vulkan_alloc_descriptor_pool(device, &manager);
|
manager.head = vulkan_alloc_descriptor_pool(device, &manager);
|
||||||
retro_assert(manager.head);
|
retro_assert(manager.head);
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vulkan_destroy_descriptor_manager(VkDevice device, struct vk_descriptor_manager *manager)
|
void vulkan_destroy_descriptor_manager(VkDevice device,
|
||||||
|
struct vk_descriptor_manager *manager)
|
||||||
{
|
{
|
||||||
struct vk_descriptor_pool *node = manager->head;
|
struct vk_descriptor_pool *node = manager->head;
|
||||||
|
|
||||||
@ -794,7 +821,8 @@ void vulkan_destroy_descriptor_manager(VkDevice device, struct vk_descriptor_man
|
|||||||
{
|
{
|
||||||
struct vk_descriptor_pool *next = node->next;
|
struct vk_descriptor_pool *next = node->next;
|
||||||
|
|
||||||
vkFreeDescriptorSets(device, node->pool, VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS, node->sets);
|
vkFreeDescriptorSets(device, node->pool,
|
||||||
|
VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS, node->sets);
|
||||||
vkDestroyDescriptorPool(device, node->pool, NULL);
|
vkDestroyDescriptorPool(device, node->pool, NULL);
|
||||||
|
|
||||||
free(node);
|
free(node);
|
||||||
@ -810,26 +838,30 @@ static void vulkan_buffer_chain_step(struct vk_buffer_chain *chain)
|
|||||||
chain->offset = 0;
|
chain->offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vulkan_buffer_chain_suballoc(struct vk_buffer_chain *chain, size_t size, struct vk_buffer_range *range)
|
static bool vulkan_buffer_chain_suballoc(struct vk_buffer_chain *chain,
|
||||||
|
size_t size, struct vk_buffer_range *range)
|
||||||
{
|
{
|
||||||
VkDeviceSize next_offset = chain->offset + size;
|
VkDeviceSize next_offset = chain->offset + size;
|
||||||
if (next_offset <= chain->current->buffer.size)
|
if (next_offset <= chain->current->buffer.size)
|
||||||
{
|
{
|
||||||
range->data = (uint8_t*)chain->current->buffer.mapped + chain->offset;
|
range->data = (uint8_t*)chain->current->buffer.mapped + chain->offset;
|
||||||
range->buffer = chain->current->buffer.buffer;
|
range->buffer = chain->current->buffer.buffer;
|
||||||
range->offset = chain->offset;
|
range->offset = chain->offset;
|
||||||
chain->offset = (next_offset + chain->alignment - 1) & ~(chain->alignment - 1);
|
chain->offset = (next_offset + chain->alignment - 1)
|
||||||
|
& ~(chain->alignment - 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vk_buffer_node *vulkan_buffer_chain_alloc_node(
|
static struct vk_buffer_node *vulkan_buffer_chain_alloc_node(
|
||||||
const struct vulkan_context *context,
|
const struct vulkan_context *context,
|
||||||
size_t size, VkBufferUsageFlags usage)
|
size_t size, VkBufferUsageFlags usage)
|
||||||
{
|
{
|
||||||
struct vk_buffer_node *node = (struct vk_buffer_node*)calloc(1, sizeof(*node));
|
struct vk_buffer_node *node = (struct vk_buffer_node*)
|
||||||
|
calloc(1, sizeof(*node));
|
||||||
if (!node)
|
if (!node)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -841,7 +873,8 @@ struct vk_buffer_chain vulkan_buffer_chain_init(VkDeviceSize block_size,
|
|||||||
VkDeviceSize alignment,
|
VkDeviceSize alignment,
|
||||||
VkBufferUsageFlags usage)
|
VkBufferUsageFlags usage)
|
||||||
{
|
{
|
||||||
struct vk_buffer_chain chain = { block_size, alignment, 0, usage, NULL, NULL };
|
struct vk_buffer_chain chain = {
|
||||||
|
block_size, alignment, 0, usage, NULL, NULL };
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,7 +885,8 @@ void vulkan_buffer_chain_discard(struct vk_buffer_chain *chain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
|
bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
|
||||||
struct vk_buffer_chain *chain, size_t size, struct vk_buffer_range *range)
|
struct vk_buffer_chain *chain,
|
||||||
|
size_t size, struct vk_buffer_range *range)
|
||||||
{
|
{
|
||||||
if (!chain->head)
|
if (!chain->head)
|
||||||
{
|
{
|
||||||
@ -878,7 +912,8 @@ bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We have to allocate a new node, might allocate larger
|
/* We have to allocate a new node, might allocate larger
|
||||||
* buffer here than block_size in case we have a very large allocation. */
|
* buffer here than block_size in case we have
|
||||||
|
* a very large allocation. */
|
||||||
if (size < chain->block_size)
|
if (size < chain->block_size)
|
||||||
size = chain->block_size;
|
size = chain->block_size;
|
||||||
|
|
||||||
@ -1321,7 +1356,7 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk)
|
|||||||
VkFence *next_fence;
|
VkFence *next_fence;
|
||||||
VkSemaphoreCreateInfo sem_info =
|
VkSemaphoreCreateInfo sem_info =
|
||||||
{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||||
VkFenceCreateInfo info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
VkFenceCreateInfo info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
||||||
|
|
||||||
vkCreateFence(vk->context.device, &info, NULL, &fence);
|
vkCreateFence(vk->context.device, &info, NULL, &fence);
|
||||||
|
|
||||||
@ -1384,7 +1419,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
|||||||
|
|
||||||
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
|
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
|
||||||
{
|
{
|
||||||
format = formats[0];
|
format = formats[0];
|
||||||
format.format = VK_FORMAT_B8G8R8A8_UNORM;
|
format.format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -52,11 +52,14 @@
|
|||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include <gfx/math/matrix_4x4.h>
|
#include <boolean.h>
|
||||||
#include <formats/image.h>
|
|
||||||
#include <retro_inline.h>
|
#include <retro_inline.h>
|
||||||
#include <retro_miscellaneous.h>
|
#include <retro_miscellaneous.h>
|
||||||
#include "boolean.h"
|
#include <gfx/math/matrix_4x4.h>
|
||||||
|
#include <gfx/scaler/scaler.h>
|
||||||
|
#include <rthreads/rthreads.h>
|
||||||
|
#include <formats/image.h>
|
||||||
|
|
||||||
#include "../../driver.h"
|
#include "../../driver.h"
|
||||||
#include "../../performance.h"
|
#include "../../performance.h"
|
||||||
#include "../../libretro.h"
|
#include "../../libretro.h"
|
||||||
@ -66,8 +69,6 @@
|
|||||||
#include "../video_context_driver.h"
|
#include "../video_context_driver.h"
|
||||||
#include "libretro_vulkan.h"
|
#include "libretro_vulkan.h"
|
||||||
#include "../drivers_shader/shader_vulkan.h"
|
#include "../drivers_shader/shader_vulkan.h"
|
||||||
#include <rthreads/rthreads.h>
|
|
||||||
#include <gfx/scaler/scaler.h>
|
|
||||||
|
|
||||||
enum vk_texture_type
|
enum vk_texture_type
|
||||||
{
|
{
|
||||||
@ -132,10 +133,14 @@ typedef struct gfx_ctx_vulkan_data
|
|||||||
{
|
{
|
||||||
vulkan_context_t context;
|
vulkan_context_t context;
|
||||||
|
|
||||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR;
|
PFN_vkGetPhysicalDeviceSurfaceSupportKHR
|
||||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
|
fpGetPhysicalDeviceSurfaceSupportKHR;
|
||||||
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
|
||||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR;
|
fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR
|
||||||
|
fpGetPhysicalDeviceSurfaceFormatsKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
|
||||||
|
fpGetPhysicalDeviceSurfacePresentModesKHR;
|
||||||
PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
|
PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
|
||||||
PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
|
PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
|
||||||
PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
|
PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
|
||||||
@ -451,7 +456,8 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad);
|
|||||||
*/
|
*/
|
||||||
void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call);
|
void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call);
|
||||||
|
|
||||||
void vulkan_image_layout_transition(vk_t *vk, VkCommandBuffer cmd, VkImage image,
|
void vulkan_image_layout_transition(vk_t *vk,
|
||||||
|
VkCommandBuffer cmd, VkImage image,
|
||||||
VkImageLayout old_layout, VkImageLayout new_layout,
|
VkImageLayout old_layout, VkImageLayout new_layout,
|
||||||
VkAccessFlags srcAccess, VkAccessFlags dstAccess,
|
VkAccessFlags srcAccess, VkAccessFlags dstAccess,
|
||||||
VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages);
|
VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages);
|
||||||
@ -493,8 +499,8 @@ static INLINE void vulkan_write_quad_vbo(struct vk_vertex *pv,
|
|||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
pv[i].x = x + strip[2 * i + 0] * width;
|
pv[i].x = x + strip[2 * i + 0] * width;
|
||||||
pv[i].y = y + strip[2 * i + 1] * height;
|
pv[i].y = y + strip[2 * i + 1] * height;
|
||||||
pv[i].tex_x = tex_x + strip[2 * i + 0] * tex_width;
|
pv[i].tex_x = tex_x + strip[2 * i + 0] * tex_width;
|
||||||
pv[i].tex_y = tex_y + strip[2 * i + 1] * tex_height;
|
pv[i].tex_y = tex_y + strip[2 * i + 1] * tex_height;
|
||||||
pv[i].color = *color;
|
pv[i].color = *color;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -801,33 +801,48 @@ static bool gfx_ctx_x_bind_api(void *data, enum gfx_ctx_api api,
|
|||||||
|
|
||||||
g_major = major;
|
g_major = major;
|
||||||
g_minor = minor;
|
g_minor = minor;
|
||||||
g_api = api;
|
|
||||||
|
|
||||||
#ifdef HAVE_VULKAN
|
switch (api)
|
||||||
if (api == GFX_CTX_VULKAN_API)
|
|
||||||
{
|
{
|
||||||
g_api = api;
|
case GFX_CTX_OPENGL_API:
|
||||||
return true;
|
#ifdef HAVE_OPENGL
|
||||||
}
|
g_api = GFX_CTX_OPENGL_API;
|
||||||
#endif
|
return true;
|
||||||
|
|
||||||
#ifdef HAVE_OPENGLES2
|
|
||||||
Display *dpy = XOpenDisplay(NULL);
|
|
||||||
const char *exts = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
|
|
||||||
bool ret = api == GFX_CTX_OPENGL_ES_API &&
|
|
||||||
exts && strstr(exts, "GLX_EXT_create_context_es2_profile");
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
if (ret && g_major < 3)
|
|
||||||
{
|
|
||||||
g_major = 2; /* ES 2.0. */
|
|
||||||
g_minor = 0;
|
|
||||||
}
|
|
||||||
g_api = GFX_CTX_OPENGL_ES_API;
|
|
||||||
return ret;
|
|
||||||
#else
|
#else
|
||||||
g_api = GFX_CTX_OPENGL_API;
|
break;
|
||||||
return api == GFX_CTX_OPENGL_API;
|
|
||||||
#endif
|
#endif
|
||||||
|
case GFX_CTX_OPENGL_ES_API:
|
||||||
|
#ifdef HAVE_OPENGLES2
|
||||||
|
{
|
||||||
|
Display *dpy = XOpenDisplay(NULL);
|
||||||
|
const char *exts = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
|
||||||
|
bool ret = exts && strstr(exts,
|
||||||
|
"GLX_EXT_create_context_es2_profile");
|
||||||
|
XCloseDisplay(dpy);
|
||||||
|
if (ret && g_major < 3)
|
||||||
|
{
|
||||||
|
g_major = 2; /* ES 2.0. */
|
||||||
|
g_minor = 0;
|
||||||
|
}
|
||||||
|
g_api = GFX_CTX_OPENGL_ES_API;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case GFX_CTX_VULKAN_API:
|
||||||
|
#ifdef HAVE_VULKAN
|
||||||
|
g_api = api;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case GFX_CTX_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_ctx_x_show_mouse(void *data, bool state)
|
static void gfx_ctx_x_show_mouse(void *data, bool state)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ typedef struct vulkan_filter_chain vulkan_filter_chain_t;
|
|||||||
|
|
||||||
enum vulkan_filter_chain_filter
|
enum vulkan_filter_chain_filter
|
||||||
{
|
{
|
||||||
VULKAN_FILTER_CHAIN_LINEAR = 0,
|
VULKAN_FILTER_CHAIN_LINEAR = 0,
|
||||||
VULKAN_FILTER_CHAIN_NEAREST = 1
|
VULKAN_FILTER_CHAIN_NEAREST = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,7 +52,8 @@ enum vulkan_filter_chain_scale
|
|||||||
|
|
||||||
struct vulkan_filter_chain_pass_info
|
struct vulkan_filter_chain_pass_info
|
||||||
{
|
{
|
||||||
/* For the last pass, make sure VIEWPORT scale with scale factors of 1 are used. */
|
/* For the last pass, make sure VIEWPORT scale
|
||||||
|
* with scale factors of 1 are used. */
|
||||||
enum vulkan_filter_chain_scale scale_type_x;
|
enum vulkan_filter_chain_scale scale_type_x;
|
||||||
enum vulkan_filter_chain_scale scale_type_y;
|
enum vulkan_filter_chain_scale scale_type_y;
|
||||||
float scale_x;
|
float scale_x;
|
||||||
@ -117,13 +118,16 @@ void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain,
|
|||||||
void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain,
|
void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain,
|
||||||
VkCommandBuffer cmd, const VkViewport *vp, const float *mvp);
|
VkCommandBuffer cmd, const VkViewport *vp, const float *mvp);
|
||||||
|
|
||||||
vulkan_filter_chain_t *vulkan_filter_chain_create_default(const struct vulkan_filter_chain_create_info *info,
|
vulkan_filter_chain_t *vulkan_filter_chain_create_default(
|
||||||
|
const struct vulkan_filter_chain_create_info *info,
|
||||||
enum vulkan_filter_chain_filter filter);
|
enum vulkan_filter_chain_filter filter);
|
||||||
|
|
||||||
vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(const struct vulkan_filter_chain_create_info *info,
|
vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||||
|
const struct vulkan_filter_chain_create_info *info,
|
||||||
const char *path, enum vulkan_filter_chain_filter filter);
|
const char *path, enum vulkan_filter_chain_filter filter);
|
||||||
|
|
||||||
struct video_shader *vulkan_filter_chain_get_preset(vulkan_filter_chain_t *chain);
|
struct video_shader *vulkan_filter_chain_get_preset(
|
||||||
|
vulkan_filter_chain_t *chain);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -276,9 +276,11 @@ static bool find_video_driver(void)
|
|||||||
|
|
||||||
if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL))
|
if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_HW_CONTEXT, NULL))
|
||||||
{
|
{
|
||||||
|
current_video = NULL;
|
||||||
struct retro_hw_render_callback *hwr =
|
struct retro_hw_render_callback *hwr =
|
||||||
video_driver_callback();
|
video_driver_callback();
|
||||||
current_video = NULL;
|
|
||||||
|
(void)hwr;
|
||||||
|
|
||||||
#if defined(HAVE_VULKAN)
|
#if defined(HAVE_VULKAN)
|
||||||
if (hwr && hw_render_context_is_vulkan(hwr->context_type))
|
if (hwr && hw_render_context_is_vulkan(hwr->context_type))
|
||||||
|
@ -336,11 +336,11 @@ int generic_menu_iterate(void *data, void *userdata, enum menu_action action)
|
|||||||
BIT64_SET(menu->state, MENU_STATE_POP_STACK);
|
BIT64_SET(menu->state, MENU_STATE_POP_STACK);
|
||||||
break;
|
break;
|
||||||
case ITERATE_TYPE_DEFAULT:
|
case ITERATE_TYPE_DEFAULT:
|
||||||
/* FIXME: Crappy hack, needed for mouse controls to not be completely broken
|
/* FIXME: Crappy hack, needed for mouse controls
|
||||||
* in case we press back.
|
* to not be completely broken in case we press back.
|
||||||
*
|
*
|
||||||
* We need to fix this entire mess, mouse controls should not rely on a
|
* We need to fix this entire mess, mouse controls
|
||||||
* hack like this in order to work. */
|
* should not rely on a hack like this in order to work. */
|
||||||
selection = max(min(selection, (menu_entries_get_size() - 1)), 0);
|
selection = max(min(selection, (menu_entries_get_size() - 1)), 0);
|
||||||
|
|
||||||
menu_entry_get(&entry, 0, selection, NULL, false);
|
menu_entry_get(&entry, 0, selection, NULL, false);
|
||||||
|
@ -243,13 +243,13 @@ HRESULT XuiTextureLoader(IXuiDevice *pDevice, LPCWSTR szFileName,
|
|||||||
|
|
||||||
if(hr != D3DXERR_INVALIDDATA )
|
if(hr != D3DXERR_INVALIDDATA )
|
||||||
{
|
{
|
||||||
pImageInfo->Depth = pSrc.Depth;
|
pImageInfo->Depth = pSrc.Depth;
|
||||||
pImageInfo->Format = pSrc.Format;
|
pImageInfo->Format = pSrc.Format;
|
||||||
pImageInfo->Height = pSrc.Height;
|
pImageInfo->Height = pSrc.Height;
|
||||||
pImageInfo->ImageFileFormat = pSrc.ImageFileFormat;
|
pImageInfo->ImageFileFormat = pSrc.ImageFileFormat;
|
||||||
pImageInfo->MipLevels = pSrc.MipLevels;
|
pImageInfo->MipLevels = pSrc.MipLevels;
|
||||||
pImageInfo->ResourceType = pSrc.ResourceType;
|
pImageInfo->ResourceType = pSrc.ResourceType;
|
||||||
pImageInfo->Width = pSrc.Width;
|
pImageInfo->Width = pSrc.Width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RARCH_ERR("D3DXERR_INVALIDDATA Encountered\n");
|
RARCH_ERR("D3DXERR_INVALIDDATA Encountered\n");
|
||||||
@ -293,7 +293,8 @@ static void* xui_init(void **userdata)
|
|||||||
|
|
||||||
d3d_make_d3dpp(d3d, &video_info, &d3dpp);
|
d3d_make_d3dpp(d3d, &video_info, &d3dpp);
|
||||||
|
|
||||||
hr = app.InitShared(d3d->dev, &d3dpp, (PFN_XUITEXTURELOADER)XuiTextureLoader);
|
hr = app.InitShared(d3d->dev, &d3dpp,
|
||||||
|
(PFN_XUITEXTURELOADER)XuiTextureLoader);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
@ -387,8 +388,8 @@ static void xui_render_message(const char *msg)
|
|||||||
float msg_height = 120;
|
float msg_height = 120;
|
||||||
float msg_offset = 32;
|
float msg_offset = 32;
|
||||||
|
|
||||||
font_parms.x = msg_width;
|
font_parms.x = msg_width;
|
||||||
font_parms.y = msg_height + (msg_offset * j);
|
font_parms.y = msg_height + (msg_offset * j);
|
||||||
font_parms.scale = 21;
|
font_parms.scale = 21;
|
||||||
|
|
||||||
video_driver_set_osd_msg(msg, &font_parms, NULL);
|
video_driver_set_osd_msg(msg, &font_parms, NULL);
|
||||||
@ -404,7 +405,7 @@ static void xui_frame(void *data)
|
|||||||
XUIMessageRender msgRender;
|
XUIMessageRender msgRender;
|
||||||
D3DXMATRIX matOrigView;
|
D3DXMATRIX matOrigView;
|
||||||
LPDIRECT3DDEVICE d3dr;
|
LPDIRECT3DDEVICE d3dr;
|
||||||
const char *message;
|
const char *message = NULL;
|
||||||
D3DVIEWPORT vp_full = {0};
|
D3DVIEWPORT vp_full = {0};
|
||||||
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
|
d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(false);
|
||||||
|
|
||||||
@ -424,7 +425,8 @@ static void xui_frame(void *data)
|
|||||||
|
|
||||||
XuiRenderGetViewTransform( app.GetDC(), &matOrigView );
|
XuiRenderGetViewTransform( app.GetDC(), &matOrigView );
|
||||||
|
|
||||||
XuiMessageRender( &msg, &msgRender, app.GetDC(), 0xffffffff, XUI_BLEND_NORMAL );
|
XuiMessageRender( &msg, &msgRender,
|
||||||
|
app.GetDC(), 0xffffffff, XUI_BLEND_NORMAL );
|
||||||
XuiSendMessage( app.GetRootObj(), &msg );
|
XuiSendMessage( app.GetRootObj(), &msg );
|
||||||
|
|
||||||
XuiRenderSetViewTransform( app.GetDC(), &matOrigView );
|
XuiRenderSetViewTransform( app.GetDC(), &matOrigView );
|
||||||
@ -452,9 +454,7 @@ static void blit_line(int x, int y, const char *message, bool green)
|
|||||||
|
|
||||||
static void xui_render_background(void)
|
static void xui_render_background(void)
|
||||||
{
|
{
|
||||||
bool libretro_running = menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL);
|
if (menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL))
|
||||||
|
|
||||||
if (libretro_running)
|
|
||||||
XuiElementSetShow(m_background, FALSE);
|
XuiElementSetShow(m_background, FALSE);
|
||||||
else
|
else
|
||||||
XuiElementSetShow(m_background, TRUE);
|
XuiElementSetShow(m_background, TRUE);
|
||||||
@ -666,13 +666,15 @@ static void xui_list_free(file_list_t *list, size_t idx,
|
|||||||
|
|
||||||
static void xui_list_clear(file_list_t *list)
|
static void xui_list_clear(file_list_t *list)
|
||||||
{
|
{
|
||||||
XuiListDeleteItems(m_menulist, 0, XuiListGetItemCount(m_menulist));
|
XuiListDeleteItems(m_menulist,
|
||||||
|
0, XuiListGetItemCount(m_menulist));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xui_list_set_selection(void *data, file_list_t *list)
|
static void xui_list_set_selection(void *data, file_list_t *list)
|
||||||
{
|
{
|
||||||
if (list)
|
if (list)
|
||||||
XuiListSetCurSel(m_menulist, file_list_get_directory_ptr(list));
|
XuiListSetCurSel(m_menulist,
|
||||||
|
file_list_get_directory_ptr(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xui_environ(menu_environ_cb_t type, void *data)
|
static int xui_environ(menu_environ_cb_t type, void *data)
|
||||||
|
@ -213,8 +213,10 @@ static void zarch_zui_font(void)
|
|||||||
|
|
||||||
menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size);
|
menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size);
|
||||||
|
|
||||||
fill_pathname_join(mediapath, settings->assets_directory, "zarch", sizeof(mediapath));
|
fill_pathname_join(mediapath,
|
||||||
fill_pathname_join(fontpath, mediapath, "Roboto-Condensed.ttf", sizeof(fontpath));
|
settings->assets_directory, "zarch", sizeof(mediapath));
|
||||||
|
fill_pathname_join(fontpath,
|
||||||
|
mediapath, "Roboto-Condensed.ttf", sizeof(fontpath));
|
||||||
|
|
||||||
font_info.path = fontpath;
|
font_info.path = fontpath;
|
||||||
font_info.size = font_size;
|
font_info.size = font_size;
|
||||||
@ -250,7 +252,8 @@ static int16_t zarch_zui_input_state(zui_t *zui, enum zarch_zui_input_state stat
|
|||||||
case MENU_POINTER_ZARCH_Y:
|
case MENU_POINTER_ZARCH_Y:
|
||||||
return menu_input_pointer_state(MENU_POINTER_Y_AXIS);
|
return menu_input_pointer_state(MENU_POINTER_Y_AXIS);
|
||||||
case MENU_ZARCH_PRESSED:
|
case MENU_ZARCH_PRESSED:
|
||||||
if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON) || menu_input_pointer_state(MENU_POINTER_PRESSED))
|
if ( menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)
|
||||||
|
|| menu_input_pointer_state(MENU_POINTER_PRESSED))
|
||||||
return 1;
|
return 1;
|
||||||
if (zui->action == MENU_ACTION_OK)
|
if (zui->action == MENU_ACTION_OK)
|
||||||
return 1;
|
return 1;
|
||||||
@ -260,7 +263,8 @@ static int16_t zarch_zui_input_state(zui_t *zui, enum zarch_zui_input_state stat
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zarch_zui_check_button_down(zui_t *zui, unsigned id, int x1, int y1, int x2, int y2)
|
static bool zarch_zui_check_button_down(zui_t *zui,
|
||||||
|
unsigned id, int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
||||||
@ -268,7 +272,8 @@ static bool zarch_zui_check_button_down(zui_t *zui, unsigned id, int x1, int y1,
|
|||||||
if (inside)
|
if (inside)
|
||||||
zui->item.hot = id;
|
zui->item.hot = id;
|
||||||
|
|
||||||
if (zui->item.hot == id && zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
|
if ( zui->item.hot == id
|
||||||
|
&& zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
zui->item.active = id;
|
zui->item.active = id;
|
||||||
@ -277,7 +282,8 @@ static bool zarch_zui_check_button_down(zui_t *zui, unsigned id, int x1, int y1,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zarch_zui_check_button_up(zui_t *zui, unsigned id, int x1, int y1, int x2, int y2)
|
static bool zarch_zui_check_button_up(zui_t *zui,
|
||||||
|
unsigned id, int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
||||||
@ -285,7 +291,8 @@ static bool zarch_zui_check_button_up(zui_t *zui, unsigned id, int x1, int y1, i
|
|||||||
if (inside)
|
if (inside)
|
||||||
zui->item.hot = id;
|
zui->item.hot = id;
|
||||||
|
|
||||||
if (zui->item.active == id && !zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
|
if ( zui->item.active == id
|
||||||
|
&& !zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
|
||||||
{
|
{
|
||||||
if (zui->item.hot == id)
|
if (zui->item.hot == id)
|
||||||
result = true;
|
result = true;
|
||||||
@ -314,7 +321,8 @@ static unsigned zarch_zui_hash(zui_t *zui, const char *s)
|
|||||||
return zui->hash = hval;
|
return zui->hash = hval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zarch_zui_draw_text(zui_t *zui, uint32_t color, int x, int y, const char *text)
|
static void zarch_zui_draw_text(zui_t *zui,
|
||||||
|
uint32_t color, int x, int y, const char *text)
|
||||||
{
|
{
|
||||||
struct font_params params;
|
struct font_params params;
|
||||||
|
|
||||||
@ -375,19 +383,21 @@ static float zarch_zui_randf(float min, float max)
|
|||||||
return (rand() * ((max - min) / RAND_MAX)) + min;
|
return (rand() * ((max - min) / RAND_MAX)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float zarch_zui_scalef(float val, float oldmin, float oldmax, float newmin, float newmax)
|
static float zarch_zui_scalef(float val,
|
||||||
|
float oldmin, float oldmax, float newmin, float newmax)
|
||||||
{
|
{
|
||||||
return (((val - oldmin) * (newmax - newmin)) / (oldmax - oldmin)) + newmin;
|
return (((val - oldmin) * (newmax - newmin)) / (oldmax - oldmin)) + newmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NPARTICLES 100
|
#define NPARTICLES 100
|
||||||
|
|
||||||
static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca, int width, int height)
|
static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca,
|
||||||
|
int width, int height)
|
||||||
{
|
{
|
||||||
static part_t particles[NPARTICLES];
|
static part_t particles[NPARTICLES];
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static int timeout = 0;
|
static int timeout = 0;
|
||||||
unsigned i, max_gen = 2;
|
unsigned i, max_gen = 2;
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
@ -404,11 +414,11 @@ static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca, int width, int hei
|
|||||||
int16_t mouse_x = zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X);
|
int16_t mouse_x = zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X);
|
||||||
|
|
||||||
p->y += p->yspeed;
|
p->y += p->yspeed;
|
||||||
p->x += zarch_zui_scalef(mouse_x, 0, width, -0.3, 0.3) + p->xspeed;
|
p->x += zarch_zui_scalef(mouse_x, 0, width, -0.3, 0.3);
|
||||||
|
p->x += p->xspeed;
|
||||||
p->alive = p->y >= 0 && p->y < height && p->x >= 0 && p->x < width;
|
|
||||||
|
|
||||||
|
|
||||||
|
p->alive = p->y >= 0 && p->y < height
|
||||||
|
&& p->x >= 0 && p->x < width;
|
||||||
}
|
}
|
||||||
else if (max_gen > 0 && timeout <= 0)
|
else if (max_gen > 0 && timeout <= 0)
|
||||||
{
|
{
|
||||||
@ -447,13 +457,15 @@ static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca, int width, int hei
|
|||||||
colors[j] = alpha;
|
colors[j] = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
zarch_zui_push_quad(width, height, colors, ca, p->x-2, p->y-2, p->x+2, p->y+2);
|
zarch_zui_push_quad(width, height,
|
||||||
|
colors, ca, p->x-2, p->y-2, p->x+2, p->y+2);
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zarch_zui_button_full(zui_t *zui, int x1, int y1, int x2, int y2, const char *label)
|
static bool zarch_zui_button_full(zui_t *zui,
|
||||||
|
int x1, int y1, int x2, int y2, const char *label)
|
||||||
{
|
{
|
||||||
unsigned id = zarch_zui_hash(zui, label);
|
unsigned id = zarch_zui_hash(zui, label);
|
||||||
bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
|
bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
|
||||||
@ -470,7 +482,8 @@ static bool zarch_zui_button_full(zui_t *zui, int x1, int y1, int x2, int y2, co
|
|||||||
|
|
||||||
static bool zarch_zui_button(zui_t *zui, int x1, int y1, const char *label)
|
static bool zarch_zui_button(zui_t *zui, int x1, int y1, const char *label)
|
||||||
{
|
{
|
||||||
return zarch_zui_button_full(zui, x1, y1, x1 + zarch_zui_strwidth(zui->fb_buf, label, 1.0) + 24, y1 + 64, label);
|
return zarch_zui_button_full(zui, x1, y1, x1
|
||||||
|
+ zarch_zui_strwidth(zui->fb_buf, label, 1.0) + 24, y1 + 64, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zarch_zui_list_item(zui_t *zui, zui_tabbed_t *tab, int x1, int y1,
|
static bool zarch_zui_list_item(zui_t *zui, zui_tabbed_t *tab, int x1, int y1,
|
||||||
@ -506,7 +519,8 @@ static bool zarch_zui_list_item(zui_t *zui, zui_tabbed_t *tab, int x1, int y1,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (zui->active_id != item_id && zui->pending_selection == item_id)
|
if ( zui->active_id != item_id
|
||||||
|
&& zui->pending_selection == item_id)
|
||||||
set_active_id = true;
|
set_active_id = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +556,8 @@ static void zarch_zui_tabbed_begin(zui_t *zui, zui_tabbed_t *tab, int x, int y)
|
|||||||
tab->tabline_size = 60 + 4;
|
tab->tabline_size = 60 + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zarch_zui_tab(zui_t *zui, zui_tabbed_t *tab, const char *label, unsigned tab_id)
|
static bool zarch_zui_tab(zui_t *zui, zui_tabbed_t *tab,
|
||||||
|
const char *label, unsigned tab_id)
|
||||||
{
|
{
|
||||||
bool active;
|
bool active;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
@ -656,7 +671,8 @@ static void zarch_zui_render_lay_root_load_free(zui_t *zui)
|
|||||||
zui->load_dlist = NULL;
|
zui->load_dlist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zarch_zui_render_lay_root_load_set_new_path(zui_t *zui, const char *newpath)
|
static void zarch_zui_render_lay_root_load_set_new_path(zui_t *zui,
|
||||||
|
const char *newpath)
|
||||||
{
|
{
|
||||||
if (!zui)
|
if (!zui)
|
||||||
return;
|
return;
|
||||||
@ -685,23 +701,29 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
core_info_t *core_info = NULL;
|
core_info_t *core_info = NULL;
|
||||||
core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info);
|
core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info);
|
||||||
|
|
||||||
zui->load_dlist = dir_list_new(zui->load_cwd, core_info->supported_extensions, true, true);
|
zui->load_dlist = dir_list_new(zui->load_cwd,
|
||||||
|
core_info->supported_extensions, true, true);
|
||||||
dir_list_sort(zui->load_dlist, true);
|
dir_list_sort(zui->load_dlist, true);
|
||||||
zui->load_dlist_first = 0;
|
zui->load_dlist_first = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cwd_offset = min(strlen(zui->load_cwd), 60);
|
cwd_offset = min(strlen(zui->load_cwd), 60);
|
||||||
|
|
||||||
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15, tabbed->tabline_size + 5 + 41, &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);
|
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15,
|
||||||
|
tabbed->tabline_size + 5 + 41,
|
||||||
|
&zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);
|
||||||
|
|
||||||
if (zarch_zui_button(zui, zui->width - 290 - 129, tabbed->tabline_size + 5, "Home"))
|
if (zarch_zui_button(zui, zui->width - 290 - 129,
|
||||||
|
tabbed->tabline_size + 5, "Home"))
|
||||||
zarch_zui_render_lay_root_load_free(zui);
|
zarch_zui_render_lay_root_load_free(zui);
|
||||||
|
|
||||||
if (zui->load_dlist)
|
if (zui->load_dlist)
|
||||||
{
|
{
|
||||||
fill_pathname_parent_dir(parent_dir, zui->load_cwd, sizeof(parent_dir));
|
fill_pathname_parent_dir(parent_dir,
|
||||||
|
zui->load_cwd, sizeof(parent_dir));
|
||||||
if (!string_is_empty(parent_dir) &&
|
if (!string_is_empty(parent_dir) &&
|
||||||
zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73, " ..", 0, NULL /* TODO/FIXME */))
|
zarch_zui_list_item(zui, tabbed, 0,
|
||||||
|
tabbed->tabline_size + 73, " ..", 0, NULL /* TODO/FIXME */))
|
||||||
{
|
{
|
||||||
zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
|
zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
|
||||||
}
|
}
|
||||||
@ -713,7 +735,8 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
|
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
const char *basename = path_basename(zui->load_dlist->elems[i].data);
|
const char *basename =
|
||||||
|
path_basename(zui->load_dlist->elems[i].data);
|
||||||
if (basename[0] != '.')
|
if (basename[0] != '.')
|
||||||
break;
|
break;
|
||||||
skip++;
|
skip++;
|
||||||
@ -726,7 +749,8 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
else if (zui->load_dlist_first > (int)size - 5)
|
else if (zui->load_dlist_first > (int)size - 5)
|
||||||
zui->load_dlist_first = size - 5;
|
zui->load_dlist_first = size - 5;
|
||||||
|
|
||||||
zui->load_dlist_first = min(max(zui->load_dlist_first, 0), size - 5 - skip);
|
zui->load_dlist_first = min(max(zui->load_dlist_first, 0),
|
||||||
|
size - 5 - skip);
|
||||||
|
|
||||||
for (i = skip + zui->load_dlist_first; i < size; ++i)
|
for (i = skip + zui->load_dlist_first; i < size; ++i)
|
||||||
{
|
{
|
||||||
@ -747,7 +771,8 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
if (path_is_directory(path))
|
if (path_is_directory(path))
|
||||||
strncat(label, "/", sizeof(label)-1);
|
strncat(label, "/", sizeof(label)-1);
|
||||||
|
|
||||||
if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73 + j * 54,
|
if (zarch_zui_list_item(zui, tabbed, 0,
|
||||||
|
tabbed->tabline_size + 73 + j * 54,
|
||||||
label, i, NULL))
|
label, i, NULL))
|
||||||
{
|
{
|
||||||
if (path_is_directory(path))
|
if (path_is_directory(path))
|
||||||
@ -758,7 +783,8 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
|
|
||||||
zui->pick_cores = NULL;
|
zui->pick_cores = NULL;
|
||||||
zui->pick_supported = 0;
|
zui->pick_supported = 0;
|
||||||
strncpy(zui->pick_content, path, sizeof(zui->pick_content)-1);
|
strncpy(zui->pick_content,
|
||||||
|
path, sizeof(zui->pick_content)-1);
|
||||||
|
|
||||||
core_info_ctl(CORE_INFO_CTL_LIST_GET, &list);
|
core_info_ctl(CORE_INFO_CTL_LIST_GET, &list);
|
||||||
|
|
||||||
@ -781,7 +807,8 @@ static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zarch_zui_render_lay_root_collections(zui_t *zui, zui_tabbed_t *tabbed)
|
static int zarch_zui_render_lay_root_collections(
|
||||||
|
zui_t *zui, zui_tabbed_t *tabbed)
|
||||||
{
|
{
|
||||||
if (zarch_zui_tab(zui, tabbed, "Collections", 2))
|
if (zarch_zui_tab(zui, tabbed, "Collections", 2))
|
||||||
{
|
{
|
||||||
@ -791,7 +818,8 @@ static int zarch_zui_render_lay_root_collections(zui_t *zui, zui_tabbed_t *tabbe
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zarch_zui_render_lay_root_downloads(zui_t *zui, zui_tabbed_t *tabbed)
|
static int zarch_zui_render_lay_root_downloads(
|
||||||
|
zui_t *zui, zui_tabbed_t *tabbed)
|
||||||
{
|
{
|
||||||
if (zarch_zui_tab(zui, tabbed, "Download", 3))
|
if (zarch_zui_tab(zui, tabbed, "Download", 3))
|
||||||
{
|
{
|
||||||
@ -855,7 +883,8 @@ static int zarch_zui_render_lay_root(zui_t *zui)
|
|||||||
else
|
else
|
||||||
zui->pending_selection = -1;
|
zui->pending_selection = -1;
|
||||||
|
|
||||||
zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_HILITE, &zui->ca, 0, 60, zui->width - 290 - 40, 60+4);
|
zarch_zui_push_quad(zui->width, zui->height,
|
||||||
|
ZUI_BG_HILITE, &zui->ca, 0, 60, zui->width - 290 - 40, 60+4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -923,7 +952,8 @@ static int zarch_zui_render_pick_core(zui_t *zui)
|
|||||||
|
|
||||||
if (!zui->pick_supported)
|
if (!zui->pick_supported)
|
||||||
{
|
{
|
||||||
zarch_zui_list_item(zui, &tabbed, 0, 54, "Content unsupported", 0, NULL /* TODO/FIXME */);
|
zarch_zui_list_item(zui, &tabbed, 0, 54,
|
||||||
|
"Content unsupported", 0, NULL /* TODO/FIXME */);
|
||||||
zui->active_id = 0;
|
zui->active_id = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -999,7 +1029,8 @@ static void zarch_frame(void *data)
|
|||||||
|
|
||||||
menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block);
|
menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block);
|
||||||
|
|
||||||
zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_SCREEN, &zui->ca, 0, 0, zui->width, zui->height);
|
zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_SCREEN,
|
||||||
|
&zui->ca, 0, 0, zui->width, zui->height);
|
||||||
zarch_zui_snow(zui, &zui->ca, zui->width, zui->height);
|
zarch_zui_snow(zui, &zui->ca, zui->width, zui->height);
|
||||||
|
|
||||||
switch (layout)
|
switch (layout)
|
||||||
@ -1078,7 +1109,8 @@ static void *zarch_init(void **userdata)
|
|||||||
int unused;
|
int unused;
|
||||||
zui_t *zui = NULL;
|
zui_t *zui = NULL;
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu));
|
menu_handle_t *menu = (menu_handle_t*)
|
||||||
|
calloc(1, sizeof(*menu));
|
||||||
|
|
||||||
if (!menu)
|
if (!menu)
|
||||||
goto error;
|
goto error;
|
||||||
@ -1112,7 +1144,8 @@ static void *zarch_init(void **userdata)
|
|||||||
|
|
||||||
if (!string_is_empty(settings->menu.wallpaper))
|
if (!string_is_empty(settings->menu.wallpaper))
|
||||||
rarch_task_push_image_load(settings->menu.wallpaper,
|
rarch_task_push_image_load(settings->menu.wallpaper,
|
||||||
"cb_menu_wallpaper", menu_display_handle_wallpaper_upload, NULL);
|
"cb_menu_wallpaper",
|
||||||
|
menu_display_handle_wallpaper_upload, NULL);
|
||||||
|
|
||||||
zui->ca.allocated = 0;
|
zui->ca.allocated = 0;
|
||||||
|
|
||||||
@ -1276,18 +1309,22 @@ static bool zarch_menu_init_list(void *data)
|
|||||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||||
|
|
||||||
|
|
||||||
strlcpy(info.label, menu_hash_to_str(MENU_VALUE_HISTORY_TAB), sizeof(info.label));
|
strlcpy(info.label,
|
||||||
|
menu_hash_to_str(MENU_VALUE_HISTORY_TAB), sizeof(info.label));
|
||||||
|
|
||||||
menu_entries_push(menu_stack, info.path, info.label, info.type, info.flags, 0);
|
menu_entries_push(menu_stack,
|
||||||
|
info.path, info.label, info.type, info.flags, 0);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
menu_entries_increment_menu_stack();
|
menu_entries_increment_menu_stack();
|
||||||
|
|
||||||
strlcpy(info.label, menu_hash_to_str(MENU_VALUE_MAIN_MENU), sizeof(info.label));
|
strlcpy(info.label,
|
||||||
|
menu_hash_to_str(MENU_VALUE_MAIN_MENU), sizeof(info.label));
|
||||||
|
|
||||||
menu_stack = menu_entries_get_menu_stack_ptr(1);
|
menu_stack = menu_entries_get_menu_stack_ptr(1);
|
||||||
|
|
||||||
menu_entries_push(menu_stack, info.path, info.label, info.type, info.flags, 0);
|
menu_entries_push(menu_stack,
|
||||||
|
info.path, info.label, info.type, info.flags, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL);
|
event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL);
|
||||||
|
@ -126,11 +126,12 @@ static void menu_display_d3d_draw(void *data)
|
|||||||
draw->height = 1;
|
draw->height = 1;
|
||||||
|
|
||||||
if (!mat)
|
if (!mat)
|
||||||
mat = (math_matrix_4x4*)menu_display_d3d_get_default_mvp();
|
mat = (math_matrix_4x4*)
|
||||||
|
menu_display_d3d_get_default_mvp();
|
||||||
if (!draw->coords->vertex)
|
if (!draw->coords->vertex)
|
||||||
draw->coords->vertex = &d3d_vertexes[0];
|
draw->coords->vertex = &d3d_vertexes[0];
|
||||||
if (!draw->coords->tex_coord)
|
if (!draw->coords->tex_coord)
|
||||||
draw->coords->tex_coord = &d3d_tex_coords[0];
|
draw->coords->tex_coord = &d3d_tex_coords[0];
|
||||||
if (!draw->coords->lut_tex_coord)
|
if (!draw->coords->lut_tex_coord)
|
||||||
draw->coords->lut_tex_coord = &d3d_tex_coords[0];
|
draw->coords->lut_tex_coord = &d3d_tex_coords[0];
|
||||||
|
|
||||||
|
@ -53,22 +53,24 @@ static void *menu_display_vk_get_default_mvp(void)
|
|||||||
return &vk->mvp_no_rot;
|
return &vk->mvp_no_rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned to_display_pipeline(enum menu_display_prim_type prim_type, bool blend)
|
static unsigned to_display_pipeline(
|
||||||
|
enum menu_display_prim_type prim_type, bool blend)
|
||||||
{
|
{
|
||||||
return ((prim_type == MENU_DISPLAY_PRIM_TRIANGLESTRIP) << 1) | (blend << 0);
|
return ((prim_type == MENU_DISPLAY_PRIM_TRIANGLESTRIP) << 1) | (blend << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void menu_display_vk_draw(void *data)
|
static void menu_display_vk_draw(void *data)
|
||||||
{
|
{
|
||||||
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
|
|
||||||
struct vk_texture *texture;
|
|
||||||
const float *vertex, *tex_coord, *color;
|
|
||||||
math_matrix_4x4 *mat;
|
|
||||||
struct vk_buffer_range range;
|
|
||||||
struct vk_vertex *pv;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
struct vk_buffer_range range;
|
||||||
vk_t *vk = vk_get_ptr();
|
struct vk_texture *texture = NULL;
|
||||||
|
const float *vertex = NULL;
|
||||||
|
const float *tex_coord = NULL;
|
||||||
|
const float *color = NULL;
|
||||||
|
math_matrix_4x4 *mat = NULL;
|
||||||
|
struct vk_vertex *pv = NULL;
|
||||||
|
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
|
||||||
|
vk_t *vk = vk_get_ptr();
|
||||||
if (!vk)
|
if (!vk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -120,7 +122,8 @@ static void menu_display_vk_draw(void *data)
|
|||||||
|
|
||||||
{
|
{
|
||||||
const struct vk_draw_triangles call = {
|
const struct vk_draw_triangles call = {
|
||||||
vk->display.pipelines[to_display_pipeline(draw->prim_type, vk->display.blend)],
|
vk->display.pipelines[
|
||||||
|
to_display_pipeline(draw->prim_type, vk->display.blend)],
|
||||||
texture,
|
texture,
|
||||||
texture->default_smooth ? vk->samplers.linear : vk->samplers.nearest,
|
texture->default_smooth ? vk->samplers.linear : vk->samplers.nearest,
|
||||||
mat,
|
mat,
|
||||||
|
@ -1446,11 +1446,11 @@ int runloop_iterate(unsigned *sleep_ms)
|
|||||||
unlock_autosave();
|
unlock_autosave();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!settings->fastforward_ratio)
|
||||||
|
return 0;
|
||||||
#ifdef HAVE_MENU
|
#ifdef HAVE_MENU
|
||||||
end:
|
end:
|
||||||
#endif
|
#endif
|
||||||
if (!settings->fastforward_ratio)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
current = retro_get_time_usec();
|
current = retro_get_time_usec();
|
||||||
target = frame_limit_last_time +
|
target = frame_limit_last_time +
|
||||||
|
Loading…
x
Reference in New Issue
Block a user