(shader vulkan) Cleanups - moving C code out of the C++ file
This commit is contained in:
parent
d4a1f2ef85
commit
ef27a660a7
|
@ -3175,3 +3175,37 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vulkan_initialize_render_pass(VkDevice device, VkFormat format,
|
||||
VkRenderPass *render_pass)
|
||||
{
|
||||
VkRenderPassCreateInfo rp_info = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
|
||||
VkAttachmentReference color_ref = { 0,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
|
||||
VkAttachmentDescription attachment = {0};
|
||||
VkSubpassDescription subpass = {0};
|
||||
|
||||
/* We will always write to the entire framebuffer,
|
||||
* so we don't really need to clear. */
|
||||
attachment.format = format;
|
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
|
||||
attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &color_ref;
|
||||
|
||||
rp_info.attachmentCount = 1;
|
||||
rp_info.pAttachments = &attachment;
|
||||
rp_info.subpassCount = 1;
|
||||
rp_info.pSubpasses = &subpass;
|
||||
|
||||
vkCreateRenderPass(device, &rp_info, NULL, render_pass);
|
||||
}
|
||||
|
|
|
@ -592,6 +592,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
|||
unsigned width, unsigned height,
|
||||
unsigned swap_interval);
|
||||
|
||||
void vulkan_initialize_render_pass(VkDevice device,
|
||||
VkFormat format, VkRenderPass *render_pass);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -85,10 +85,10 @@ static void vulkan_init_render_pass(
|
|||
{
|
||||
VkRenderPassCreateInfo rp_info = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
|
||||
VkAttachmentDescription attachment = {0};
|
||||
VkSubpassDescription subpass = {0};
|
||||
VkAttachmentReference color_ref = { 0,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
|
||||
VkAttachmentDescription attachment = {0};
|
||||
VkSubpassDescription subpass = {0};
|
||||
|
||||
/* Backbuffer format. */
|
||||
attachment.format = vk->context->swapchain_format;
|
||||
|
|
|
@ -129,26 +129,6 @@ struct Texture
|
|||
vulkan_filter_chain_address address;
|
||||
};
|
||||
|
||||
static vulkan_filter_chain_address wrap_to_address(gfx_wrap_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case RARCH_WRAP_BORDER:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER;
|
||||
case RARCH_WRAP_REPEAT:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_REPEAT;
|
||||
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT;
|
||||
case RARCH_WRAP_EDGE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DeferredDisposer
|
||||
{
|
||||
public:
|
||||
|
@ -263,14 +243,14 @@ class Framebuffer
|
|||
void generate_mips(VkCommandBuffer cmd);
|
||||
|
||||
private:
|
||||
const VkPhysicalDeviceMemoryProperties &memory_properties;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkImage image = VK_NULL_HANDLE;
|
||||
VkImageView view = VK_NULL_HANDLE;
|
||||
VkImageView fb_view = VK_NULL_HANDLE;
|
||||
Size2D size;
|
||||
VkFormat format;
|
||||
unsigned max_levels;
|
||||
const VkPhysicalDeviceMemoryProperties &memory_properties;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkImage image = VK_NULL_HANDLE;
|
||||
VkImageView view = VK_NULL_HANDLE;
|
||||
VkImageView fb_view = VK_NULL_HANDLE;
|
||||
unsigned levels = 0;
|
||||
|
||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||
|
@ -278,14 +258,12 @@ class Framebuffer
|
|||
|
||||
struct
|
||||
{
|
||||
size_t size = 0;
|
||||
uint32_t type = 0;
|
||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||
size_t size = 0;
|
||||
uint32_t type = 0;
|
||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||
} memory;
|
||||
|
||||
void init(DeferredDisposer *disposer);
|
||||
void init_framebuffer();
|
||||
void init_render_pass();
|
||||
};
|
||||
|
||||
struct CommonResources
|
||||
|
@ -296,10 +274,10 @@ struct CommonResources
|
|||
|
||||
unique_ptr<Buffer> vbo;
|
||||
unique_ptr<Buffer> ubo;
|
||||
uint8_t *ubo_mapped = nullptr;
|
||||
uint8_t *ubo_mapped = nullptr;
|
||||
size_t ubo_sync_index_stride = 0;
|
||||
size_t ubo_offset = 0;
|
||||
size_t ubo_alignment = 1;
|
||||
size_t ubo_offset = 0;
|
||||
size_t ubo_alignment = 1;
|
||||
|
||||
VkSampler samplers[VULKAN_FILTER_CHAIN_COUNT][VULKAN_FILTER_CHAIN_COUNT][VULKAN_FILTER_CHAIN_ADDRESS_COUNT];
|
||||
|
||||
|
@ -1192,23 +1170,25 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
|
|||
if (!image_texture_load(&image, shader->path))
|
||||
return {};
|
||||
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_info.format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
image_info.extent.width = image.width;
|
||||
image_info.extent.height = image.height;
|
||||
image_info.extent.depth = 1;
|
||||
image_info.mipLevels = shader->mipmap ? num_miplevels(image.width, image.height) : 1;
|
||||
image_info.arrayLayers = 1;
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_info.format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
image_info.extent.width = image.width;
|
||||
image_info.extent.height = image.height;
|
||||
image_info.extent.depth = 1;
|
||||
image_info.mipLevels = shader->mipmap ? num_miplevels(image.width, image.height) : 1;
|
||||
image_info.arrayLayers = 1;
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
vkCreateImage(info->device, &image_info, nullptr, &tex);
|
||||
vkGetImageMemoryRequirements(info->device, tex, &mem_reqs);
|
||||
alloc.allocationSize = mem_reqs.size;
|
||||
alloc.memoryTypeIndex = vulkan_find_memory_type(
|
||||
|
||||
alloc.allocationSize = mem_reqs.size;
|
||||
alloc.memoryTypeIndex = vulkan_find_memory_type(
|
||||
&*info->memory_properties,
|
||||
mem_reqs.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
@ -1230,9 +1210,10 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
|
|||
view_info.subresourceRange.layerCount = 1;
|
||||
vkCreateImageView(info->device, &view_info, nullptr, &view);
|
||||
|
||||
buffer = unique_ptr<Buffer>(new Buffer(info->device, *info->memory_properties,
|
||||
image.width * image.height * sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
|
||||
ptr = buffer->map();
|
||||
buffer =
|
||||
unique_ptr<Buffer>(new Buffer(info->device, *info->memory_properties,
|
||||
image.width * image.height * sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
|
||||
ptr = buffer->map();
|
||||
memcpy(ptr, image.pixels, image.width * image.height * sizeof(uint32_t));
|
||||
buffer->unmap();
|
||||
|
||||
|
@ -1242,13 +1223,13 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
|
|||
0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageExtent.width = image.width;
|
||||
region.imageExtent.height = image.height;
|
||||
region.imageExtent.depth = 1;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageExtent.width = image.width;
|
||||
region.imageExtent.height = image.height;
|
||||
region.imageExtent.depth = 1;
|
||||
|
||||
vkCmdCopyBufferToImage(cmd, buffer->get_buffer(), tex,
|
||||
shader->mipmap ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
|
@ -1256,11 +1237,11 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
|
|||
|
||||
for (i = 1; i < image_info.mipLevels; i++)
|
||||
{
|
||||
VkImageBlit blit_region = {};
|
||||
unsigned src_width = MAX(image.width >> (i - 1), 1u);
|
||||
unsigned src_height = MAX(image.height >> (i - 1), 1u);
|
||||
unsigned target_width = MAX(image.width >> i, 1u);
|
||||
unsigned target_height = MAX(image.height >> i, 1u);
|
||||
VkImageBlit blit_region = {};
|
||||
unsigned src_width = MAX(image.width >> (i - 1), 1u);
|
||||
unsigned src_height = MAX(image.height >> (i - 1), 1u);
|
||||
unsigned target_width = MAX(image.width >> i, 1u);
|
||||
unsigned target_height = MAX(image.height >> i, 1u);
|
||||
|
||||
blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit_region.srcSubresource.mipLevel = i - 1;
|
||||
|
@ -1304,7 +1285,7 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
|
|||
tex, view, memory, move(buffer), image.width, image.height,
|
||||
shader->filter != RARCH_FILTER_NEAREST,
|
||||
image_info.mipLevels > 1,
|
||||
wrap_to_address(shader->wrap)));
|
||||
vk_wrap_to_address(shader->wrap)));
|
||||
|
||||
error:
|
||||
if (image.pixels)
|
||||
|
@ -1318,9 +1299,6 @@ error:
|
|||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static bool vulkan_filter_chain_load_luts(
|
||||
const struct vulkan_filter_chain_create_info *info,
|
||||
vulkan_filter_chain *chain,
|
||||
|
@ -1374,8 +1352,6 @@ error:
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
StaticTexture::StaticTexture(string id,
|
||||
VkDevice device,
|
||||
VkImage image,
|
||||
|
@ -1393,15 +1369,19 @@ StaticTexture::StaticTexture(string id,
|
|||
buffer(move(buffer)),
|
||||
id(move(id))
|
||||
{
|
||||
texture.filter = linear ? VULKAN_FILTER_CHAIN_LINEAR : VULKAN_FILTER_CHAIN_NEAREST;
|
||||
texture.mip_filter =
|
||||
mipmap && linear ? VULKAN_FILTER_CHAIN_LINEAR : VULKAN_FILTER_CHAIN_NEAREST;
|
||||
texture.address = address;
|
||||
texture.texture.image = image;
|
||||
texture.texture.view = view;
|
||||
texture.filter = VULKAN_FILTER_CHAIN_NEAREST;
|
||||
texture.mip_filter = VULKAN_FILTER_CHAIN_NEAREST;
|
||||
texture.address = address;
|
||||
texture.texture.image = image;
|
||||
texture.texture.view = view;
|
||||
texture.texture.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
texture.texture.width = width;
|
||||
texture.texture.width = width;
|
||||
texture.texture.height = height;
|
||||
|
||||
if (linear)
|
||||
texture.filter = VULKAN_FILTER_CHAIN_LINEAR;
|
||||
if (mipmap && linear)
|
||||
texture.mip_filter = VULKAN_FILTER_CHAIN_LINEAR;
|
||||
}
|
||||
|
||||
StaticTexture::~StaticTexture()
|
||||
|
@ -1420,17 +1400,17 @@ Buffer::Buffer(VkDevice device,
|
|||
device(device), size(size)
|
||||
{
|
||||
VkMemoryRequirements mem_reqs;
|
||||
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
info.size = size;
|
||||
info.usage = usage;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
|
||||
info.size = size;
|
||||
info.usage = usage;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
vkCreateBuffer(device, &info, nullptr, &buffer);
|
||||
|
||||
vkGetBufferMemoryRequirements(device, buffer, &mem_reqs);
|
||||
|
||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
alloc.allocationSize = mem_reqs.size;
|
||||
|
||||
alloc.memoryTypeIndex = vulkan_find_memory_type(
|
||||
&mem_props, mem_reqs.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
|
@ -1444,9 +1424,8 @@ void *Buffer::map()
|
|||
{
|
||||
if (!mapped)
|
||||
{
|
||||
if (vkMapMemory(device, memory, 0, size, 0, &mapped) == VK_SUCCESS)
|
||||
return mapped;
|
||||
return nullptr;
|
||||
if (vkMapMemory(device, memory, 0, size, 0, &mapped) != VK_SUCCESS)
|
||||
return nullptr;
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
|
@ -1482,17 +1461,20 @@ void Pass::set_shader(VkShaderStageFlags stage,
|
|||
const uint32_t *spirv,
|
||||
size_t spirv_words)
|
||||
{
|
||||
if (stage == VK_SHADER_STAGE_VERTEX_BIT)
|
||||
switch (stage)
|
||||
{
|
||||
vertex_shader.clear();
|
||||
vertex_shader.insert(end(vertex_shader),
|
||||
spirv, spirv + spirv_words);
|
||||
}
|
||||
else if (stage == VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
{
|
||||
fragment_shader.clear();
|
||||
fragment_shader.insert(end(fragment_shader),
|
||||
spirv, spirv + spirv_words);
|
||||
case VK_SHADER_STAGE_VERTEX_BIT:
|
||||
vertex_shader.clear();
|
||||
vertex_shader.insert(end(vertex_shader),
|
||||
spirv, spirv + spirv_words);
|
||||
break;
|
||||
case VK_SHADER_STAGE_FRAGMENT_BIT:
|
||||
fragment_shader.clear();
|
||||
fragment_shader.insert(end(fragment_shader),
|
||||
spirv, spirv + spirv_words);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,14 +1537,15 @@ Size2D Pass::set_pass_info(
|
|||
{
|
||||
clear_vk();
|
||||
|
||||
current_viewport = swapchain.viewport;
|
||||
pass_info = info;
|
||||
current_viewport = swapchain.viewport;
|
||||
pass_info = info;
|
||||
|
||||
num_sync_indices = swapchain.num_indices;
|
||||
sync_index = 0;
|
||||
num_sync_indices = swapchain.num_indices;
|
||||
sync_index = 0;
|
||||
|
||||
current_framebuffer_size = get_output_size(max_original, max_source);
|
||||
swapchain_render_pass = swapchain.render_pass;
|
||||
swapchain_render_pass = swapchain.render_pass;
|
||||
|
||||
return current_framebuffer_size;
|
||||
}
|
||||
|
||||
|
@ -1587,9 +1570,19 @@ bool Pass::init_pipeline_layout()
|
|||
unsigned i;
|
||||
vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
vector<VkDescriptorPoolSize> desc_counts;
|
||||
VkPushConstantRange push_range = {};
|
||||
VkDescriptorSetLayoutCreateInfo set_layout_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
|
||||
VkPipelineLayoutCreateInfo layout_info = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
|
||||
VkDescriptorPoolCreateInfo pool_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
|
||||
VkDescriptorSetAllocateInfo alloc_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
|
||||
|
||||
/* Main UBO. */
|
||||
VkShaderStageFlags ubo_mask = 0;
|
||||
VkShaderStageFlags ubo_mask = 0;
|
||||
|
||||
if (reflection.ubo_stage_mask & SLANG_STAGE_VERTEX_MASK)
|
||||
ubo_mask |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (reflection.ubo_stage_mask & SLANG_STAGE_FRAGMENT_MASK)
|
||||
|
@ -1608,10 +1601,11 @@ bool Pass::init_pipeline_layout()
|
|||
{
|
||||
for (auto &texture : semantic)
|
||||
{
|
||||
VkShaderStageFlags stages = 0;
|
||||
|
||||
if (!texture.texture)
|
||||
continue;
|
||||
|
||||
VkShaderStageFlags stages = 0;
|
||||
if (texture.stage_mask & SLANG_STAGE_VERTEX_MASK)
|
||||
stages |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (texture.stage_mask & SLANG_STAGE_FRAGMENT_MASK)
|
||||
|
@ -1624,22 +1618,17 @@ bool Pass::init_pipeline_layout()
|
|||
}
|
||||
}
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo set_layout_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
|
||||
set_layout_info.bindingCount = bindings.size();
|
||||
set_layout_info.pBindings = bindings.data();
|
||||
set_layout_info.bindingCount = bindings.size();
|
||||
set_layout_info.pBindings = bindings.data();
|
||||
|
||||
if (vkCreateDescriptorSetLayout(device,
|
||||
&set_layout_info, NULL, &set_layout) != VK_SUCCESS)
|
||||
return false;
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &set_layout;
|
||||
|
||||
/* Push constants */
|
||||
VkPushConstantRange push_range = {};
|
||||
if (reflection.push_constant_stage_mask && reflection.push_constant_size)
|
||||
{
|
||||
if (reflection.push_constant_stage_mask & SLANG_STAGE_VERTEX_MASK)
|
||||
|
@ -1650,27 +1639,23 @@ bool Pass::init_pipeline_layout()
|
|||
RARCH_LOG("[Vulkan]: Push Constant Block: %u bytes.\n", (unsigned int)reflection.push_constant_size);
|
||||
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = &push_range;
|
||||
layout_info.pPushConstantRanges = &push_range;
|
||||
push.buffer.resize((reflection.push_constant_size + sizeof(uint32_t) - 1) / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
push.stages = push_range.stageFlags;
|
||||
push.stages = push_range.stageFlags;
|
||||
push_range.size = reflection.push_constant_size;
|
||||
|
||||
if (vkCreatePipelineLayout(device,
|
||||
&layout_info, NULL, &pipeline_layout) != VK_SUCCESS)
|
||||
return false;
|
||||
|
||||
VkDescriptorPoolCreateInfo pool_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
|
||||
pool_info.maxSets = num_sync_indices;
|
||||
pool_info.poolSizeCount = desc_counts.size();
|
||||
pool_info.pPoolSizes = desc_counts.data();
|
||||
if (vkCreateDescriptorPool(device, &pool_info, nullptr, &pool) != VK_SUCCESS)
|
||||
return false;
|
||||
|
||||
VkDescriptorSetAllocateInfo alloc_info = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
|
||||
alloc_info.descriptorPool = pool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &set_layout;
|
||||
|
@ -1685,18 +1670,43 @@ bool Pass::init_pipeline_layout()
|
|||
|
||||
bool Pass::init_pipeline()
|
||||
{
|
||||
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
VkVertexInputAttributeDescription attributes[2] = {{0}};
|
||||
VkVertexInputBindingDescription binding = {0};
|
||||
VkPipelineVertexInputStateCreateInfo vertex_input = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
|
||||
VkPipelineRasterizationStateCreateInfo raster = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
VkPipelineColorBlendAttachmentState blend_attachment = {0};
|
||||
VkPipelineColorBlendStateCreateInfo blend = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
VkPipelineViewportStateCreateInfo viewport = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
|
||||
VkPipelineDepthStencilStateCreateInfo depth_stencil = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
VkPipelineMultisampleStateCreateInfo multisample = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
|
||||
VkPipelineDynamicStateCreateInfo dynamic = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||
static const VkDynamicState dynamics[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
VkPipelineShaderStageCreateInfo shader_stages[2] = {
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
};
|
||||
VkShaderModuleCreateInfo module_info = {
|
||||
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
|
||||
VkGraphicsPipelineCreateInfo pipe = {
|
||||
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
|
||||
|
||||
if (!init_pipeline_layout())
|
||||
return false;
|
||||
|
||||
/* Input assembly */
|
||||
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
|
||||
/* VAO state */
|
||||
VkVertexInputAttributeDescription attributes[2] = {{0}};
|
||||
VkVertexInputBindingDescription binding = {0};
|
||||
|
||||
attributes[0].location = 0;
|
||||
attributes[0].binding = 0;
|
||||
attributes[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
|
@ -1710,70 +1720,47 @@ bool Pass::init_pipeline()
|
|||
binding.stride = 4 * sizeof(float);
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertex_input = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
|
||||
vertex_input.vertexBindingDescriptionCount = 1;
|
||||
vertex_input.pVertexBindingDescriptions = &binding;
|
||||
vertex_input.vertexAttributeDescriptionCount = 2;
|
||||
vertex_input.pVertexAttributeDescriptions = attributes;
|
||||
|
||||
/* Raster state */
|
||||
VkPipelineRasterizationStateCreateInfo raster = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
raster.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
raster.cullMode = VK_CULL_MODE_NONE;
|
||||
raster.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
raster.depthClampEnable = false;
|
||||
raster.rasterizerDiscardEnable = false;
|
||||
raster.depthBiasEnable = false;
|
||||
raster.lineWidth = 1.0f;
|
||||
raster.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
raster.cullMode = VK_CULL_MODE_NONE;
|
||||
raster.frontFace =
|
||||
VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
raster.depthClampEnable = false;
|
||||
raster.rasterizerDiscardEnable = false;
|
||||
raster.depthBiasEnable = false;
|
||||
raster.lineWidth = 1.0f;
|
||||
|
||||
/* Blend state */
|
||||
VkPipelineColorBlendAttachmentState blend_attachment = {0};
|
||||
VkPipelineColorBlendStateCreateInfo blend = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
blend_attachment.blendEnable = false;
|
||||
blend_attachment.colorWriteMask = 0xf;
|
||||
blend.attachmentCount = 1;
|
||||
blend.pAttachments = &blend_attachment;
|
||||
blend_attachment.blendEnable = false;
|
||||
blend_attachment.colorWriteMask = 0xf;
|
||||
blend.attachmentCount = 1;
|
||||
blend.pAttachments = &blend_attachment;
|
||||
|
||||
/* Viewport state */
|
||||
VkPipelineViewportStateCreateInfo viewport = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
|
||||
viewport.viewportCount = 1;
|
||||
viewport.scissorCount = 1;
|
||||
viewport.viewportCount = 1;
|
||||
viewport.scissorCount = 1;
|
||||
|
||||
/* Depth-stencil state */
|
||||
VkPipelineDepthStencilStateCreateInfo depth_stencil = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
depth_stencil.depthTestEnable = false;
|
||||
depth_stencil.depthWriteEnable = false;
|
||||
depth_stencil.depthBoundsTestEnable = false;
|
||||
depth_stencil.stencilTestEnable = false;
|
||||
depth_stencil.minDepthBounds = 0.0f;
|
||||
depth_stencil.maxDepthBounds = 1.0f;
|
||||
depth_stencil.depthTestEnable = false;
|
||||
depth_stencil.depthWriteEnable = false;
|
||||
depth_stencil.depthBoundsTestEnable = false;
|
||||
depth_stencil.stencilTestEnable = false;
|
||||
depth_stencil.minDepthBounds = 0.0f;
|
||||
depth_stencil.maxDepthBounds = 1.0f;
|
||||
|
||||
/* Multisample state */
|
||||
VkPipelineMultisampleStateCreateInfo multisample = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
|
||||
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
/* Dynamic state */
|
||||
VkPipelineDynamicStateCreateInfo dynamic = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||
static const VkDynamicState dynamics[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
dynamic.pDynamicStates = dynamics;
|
||||
dynamic.dynamicStateCount = sizeof(dynamics) / sizeof(dynamics[0]);
|
||||
|
||||
/* Shaders */
|
||||
VkPipelineShaderStageCreateInfo shader_stages[2] = {
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
};
|
||||
|
||||
VkShaderModuleCreateInfo module_info = {
|
||||
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
|
||||
module_info.codeSize = vertex_shader.size() * sizeof(uint32_t);
|
||||
module_info.pCode = vertex_shader.data();
|
||||
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
@ -1786,8 +1773,6 @@ bool Pass::init_pipeline()
|
|||
shader_stages[1].pName = "main";
|
||||
vkCreateShaderModule(device, &module_info, NULL, &shader_stages[1].module);
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipe = {
|
||||
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
|
||||
pipe.stageCount = 2;
|
||||
pipe.pStages = shader_stages;
|
||||
pipe.pVertexInputState = &vertex_input;
|
||||
|
@ -1820,6 +1805,7 @@ CommonResources::CommonResources(VkDevice device,
|
|||
: device(device)
|
||||
{
|
||||
unsigned i;
|
||||
VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
/* The final pass uses an MVP designed for [0, 1] range VBO.
|
||||
* For in-between passes, we just go with identity matrices,
|
||||
* so keep it simple.
|
||||
|
@ -1838,14 +1824,14 @@ CommonResources::CommonResources(VkDevice device,
|
|||
1.0f, +1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
vbo = unique_ptr<Buffer>(new Buffer(device,
|
||||
memory_properties, sizeof(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
|
||||
vbo =
|
||||
unique_ptr<Buffer>(new Buffer(device,
|
||||
memory_properties, sizeof(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
|
||||
|
||||
void *ptr = vbo->map();
|
||||
void *ptr = vbo->map();
|
||||
memcpy(ptr, vbo_data, sizeof(vbo_data));
|
||||
vbo->unmap();
|
||||
|
||||
VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
info.mipLodBias = 0.0f;
|
||||
info.maxAnisotropy = 1.0f;
|
||||
info.compareEnable = false;
|
||||
|
@ -1974,9 +1960,9 @@ bool Pass::init_feedback()
|
|||
|
||||
bool Pass::build()
|
||||
{
|
||||
unordered_map<string, slang_semantic_map> semantic_map;
|
||||
unsigned i;
|
||||
unsigned j = 0;
|
||||
unordered_map<string, slang_semantic_map> semantic_map;
|
||||
|
||||
framebuffer.reset();
|
||||
framebuffer_feedback.reset();
|
||||
|
@ -2026,16 +2012,17 @@ void Pass::set_uniform_buffer(VkDescriptorSet set, unsigned binding,
|
|||
VkDeviceSize range)
|
||||
{
|
||||
VkDescriptorBufferInfo buffer_info;
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = range;
|
||||
|
||||
VkWriteDescriptorSet write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
||||
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = range;
|
||||
|
||||
write.dstSet = set;
|
||||
write.dstBinding = binding;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
write.pBufferInfo = &buffer_info;
|
||||
write.pBufferInfo = &buffer_info;
|
||||
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||
}
|
||||
|
@ -2044,11 +2031,12 @@ void Pass::set_texture(VkDescriptorSet set, unsigned binding,
|
|||
const Texture &texture)
|
||||
{
|
||||
VkDescriptorImageInfo image_info;
|
||||
VkWriteDescriptorSet write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
||||
|
||||
image_info.sampler = common->samplers[texture.filter][texture.mip_filter][texture.address];
|
||||
image_info.imageView = texture.texture.view;
|
||||
image_info.imageLayout = texture.texture.layout;
|
||||
|
||||
VkWriteDescriptorSet write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
|
||||
write.dstSet = set;
|
||||
write.dstBinding = binding;
|
||||
write.descriptorCount = 1;
|
||||
|
@ -2294,6 +2282,9 @@ void Pass::build_commands(
|
|||
* the passes that end up on-screen. */
|
||||
if (!final_pass)
|
||||
{
|
||||
VkRenderPassBeginInfo rp_info = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
|
||||
|
||||
/* Render. */
|
||||
vulkan_image_layout_transition_levels(cmd,
|
||||
framebuffer->get_image(), 1,
|
||||
|
@ -2304,8 +2295,6 @@ void Pass::build_commands(
|
|||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
|
||||
VkRenderPassBeginInfo rp_info = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
|
||||
rp_info.renderPass = framebuffer->get_render_pass();
|
||||
rp_info.framebuffer = framebuffer->get_framebuffer();
|
||||
rp_info.renderArea.extent.width = current_framebuffer_size.width;
|
||||
|
@ -2317,7 +2306,8 @@ void Pass::build_commands(
|
|||
}
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout,
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline_layout,
|
||||
0, 1, &sets[sync_index], 0, nullptr);
|
||||
|
||||
if (push.stages != 0)
|
||||
|
@ -2327,10 +2317,12 @@ void Pass::build_commands(
|
|||
push.buffer.data());
|
||||
}
|
||||
|
||||
VkDeviceSize offset = final_pass ? 16 * sizeof(float) : 0;
|
||||
vkCmdBindVertexBuffers(cmd, 0, 1,
|
||||
&common->vbo->get_buffer(),
|
||||
&offset);
|
||||
{
|
||||
VkDeviceSize offset = final_pass ? 16 * sizeof(float) : 0;
|
||||
vkCmdBindVertexBuffers(cmd, 0, 1,
|
||||
&common->vbo->get_buffer(),
|
||||
&offset);
|
||||
}
|
||||
|
||||
if (final_pass)
|
||||
{
|
||||
|
@ -2404,7 +2396,7 @@ Framebuffer::Framebuffer(
|
|||
{
|
||||
RARCH_LOG("[Vulkan filter chain]: Creating framebuffer %u x %u (max %u level(s)).\n",
|
||||
max_size.width, max_size.height, max_levels);
|
||||
init_render_pass();
|
||||
vulkan_initialize_render_pass(device, format, &render_pass);
|
||||
init(nullptr);
|
||||
}
|
||||
|
||||
|
@ -2429,9 +2421,12 @@ void Framebuffer::clear(VkCommandBuffer cmd)
|
|||
vkCmdClearColorImage(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&color, 1, &range);
|
||||
|
||||
vulkan_image_layout_transition_levels(cmd, image,VK_REMAINING_MIP_LEVELS,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
vulkan_image_layout_transition_levels(cmd, image,
|
||||
VK_REMAINING_MIP_LEVELS,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
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_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
@ -2488,6 +2483,9 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
|||
|
||||
for (i = 1; i < levels; i++)
|
||||
{
|
||||
unsigned src_width, src_height, target_width, target_height;
|
||||
VkImageBlit blit_region = {};
|
||||
|
||||
/* For subsequent passes, we have to transition
|
||||
* from DST_OPTIMAL to SRC_OPTIMAL,
|
||||
* but only do so one mip-level at a time. */
|
||||
|
@ -2509,11 +2507,10 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
|||
1, barriers);
|
||||
}
|
||||
|
||||
VkImageBlit blit_region = {};
|
||||
unsigned src_width = MAX(size.width >> (i - 1), 1u);
|
||||
unsigned src_height = MAX(size.height >> (i - 1), 1u);
|
||||
unsigned target_width = MAX(size.width >> i, 1u);
|
||||
unsigned target_height = MAX(size.height >> i, 1u);
|
||||
src_width = MAX(size.width >> (i - 1), 1u);
|
||||
src_height = MAX(size.height >> (i - 1), 1u);
|
||||
target_width = MAX(size.width >> i, 1u);
|
||||
target_height = MAX(size.height >> i, 1u);
|
||||
|
||||
blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit_region.srcSubresource.mipLevel = i - 1;
|
||||
|
@ -2607,7 +2604,11 @@ void Framebuffer::copy(VkCommandBuffer cmd,
|
|||
void Framebuffer::init(DeferredDisposer *disposer)
|
||||
{
|
||||
VkMemoryRequirements mem_reqs;
|
||||
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||
VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
VkImageViewCreateInfo view_info = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
info.format = format;
|
||||
info.extent.width = size.width;
|
||||
|
@ -2618,19 +2619,18 @@ void Framebuffer::init(DeferredDisposer *disposer)
|
|||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
levels = info.mipLevels;
|
||||
levels = info.mipLevels;
|
||||
|
||||
vkCreateImage(device, &info, nullptr, &image);
|
||||
|
||||
vkGetImageMemoryRequirements(device, image, &mem_reqs);
|
||||
|
||||
VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
alloc.allocationSize = mem_reqs.size;
|
||||
alloc.memoryTypeIndex = find_memory_type_fallback(
|
||||
memory_properties, mem_reqs.memoryTypeBits,
|
||||
|
@ -2657,8 +2657,6 @@ void Framebuffer::init(DeferredDisposer *disposer)
|
|||
|
||||
vkBindImageMemory(device, image, memory.memory, 0);
|
||||
|
||||
VkImageViewCreateInfo view_info = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
view_info.format = format;
|
||||
view_info.image = image;
|
||||
|
@ -2676,54 +2674,19 @@ void Framebuffer::init(DeferredDisposer *disposer)
|
|||
view_info.subresourceRange.levelCount = 1;
|
||||
vkCreateImageView(device, &view_info, nullptr, &fb_view);
|
||||
|
||||
init_framebuffer();
|
||||
}
|
||||
/* Initialize framebuffer */
|
||||
{
|
||||
VkFramebufferCreateInfo info = {
|
||||
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
|
||||
info.renderPass = render_pass;
|
||||
info.attachmentCount = 1;
|
||||
info.pAttachments = &fb_view;
|
||||
info.width = size.width;
|
||||
info.height = size.height;
|
||||
info.layers = 1;
|
||||
|
||||
void Framebuffer::init_render_pass()
|
||||
{
|
||||
VkRenderPassCreateInfo rp_info = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
|
||||
VkAttachmentReference color_ref = { 0,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
|
||||
|
||||
/* We will always write to the entire framebuffer,
|
||||
* so we don't really need to clear. */
|
||||
VkAttachmentDescription attachment = {0};
|
||||
attachment.format = format;
|
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
|
||||
attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {0};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &color_ref;
|
||||
|
||||
rp_info.attachmentCount = 1;
|
||||
rp_info.pAttachments = &attachment;
|
||||
rp_info.subpassCount = 1;
|
||||
rp_info.pSubpasses = &subpass;
|
||||
|
||||
vkCreateRenderPass(device, &rp_info, nullptr, &render_pass);
|
||||
}
|
||||
|
||||
void Framebuffer::init_framebuffer()
|
||||
{
|
||||
VkFramebufferCreateInfo info = {
|
||||
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
|
||||
info.renderPass = render_pass;
|
||||
info.attachmentCount = 1;
|
||||
info.pAttachments = &fb_view;
|
||||
info.width = size.width;
|
||||
info.height = size.height;
|
||||
info.layers = 1;
|
||||
|
||||
vkCreateFramebuffer(device, &info, nullptr, &framebuffer);
|
||||
vkCreateFramebuffer(device, &info, nullptr, &framebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::set_size(DeferredDisposer &disposer, const Size2D &size, VkFormat format)
|
||||
|
@ -2792,8 +2755,9 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_default(
|
|||
vulkan_filter_chain_filter filter)
|
||||
{
|
||||
struct vulkan_filter_chain_pass_info pass_info;
|
||||
auto tmpinfo = *info;
|
||||
tmpinfo.num_passes = 1;
|
||||
auto tmpinfo = *info;
|
||||
|
||||
tmpinfo.num_passes = 1;
|
||||
|
||||
unique_ptr<vulkan_filter_chain> chain{ new vulkan_filter_chain(tmpinfo) };
|
||||
if (!chain)
|
||||
|
@ -2971,7 +2935,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
param.initial = meta_param.initial;
|
||||
param.minimum = meta_param.minimum;
|
||||
param.maximum = meta_param.maximum;
|
||||
param.step = meta_param.step;
|
||||
param.step = meta_param.step;
|
||||
chain->add_parameter(i, shader->num_parameters, meta_param.id);
|
||||
shader->num_parameters++;
|
||||
}
|
||||
|
@ -3004,7 +2968,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
pass->filter == RARCH_FILTER_LINEAR ? VULKAN_FILTER_CHAIN_LINEAR :
|
||||
VULKAN_FILTER_CHAIN_NEAREST;
|
||||
}
|
||||
pass_info.address = wrap_to_address(pass->wrap);
|
||||
pass_info.address = vk_wrap_to_address(pass->wrap);
|
||||
pass_info.max_levels = 1;
|
||||
|
||||
/* TODO: Expose max_levels in slangp.
|
||||
|
@ -3025,18 +2989,16 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
|
||||
if (!pass->fbo.valid)
|
||||
{
|
||||
pass_info.scale_type_x = i + 1 == shader->passes
|
||||
? VULKAN_FILTER_CHAIN_SCALE_VIEWPORT
|
||||
: VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
pass_info.scale_type_y = i + 1 == shader->passes
|
||||
? VULKAN_FILTER_CHAIN_SCALE_VIEWPORT
|
||||
: VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
pass_info.scale_x = 1.0f;
|
||||
pass_info.scale_y = 1.0f;
|
||||
pass_info.scale_type_x = VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
pass_info.scale_type_y = VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
pass_info.scale_x = 1.0f;
|
||||
pass_info.scale_y = 1.0f;
|
||||
|
||||
if (i + 1 == shader->passes)
|
||||
{
|
||||
pass_info.rt_format = tmpinfo.swapchain.format;
|
||||
pass_info.scale_type_x = VULKAN_FILTER_CHAIN_SCALE_VIEWPORT;
|
||||
pass_info.scale_type_y = VULKAN_FILTER_CHAIN_SCALE_VIEWPORT;
|
||||
pass_info.rt_format = tmpinfo.swapchain.format;
|
||||
|
||||
if (explicit_format)
|
||||
RARCH_WARN("[slang]: Using explicit format for last pass in chain,"
|
||||
|
@ -3044,7 +3006,8 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
}
|
||||
else
|
||||
{
|
||||
pass_info.rt_format = glslang_format_to_vk(output.meta.rt_format);
|
||||
pass_info.rt_format = glslang_format_to_vk(
|
||||
output.meta.rt_format);
|
||||
RARCH_LOG("[slang]: Using render target format %s for pass output #%u.\n",
|
||||
glslang_format_to_string(output.meta.rt_format), i);
|
||||
}
|
||||
|
@ -3058,24 +3021,25 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
else if (pass->fbo.fp_fbo)
|
||||
output.meta.rt_format = SLANG_FORMAT_R16G16B16A16_SFLOAT;
|
||||
|
||||
pass_info.rt_format = glslang_format_to_vk(output.meta.rt_format);
|
||||
pass_info.rt_format = glslang_format_to_vk(output.meta.rt_format);
|
||||
|
||||
RARCH_LOG("[slang]: Using render target format %s for pass output #%u.\n",
|
||||
glslang_format_to_string(output.meta.rt_format), i);
|
||||
|
||||
switch (pass->fbo.type_x)
|
||||
{
|
||||
case RARCH_SCALE_INPUT:
|
||||
pass_info.scale_x = pass->fbo.scale_x;
|
||||
pass_info.scale_x = pass->fbo.scale_x;
|
||||
pass_info.scale_type_x = VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
break;
|
||||
|
||||
case RARCH_SCALE_ABSOLUTE:
|
||||
pass_info.scale_x = float(pass->fbo.abs_x);
|
||||
pass_info.scale_x = float(pass->fbo.abs_x);
|
||||
pass_info.scale_type_x = VULKAN_FILTER_CHAIN_SCALE_ABSOLUTE;
|
||||
break;
|
||||
|
||||
case RARCH_SCALE_VIEWPORT:
|
||||
pass_info.scale_x = pass->fbo.scale_x;
|
||||
pass_info.scale_x = pass->fbo.scale_x;
|
||||
pass_info.scale_type_x = VULKAN_FILTER_CHAIN_SCALE_VIEWPORT;
|
||||
break;
|
||||
}
|
||||
|
@ -3083,17 +3047,17 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
|||
switch (pass->fbo.type_y)
|
||||
{
|
||||
case RARCH_SCALE_INPUT:
|
||||
pass_info.scale_y = pass->fbo.scale_y;
|
||||
pass_info.scale_y = pass->fbo.scale_y;
|
||||
pass_info.scale_type_y = VULKAN_FILTER_CHAIN_SCALE_SOURCE;
|
||||
break;
|
||||
|
||||
case RARCH_SCALE_ABSOLUTE:
|
||||
pass_info.scale_y = float(pass->fbo.abs_y);
|
||||
pass_info.scale_y = float(pass->fbo.abs_y);
|
||||
pass_info.scale_type_y = VULKAN_FILTER_CHAIN_SCALE_ABSOLUTE;
|
||||
break;
|
||||
|
||||
case RARCH_SCALE_VIEWPORT:
|
||||
pass_info.scale_y = pass->fbo.scale_y;
|
||||
pass_info.scale_y = pass->fbo.scale_y;
|
||||
pass_info.scale_type_y = VULKAN_FILTER_CHAIN_SCALE_VIEWPORT;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,25 @@ struct vulkan_filter_chain_create_info
|
|||
struct vulkan_filter_chain_swapchain_info swapchain;
|
||||
};
|
||||
|
||||
static INLINE enum vulkan_filter_chain_address vk_wrap_to_address(enum gfx_wrap_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case RARCH_WRAP_BORDER:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER;
|
||||
case RARCH_WRAP_REPEAT:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_REPEAT;
|
||||
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT;
|
||||
case RARCH_WRAP_EDGE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return VULKAN_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
|
||||
vulkan_filter_chain_t *vulkan_filter_chain_new(
|
||||
const struct vulkan_filter_chain_create_info *info);
|
||||
void vulkan_filter_chain_free(vulkan_filter_chain_t *chain);
|
||||
|
|
Loading…
Reference in New Issue