rpcsx/rpcsx-gpu/FlipPipeline.cpp
2024-10-01 22:04:40 +03:00

282 lines
10 KiB
C++

#include "FlipPipeline.hpp"
#include "shaders/flip.vert.h"
#include "shaders/flip_alt.frag.h"
#include "shaders/flip_std.frag.h"
#include "vk.hpp"
#include <vulkan/vulkan.h>
FlipPipeline::~FlipPipeline() {
vkDestroyPipeline(vk::context->device, pipelines[0], vk::context->allocator);
vkDestroyPipeline(vk::context->device, pipelines[1], vk::context->allocator);
vkDestroyPipelineLayout(vk::context->device, pipelineLayout,
vk::context->allocator);
vkDestroyDescriptorPool(vk::context->device, descriptorPool,
vk::context->allocator);
vkDestroyDescriptorSetLayout(vk::context->device, descriptorSetLayout,
vk::context->allocator);
vkDestroyShaderModule(vk::context->device, flipVertShaderModule,
vk::context->allocator);
vkDestroyShaderModule(vk::context->device, flipFragStdShaderModule,
vk::context->allocator);
vkDestroyShaderModule(vk::context->device, flipFragAltShaderModule,
vk::context->allocator);
}
FlipPipeline::FlipPipeline() {
VkShaderModuleCreateInfo flipVertexModuleInfo{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = std::size(spirv_flip_vert) * sizeof(*spirv_flip_std_frag),
.pCode = spirv_flip_vert,
};
VkShaderModuleCreateInfo flipFragmentStdInfo{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = std::size(spirv_flip_std_frag) * sizeof(*spirv_flip_std_frag),
.pCode = spirv_flip_std_frag,
};
VkShaderModuleCreateInfo flipFragmentAltInfo{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.codeSize = std::size(spirv_flip_alt_frag) * sizeof(*spirv_flip_std_frag),
.pCode = spirv_flip_alt_frag,
};
VK_VERIFY(vkCreateShaderModule(vk::context->device, &flipVertexModuleInfo,
vk::context->allocator,
&flipVertShaderModule));
VK_VERIFY(vkCreateShaderModule(vk::context->device, &flipFragmentStdInfo,
vk::context->allocator,
&flipFragStdShaderModule));
VK_VERIFY(vkCreateShaderModule(vk::context->device, &flipFragmentAltInfo,
vk::context->allocator,
&flipFragAltShaderModule));
{
VkDescriptorSetLayoutBinding bindings[] = {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
{
.binding = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
};
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = std::size(bindings),
.pBindings = bindings,
};
vkCreateDescriptorSetLayout(vk::context->device,
&descriptorSetLayoutCreateInfo,
vk::context->allocator, &descriptorSetLayout);
}
{
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &descriptorSetLayout,
};
VK_VERIFY(vkCreatePipelineLayout(vk::context->device,
&pipelineLayoutCreateInfo,
vk::context->allocator, &pipelineLayout));
}
{
VkPipelineShaderStageCreateInfo stagesStd[]{
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
// .pNext = &flipVertexModuleInfo,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = flipVertShaderModule,
.pName = "main",
},
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
// .pNext = &flipFragmentStdInfo,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = flipFragStdShaderModule,
.pName = "main",
}};
VkPipelineShaderStageCreateInfo stagesAlt[]{
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
// .pNext = &flipVertexModuleInfo,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = flipVertShaderModule,
.pName = "main",
},
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
// .pNext = &flipFragmentAltInfo,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = flipFragAltShaderModule,
.pName = "main",
}};
VkPipelineVertexInputStateCreateInfo vertexInputState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
};
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
};
VkPipelineTessellationStateCreateInfo tessellationState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
};
VkPipelineRasterizationStateCreateInfo rasterizationState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
};
VkSampleMask sampleMask = -1;
VkPipelineMultisampleStateCreateInfo multisampleState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
.pSampleMask = &sampleMask,
};
VkPipelineDepthStencilStateCreateInfo depthStencilState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
};
VkPipelineColorBlendStateCreateInfo colorBlendState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
};
VkDynamicState dynamicStates[] = {
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
};
VkPipelineDynamicStateCreateInfo dynamicState{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = std::size(dynamicStates),
.pDynamicStates = dynamicStates,
};
VkGraphicsPipelineCreateInfo pipelineCreateInfos[]{
{
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = std::size(stagesStd),
.pStages = stagesStd,
.pVertexInputState = &vertexInputState,
.pInputAssemblyState = &inputAssemblyState,
.pTessellationState = &tessellationState,
.pRasterizationState = &rasterizationState,
.pMultisampleState = &multisampleState,
.pDepthStencilState = &depthStencilState,
.pColorBlendState = &colorBlendState,
.pDynamicState = &dynamicState,
.layout = pipelineLayout,
},
{
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = std::size(stagesAlt),
.pStages = stagesAlt,
.pVertexInputState = &vertexInputState,
.pInputAssemblyState = &inputAssemblyState,
.pTessellationState = &tessellationState,
.pRasterizationState = &rasterizationState,
.pMultisampleState = &multisampleState,
.pDepthStencilState = &depthStencilState,
.pColorBlendState = &colorBlendState,
.pDynamicState = &dynamicState,
.layout = pipelineLayout,
},
};
VK_VERIFY(vkCreateGraphicsPipelines(
vk::context->device, VK_NULL_HANDLE, std::size(pipelines),
pipelineCreateInfos, vk::context->allocator, pipelines));
}
{
VkDescriptorPoolSize poolSizes[]{
{
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount =
static_cast<std::uint32_t>(std::size(descriptorSets) * 2),
},
{
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount =
static_cast<std::uint32_t>(std::size(descriptorSets) * 2),
}};
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.maxSets = static_cast<std::uint32_t>(std::size(descriptorSets) * 2),
.poolSizeCount = std::size(poolSizes),
.pPoolSizes = poolSizes,
};
VK_VERIFY(vkCreateDescriptorPool(vk::context->device,
&descriptorPoolCreateInfo,
vk::context->allocator, &descriptorPool));
}
for (auto &set : descriptorSets) {
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = descriptorPool,
.descriptorSetCount = 1,
.pSetLayouts = &descriptorSetLayout,
};
VK_VERIFY(vkAllocateDescriptorSets(vk::context->device,
&descriptorSetAllocateInfo, &set));
}
}
void FlipPipeline::bind(Scheduler &sched, FlipType type, VkImageView imageView,
VkSampler sampler) {
auto cmdBuffer = sched.getCommandBuffer();
auto descriptorIndex = descriptorSetPool.acquire();
sched.afterSubmit(
[this, descriptorIndex] { descriptorSetPool.release(descriptorIndex); });
auto descriptorSet = descriptorSets[descriptorIndex];
VkDescriptorImageInfo imageInfo = {
.sampler = sampler,
.imageView = imageView,
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
};
VkWriteDescriptorSet writeDescSets[]{
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptorSet,
.dstBinding = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.pImageInfo = &imageInfo,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptorSet,
.dstBinding = 1,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfo,
},
};
vkUpdateDescriptorSets(vk::context->device, std::size(writeDescSets),
writeDescSets, 0, nullptr);
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelines[static_cast<int>(type)]);
}