Separate reconstruction framebuffer
This commit is contained in:
parent
8ccd994e5b
commit
ba7d9abe25
2 changed files with 235 additions and 82 deletions
312
vkplayer.cpp
312
vkplayer.cpp
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
// todo: REMOVE THIS. Why "simpliest triangle" demos even use this????
|
||||
// It does not "HELP" drawing 2D triangle!!! It is not useful in engines using own matrix transform code!
|
||||
//#include <glm/gtc/matrix_transform.hpp>
|
||||
#define MAX_SWAPCHAIN_IMAGES 32
|
||||
#define MAX_SWAPCHAIN_IMAGES 8
|
||||
// workaround for ffmpeg stable api nonsence with incompatible pointers between versions
|
||||
struct PointerWrap
|
||||
{
|
||||
|
@ -47,8 +47,6 @@ struct Vertex
|
|||
|
||||
struct DecoderImage
|
||||
{
|
||||
VkSamplerYcbcrConversion ycbcr_sampler_conversion;
|
||||
VkSampler ycbcr_sampler;
|
||||
VkImage image;
|
||||
VkDeviceMemory image_memory;
|
||||
// todo: deduplicate shared parameters
|
||||
|
@ -59,7 +57,7 @@ struct DecoderImage
|
|||
};
|
||||
|
||||
|
||||
void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image)
|
||||
void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image, const VkSamplerYcbcrConversionInfo &ycbcr_info)
|
||||
{
|
||||
|
||||
CallWith(Image2dInfo(VK_IMAGE_USAGE_SAMPLED_BIT, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, 1920, 1080,
|
||||
|
@ -97,31 +95,7 @@ void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image
|
|||
$F(bindInfo[1], $(image) = image.image, $(memory) = image.image_memory, $(memoryOffset) = image.memory_offset_plane1);
|
||||
PFN_vkBindImageMemory2 pvkBindImageMemory2 = (PFN_vkBindImageMemory2)vkGetInstanceProcAddr(inst, "vkBindImageMemory2KHR");
|
||||
pvkBindImageMemory2(dev.device, 2, bindInfo);
|
||||
PFN_vkCreateSamplerYcbcrConversion pvkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)vkGetInstanceProcAddr(inst, "vkCreateSamplerYcbcrConversionKHR");
|
||||
|
||||
|
||||
CallWith($M(VkSamplerYcbcrConversionCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO},
|
||||
$(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
|
||||
$(ycbcrModel) = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY,
|
||||
$(ycbcrRange) = VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
|
||||
$(xChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, // zero
|
||||
$(yChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
$(chromaFilter) = VK_FILTER_NEAREST), // zero
|
||||
pvkCreateSamplerYcbcrConversion(dev.device, &ref, NULL, &image.ycbcr_sampler_conversion));
|
||||
|
||||
$Sc ycbcr_info = $M(VkSamplerYcbcrConversionInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO},
|
||||
$(conversion) = image.ycbcr_sampler_conversion);
|
||||
CallWith($M(VkSamplerCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, &ycbcr_info},
|
||||
$(magFilter) = VK_FILTER_NEAREST,
|
||||
$(minFilter) = VK_FILTER_NEAREST,
|
||||
$(mipmapMode) = VK_SAMPLER_MIPMAP_MODE_NEAREST, // zero
|
||||
$(addressModeU) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(addressModeV) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(addressModeW) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(maxLod) = 1.0f,
|
||||
$(borderColor) = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK),
|
||||
vkCreateSampler(dev.device, &ref, NULL, &image.ycbcr_sampler);
|
||||
);
|
||||
CallWith($M(VkImageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &ycbcr_info},
|
||||
$(image) = image.image, $(viewType) = VK_IMAGE_VIEW_TYPE_2D,
|
||||
$(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
|
||||
|
@ -145,6 +119,8 @@ void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image
|
|||
static struct FFmpegDecoder
|
||||
{
|
||||
DecoderImage images[MAX_DECODER_FRAMES];
|
||||
VkSamplerYcbcrConversion ycbcr_sampler_conversion;
|
||||
VkSampler ycbcr_sampler;
|
||||
// todo: align thread-shared data to unshare with immutable
|
||||
volatile int decode_index, present_index;
|
||||
pthread_t thread = 0;
|
||||
|
@ -227,8 +203,33 @@ static void *DecoderThread(void*)
|
|||
|
||||
static void SetupFFMpeg(VkInstance inst, VulkanDevice &dev)
|
||||
{
|
||||
PFN_vkCreateSamplerYcbcrConversion pvkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)vkGetInstanceProcAddr(inst, "vkCreateSamplerYcbcrConversionKHR");
|
||||
|
||||
|
||||
CallWith($M(VkSamplerYcbcrConversionCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO},
|
||||
$(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
|
||||
$(ycbcrModel) = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY,
|
||||
$(ycbcrRange) = VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
|
||||
$(xChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, // zero
|
||||
$(yChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
$(chromaFilter) = VK_FILTER_NEAREST), // zero
|
||||
pvkCreateSamplerYcbcrConversion(dev.device, &ref, NULL, &gFF.ycbcr_sampler_conversion));
|
||||
|
||||
$Sc ycbcr_info = $M(VkSamplerYcbcrConversionInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO},
|
||||
$(conversion) = gFF.ycbcr_sampler_conversion);
|
||||
CallWith($M(VkSamplerCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, &ycbcr_info},
|
||||
$(magFilter) = VK_FILTER_NEAREST,
|
||||
$(minFilter) = VK_FILTER_NEAREST,
|
||||
$(mipmapMode) = VK_SAMPLER_MIPMAP_MODE_NEAREST, // zero
|
||||
$(addressModeU) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(addressModeV) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(addressModeW) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
$(maxLod) = 1.0f,
|
||||
$(borderColor) = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK),
|
||||
vkCreateSampler(dev.device, &ref, NULL, &gFF.ycbcr_sampler);
|
||||
);
|
||||
for(int i = 0; i < MAX_DECODER_FRAMES; i++)
|
||||
CreateSoftwareImage(inst, dev, gFF.images[i]);
|
||||
CreateSoftwareImage(inst, dev, gFF.images[i], ycbcr_info);
|
||||
pthread_mutex_init(&gFF.mutex, NULL);
|
||||
pthread_cond_init(&gFF.cond, NULL);
|
||||
pthread_create(&gFF.thread, NULL, &DecoderThread, NULL);
|
||||
|
@ -240,7 +241,7 @@ static void SetupFFMpeg(VkInstance inst, VulkanDevice &dev)
|
|||
struct GraphicsApplicationPipeline: BaseVulkanPipeline
|
||||
{
|
||||
|
||||
void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers)
|
||||
void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count)
|
||||
{
|
||||
|
||||
device = dev;
|
||||
|
@ -248,9 +249,9 @@ struct GraphicsApplicationPipeline: BaseVulkanPipeline
|
|||
//BasicBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,1,VK_SHADER_STAGE_VERTEX_BIT)
|
||||
BasicBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,1,VK_SHADER_STAGE_FRAGMENT_BIT, pImmutableSamplers)
|
||||
);
|
||||
CreatePool(1,
|
||||
CreatePool(count,
|
||||
//BasicPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count)
|
||||
);
|
||||
VkShaderModule vp, fp;
|
||||
CreateGraphicsPipeline(renderPass,
|
||||
|
@ -282,7 +283,7 @@ struct GraphicsApplicationPipeline: BaseVulkanPipeline
|
|||
struct ComputeApplicationPipeline: BaseVulkanPipeline
|
||||
{
|
||||
|
||||
void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count)
|
||||
void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count1, int count2, int count3)
|
||||
{
|
||||
|
||||
device = dev;
|
||||
|
@ -290,9 +291,9 @@ struct ComputeApplicationPipeline: BaseVulkanPipeline
|
|||
BasicBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,1,VK_SHADER_STAGE_COMPUTE_BIT, pImmutableSamplers),
|
||||
BasicBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,1,VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
);
|
||||
CreatePool(count,
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count),
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, count));
|
||||
CreatePool((count1 + count3) * count2,
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count2 * count3),
|
||||
BasicPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, count3 * count2 * count1));
|
||||
VkShaderModule shader;
|
||||
CreateComputePipeline(ShaderFromFile(shader, "quad.comp.spv", VK_SHADER_STAGE_COMPUTE_BIT));
|
||||
// todo: should not we destroy shader internally?
|
||||
|
@ -311,15 +312,27 @@ struct GraphicsApplication
|
|||
VulkanContext context;
|
||||
VulkanDevice dev;
|
||||
GLFWwindow *window = NULL;
|
||||
|
||||
// swapchain stuff
|
||||
VkSwapchainKHR swapchain;
|
||||
VkSurfaceKHR surface;
|
||||
VkImage swapchainImages[MAX_SWAPCHAIN_IMAGES];
|
||||
unsigned int numSwapchainImages;
|
||||
VulkanFramebuffer swapchainFbs[MAX_SWAPCHAIN_IMAGES];
|
||||
VkCommandBuffer commandBuffers[MAX_SWAPCHAIN_IMAGES * RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkCommandBuffer reconstructionCommandBuffers[MAX_DECODER_FRAMES * RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkFence chainFences[MAX_SWAPCHAIN_IMAGES];
|
||||
VkSemaphore swapchainRenderSemaphore[MAX_SWAPCHAIN_IMAGES], swapchainPresentSemaphore[MAX_SWAPCHAIN_IMAGES];
|
||||
|
||||
// direct reconstruction to swapchain
|
||||
VkCommandBuffer commandBuffers[MAX_SWAPCHAIN_IMAGES * MAX_DECODER_FRAMES];
|
||||
|
||||
// reconstruction to temporary framebuffer
|
||||
VulkanFramebuffer reconstructionFbs[RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkImage reconstructionImages[RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkDeviceMemory reconstructionImagesMem[RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkCommandBuffer reconstructionCommandBuffers[MAX_DECODER_FRAMES * RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkCommandBuffer presentCommandBuffers[MAX_SWAPCHAIN_IMAGES * RECONSTRUCTION_TARGET_FRAMES];
|
||||
VkSemaphore reconstructionSemaphore[RECONSTRUCTION_TARGET_FRAMES];
|
||||
|
||||
struct UBO
|
||||
{
|
||||
//glm::mat4 transformationMatrix;
|
||||
|
@ -328,7 +341,9 @@ struct GraphicsApplication
|
|||
GraphicsApplicationPipeline graphicsPipeline;
|
||||
ComputeApplicationPipeline computePipeline;
|
||||
VkDescriptorSet descriptorSet;
|
||||
VkDescriptorSet descriptorSets[MAX_SWAPCHAIN_IMAGES];
|
||||
VkDescriptorSet swapchainDescriptorSets[MAX_SWAPCHAIN_IMAGES*MAX_DECODER_FRAMES];
|
||||
VkDescriptorSet reconstructionDescriptorSets[RECONSTRUCTION_TARGET_FRAMES*MAX_DECODER_FRAMES];
|
||||
VkDescriptorSet decodeDescriptorSet[MAX_DECODER_FRAMES];
|
||||
VulkanBuffer uboBuf;
|
||||
VulkanBuffer stagingVert;
|
||||
VulkanBuffer stagingInd;
|
||||
|
@ -378,7 +393,7 @@ struct GraphicsApplication
|
|||
$(imageColorSpace) = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
||||
$(imageExtent) = VkExtent2D{width, height},
|
||||
$(imageArrayLayers),$(queueFamilyIndexCount),$(clipped),
|
||||
$(imageUsage) = graphics?VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
$(imageUsage) = VK_IMAGE_USAGE_TRANSFER_DST_BIT | (graphics?VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:VK_IMAGE_USAGE_STORAGE_BIT),
|
||||
$(pQueueFamilyIndices) = &dev.defaultFamilyIndex,
|
||||
$(preTransform) = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
$(compositeAlpha) = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
|
||||
|
@ -468,7 +483,8 @@ struct GraphicsApplication
|
|||
#else
|
||||
#define ENABLE_VALIDATION_LAYERS 0
|
||||
#endif
|
||||
bool compute = true;
|
||||
bool compute = false;
|
||||
bool separateReconstruction = false;
|
||||
context.Create("streamingengine", "vulkan-playground-server", ENABLE_VALIDATION_LAYERS);
|
||||
dev.Create(context.FindPhysicalDevice(), compute?VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT);
|
||||
dev.CreateDevice(context);
|
||||
|
@ -476,24 +492,73 @@ struct GraphicsApplication
|
|||
int height = 1080;
|
||||
CreateWindow("demo", width, height, false);
|
||||
CreateSwapchain(width,height, !compute);
|
||||
printf("%d swapchain images\n", numSwapchainImages);
|
||||
dev.CreateAndMap(uboBuf, sizeof(UBO));
|
||||
SetupFFMpeg(context.instance, dev);
|
||||
for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++)
|
||||
{
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(dev.device, &semaphoreCreateInfo, nullptr, &reconstructionSemaphore[i]));
|
||||
CallWith(Image2dInfo(VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
VK_FORMAT_B8G8R8A8_UNORM, width, height),
|
||||
vkCreateImage(dev.device, &ref,NULL, &reconstructionImages[i]));
|
||||
|
||||
VkMemoryRequirements mem_reqs;
|
||||
vkGetImageMemoryRequirements(dev.device, reconstructionImages[i], &mem_reqs);
|
||||
|
||||
VkMemoryAllocateInfo mem_alloc = AllocateInfo(mem_reqs.size);
|
||||
|
||||
if (!dev.GetMemoryType(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
&mem_alloc.memoryTypeIndex))
|
||||
printf("Could not find memory type.\n");
|
||||
|
||||
VK_CHECK_RESULT(vkAllocateMemory(dev.device, &mem_alloc, NULL, &reconstructionImagesMem[i]));
|
||||
VK_CHECK_RESULT(vkBindImageMemory(dev.device, reconstructionImages[i], reconstructionImagesMem[i], 0));
|
||||
}
|
||||
if(compute)
|
||||
{
|
||||
computePipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.images[0].ycbcr_sampler, numSwapchainImages);
|
||||
computePipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.ycbcr_sampler, numSwapchainImages, MAX_DECODER_FRAMES, RECONSTRUCTION_TARGET_FRAMES);
|
||||
for(int i = 0; i < numSwapchainImages; i++)
|
||||
{
|
||||
descriptorSets[i] = computePipeline.AllocateSingleDescriptorSet();
|
||||
computePipeline.UpdateDescriptors(descriptorSets[i], gFF.images[0].image_view, gFF.images[0].ycbcr_sampler, swapchainFbs[i].color_view);
|
||||
for(int j = 0; j < MAX_DECODER_FRAMES; j++)
|
||||
{
|
||||
int ci = MAX_DECODER_FRAMES * i + j;
|
||||
swapchainDescriptorSets[ci] = computePipeline.AllocateSingleDescriptorSet();
|
||||
computePipeline.UpdateDescriptors(swapchainDescriptorSets[ci], gFF.images[j].image_view, gFF.ycbcr_sampler, swapchainFbs[i].color_view);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++)
|
||||
{
|
||||
CallWith($M(VkImageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO},
|
||||
$(image) = reconstructionImages[i], $(viewType) = VK_IMAGE_VIEW_TYPE_2D,
|
||||
$(format) = VK_FORMAT_B8G8R8A8_UNORM,
|
||||
$(subresourceRange) = SubresourceRange()),
|
||||
vkCreateImageView(dev.device, &ref, NULL, &reconstructionFbs[i].color_view));
|
||||
|
||||
for(int j = 0; j < MAX_DECODER_FRAMES; j++)
|
||||
{
|
||||
int ci = MAX_DECODER_FRAMES * i + j;
|
||||
reconstructionDescriptorSets[ci] = computePipeline.AllocateSingleDescriptorSet();
|
||||
computePipeline.UpdateDescriptors(reconstructionDescriptorSets[ci], gFF.images[j].image_view, gFF.ycbcr_sampler, reconstructionFbs[i].color_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
graphicsPipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.images[0].ycbcr_sampler);
|
||||
descriptorSet = graphicsPipeline.AllocateSingleDescriptorSet();
|
||||
graphicsPipeline.UpdateDescriptors(descriptorSet, gFF.images[0].image_view, gFF.images[0].ycbcr_sampler);
|
||||
graphicsPipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.ycbcr_sampler, MAX_DECODER_FRAMES);
|
||||
for(int j = 0; j < MAX_DECODER_FRAMES; j++)
|
||||
{
|
||||
decodeDescriptorSet[j] = graphicsPipeline.AllocateSingleDescriptorSet();
|
||||
graphicsPipeline.UpdateDescriptors(decodeDescriptorSet[j], gFF.images[j].image_view, gFF.ycbcr_sampler);
|
||||
}
|
||||
for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++)
|
||||
{
|
||||
reconstructionFbs[i].Create(dev.device);
|
||||
reconstructionFbs[i].CreateDepthAttachment(dev,VK_FORMAT_D32_SFLOAT, width, height);
|
||||
reconstructionFbs[i].Init(reconstructionImages[i],VK_FORMAT_B8G8R8A8_UNORM, width, height);
|
||||
}
|
||||
}
|
||||
updateUniformData();
|
||||
/*updateUniformData();
|
||||
|
||||
Vertex vertices[] = {
|
||||
{ { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f } },
|
||||
|
@ -505,60 +570,143 @@ struct GraphicsApplication
|
|||
|
||||
dev.CreateBuffer(stagingVert, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, sizeof(vertices), vertices);
|
||||
dev.CreateBuffer(stagingInd, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, sizeof(indices), indices);
|
||||
*/
|
||||
for(int i = 0; i < numSwapchainImages; i++)
|
||||
{
|
||||
commandBuffers[i] = dev.CreateCommandBuffer();
|
||||
//VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
//vkCmdClearColorImage(commandBuffers[i], swapchainImages[i],VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, &color, 1, &range );
|
||||
if(!compute)
|
||||
for(int j = 0; j < MAX_DECODER_FRAMES; j++)
|
||||
{
|
||||
swapchainFbs[i].BeginRenderPass(commandBuffers[i]);
|
||||
swapchainFbs[i].SetViewportAndScissor(commandBuffers[i]);
|
||||
int ci = MAX_DECODER_FRAMES * i + j;
|
||||
commandBuffers[ci] = dev.CreateCommandBuffer();
|
||||
//VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
//vkCmdClearColorImage(commandBuffers[i], swapchainImages[i],VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, &color, 1, &range );
|
||||
if(!compute)
|
||||
{
|
||||
swapchainFbs[i].BeginRenderPass(commandBuffers[ci]);
|
||||
swapchainFbs[i].SetViewportAndScissor(commandBuffers[ci]);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffers[i],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
|
||||
vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline);
|
||||
// VkDeviceSize offset = 0;
|
||||
//vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset);
|
||||
//vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
//vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0);
|
||||
vkCmdDraw(commandBuffers[i], 4, 1, 0, 0);
|
||||
vkCmdEndRenderPass(commandBuffers[i]);
|
||||
VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
vkCmdBindDescriptorSets(commandBuffers[ci],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &decodeDescriptorSet[j], 0, nullptr);
|
||||
vkCmdBindPipeline(commandBuffers[ci], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline);
|
||||
// VkDeviceSize offset = 0;
|
||||
//vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset);
|
||||
//vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
//vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0);
|
||||
vkCmdDraw(commandBuffers[ci], 4, 1, 0, 0);
|
||||
vkCmdEndRenderPass(commandBuffers[ci]);
|
||||
VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
}
|
||||
else
|
||||
{
|
||||
const int WIDTH = 1920; // Size of rendered mandelbrot set.
|
||||
const int HEIGHT = 1080; // Size of renderered mandelbrot set.
|
||||
const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader.
|
||||
VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
vkCmdBindPipeline(commandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline);
|
||||
vkCmdBindDescriptorSets(commandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &swapchainDescriptorSets[ci], 0, NULL);
|
||||
vkCmdDispatch(commandBuffers[ci], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1);
|
||||
VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
}
|
||||
vkEndCommandBuffer(commandBuffers[ci]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int WIDTH = 1920; // Size of rendered mandelbrot set.
|
||||
const int HEIGHT = 1080; // Size of renderered mandelbrot set.
|
||||
const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader.
|
||||
VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline);
|
||||
vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &descriptorSets[i], 0, NULL);
|
||||
vkCmdDispatch(commandBuffers[i], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1);
|
||||
VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
}
|
||||
vkEndCommandBuffer(commandBuffers[i]);
|
||||
VK_CHECK_RESULT(CallWith(FenceInfo(VK_FENCE_CREATE_SIGNALED_BIT),
|
||||
vkCreateFence(dev.device, &ref, NULL, &chainFences[i])));
|
||||
}
|
||||
for(int i = 0; i < numSwapchainImages; i++)
|
||||
{
|
||||
for(int j = 0; j < RECONSTRUCTION_TARGET_FRAMES; j++)
|
||||
{
|
||||
int ci = RECONSTRUCTION_TARGET_FRAMES*i+j;
|
||||
presentCommandBuffers[ci] = dev.CreateCommandBuffer();
|
||||
//VulkanTexture::SetImageLayout(presentCommandBuffers[ci], reconstructionImages[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
VulkanTexture::SetImageLayout(presentCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
VkImageCopy regions = $M(VkImageCopy{}, $(srcSubresource) = SubresourceLayers(), $(dstSubresource) = SubresourceLayers(), $(extent) = VkExtent3D{1920, 1080, 1});
|
||||
vkCmdCopyImage(presentCommandBuffers[ci], reconstructionImages[j],VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchainImages[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ions);
|
||||
VulkanTexture::SetImageLayout(presentCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
vkEndCommandBuffer(presentCommandBuffers[ci]);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++)
|
||||
{
|
||||
for(int j = 0; j < MAX_DECODER_FRAMES; j++)
|
||||
{
|
||||
int ci = RECONSTRUCTION_TARGET_FRAMES*i+j;
|
||||
reconstructionCommandBuffers[ci] = dev.CreateCommandBuffer();
|
||||
if(!compute)
|
||||
{
|
||||
VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
|
||||
reconstructionFbs[i].BeginRenderPass(reconstructionCommandBuffers[ci]);
|
||||
reconstructionFbs[i].SetViewportAndScissor(reconstructionCommandBuffers[ci]);
|
||||
|
||||
vkCmdBindDescriptorSets(reconstructionCommandBuffers[ci],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &decodeDescriptorSet[j], 0, nullptr);
|
||||
vkCmdBindPipeline(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline);
|
||||
// VkDeviceSize offset = 0;
|
||||
//vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset);
|
||||
//vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
//vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0);
|
||||
vkCmdDraw(reconstructionCommandBuffers[ci], 4, 1, 0, 0);
|
||||
vkCmdEndRenderPass(reconstructionCommandBuffers[ci]);
|
||||
VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
}
|
||||
else
|
||||
{
|
||||
const int WIDTH = 1920; // Size of rendered mandelbrot set.
|
||||
const int HEIGHT = 1080; // Size of renderered mandelbrot set.
|
||||
const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader.
|
||||
//VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
vkCmdBindPipeline(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline);
|
||||
vkCmdBindDescriptorSets(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &reconstructionDescriptorSets[ci], 0, NULL);
|
||||
vkCmdDispatch(reconstructionCommandBuffers[ci], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1);
|
||||
VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||
}
|
||||
vkEndCommandBuffer(reconstructionCommandBuffers[ci]);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t idx = 0;
|
||||
int sem_idx = 0;
|
||||
int ridx = 0;
|
||||
while(true)
|
||||
{
|
||||
updateUniformData();
|
||||
sem_idx = (sem_idx + 1) % numSwapchainImages;
|
||||
waitFence(sem_idx);
|
||||
idx = AcquireImage(sem_idx);
|
||||
int decoder_idx = WaitActiveFrame() & 3;
|
||||
VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
vkResetFences(dev.device,1, &chainFences[sem_idx]);
|
||||
CallWith(
|
||||
SubmitInfo(
|
||||
commandBuffers[idx],$(waitSemaphoreCount), $(signalSemaphoreCount),
|
||||
$(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx],
|
||||
$(pSignalSemaphores) = &swapchainPresentSemaphore[idx],
|
||||
$(pWaitDstStageMask) = &waitDstStageMask),
|
||||
vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx]));
|
||||
|
||||
if(separateReconstruction)
|
||||
{
|
||||
CallWith(
|
||||
SubmitInfo(
|
||||
reconstructionCommandBuffers[ridx * MAX_DECODER_FRAMES + decoder_idx],$(waitSemaphoreCount), $(signalSemaphoreCount),
|
||||
$(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx],
|
||||
$(pSignalSemaphores) = &reconstructionSemaphore[ridx],
|
||||
$(pWaitDstStageMask) = &waitDstStageMask),
|
||||
vkQueueSubmit(dev.defautQueue, 1, &ref, NULL));
|
||||
CallWith(
|
||||
SubmitInfo(
|
||||
presentCommandBuffers[idx * RECONSTRUCTION_TARGET_FRAMES + ridx],$(waitSemaphoreCount), $(signalSemaphoreCount),
|
||||
$(pWaitSemaphores) = &reconstructionSemaphore[ridx],
|
||||
$(pSignalSemaphores) = &swapchainPresentSemaphore[idx],
|
||||
$(pWaitDstStageMask) = &waitDstStageMask),
|
||||
vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx]));
|
||||
ridx = (ridx + 1) & 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
CallWith(
|
||||
SubmitInfo(
|
||||
commandBuffers[idx*MAX_DECODER_FRAMES + decoder_idx],$(waitSemaphoreCount), $(signalSemaphoreCount),
|
||||
$(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx],
|
||||
$(pSignalSemaphores) = &swapchainPresentSemaphore[idx],
|
||||
$(pWaitDstStageMask) = &waitDstStageMask),
|
||||
vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx]));
|
||||
}
|
||||
|
||||
PresentImage(idx);
|
||||
|
||||
}
|
||||
vkDeviceWaitIdle(dev.device);
|
||||
graphicsPipeline.Destroy();
|
||||
|
|
|
@ -74,6 +74,11 @@ VkSubresourceLayout SubresourceLayout(VkDeviceSize pitch, const Args&... argumen
|
|||
{
|
||||
return $M(VkSubresourceLayout{0},$(rowPitch) = pitch,arguments...);
|
||||
}
|
||||
template <typename... Args>
|
||||
VkImageSubresourceLayers SubresourceLayers(const Args&... arguments)
|
||||
{
|
||||
return $M(VkImageSubresourceLayers{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, arguments...);
|
||||
}
|
||||
|
||||
VkFenceCreateInfo FenceInfo(VkFenceCreateFlags flags = 0)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue