|
@ -85,9 +85,9 @@ void ComputeAndGraphics::initVulkan() |
|
|
createImageViews(); |
|
|
createImageViews(); |
|
|
createRenderPass(); |
|
|
createRenderPass(); |
|
|
createDescriptorSetLayout(); |
|
|
createDescriptorSetLayout(); |
|
|
// createComputeDescriptorSetLayout();
|
|
|
createComputeDescriptorSetLayout(); |
|
|
createGraphicsPipeline(); |
|
|
createGraphicsPipeline(); |
|
|
// createComputePipeline();
|
|
|
createComputePipeline(); |
|
|
createCommandPool(); |
|
|
createCommandPool(); |
|
|
createDepthResources(); |
|
|
createDepthResources(); |
|
|
createFramebuffers(); |
|
|
createFramebuffers(); |
|
@ -96,14 +96,14 @@ void ComputeAndGraphics::initVulkan() |
|
|
createTextureSampler(); |
|
|
createTextureSampler(); |
|
|
createVertexBuffer(); |
|
|
createVertexBuffer(); |
|
|
createIndexBuffer(); |
|
|
createIndexBuffer(); |
|
|
// createShaderStorageBuffers();
|
|
|
createShaderStorageBuffers(); |
|
|
createUniformBuffers(); |
|
|
createUniformBuffers(); |
|
|
createDescriptorPool(); |
|
|
createDescriptorPool(); |
|
|
// createComputeDescriptorPool();
|
|
|
createComputeDescriptorPool(); |
|
|
createDescriptorSets(); |
|
|
createDescriptorSets(); |
|
|
// createComputeDescriptorSets();
|
|
|
createComputeDescriptorSets(); |
|
|
createCommandBuffer(); |
|
|
createCommandBuffer(); |
|
|
// createComputeCommandBuffers();
|
|
|
createComputeCommandBuffers(); |
|
|
createSyncObjects(); |
|
|
createSyncObjects(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -651,9 +651,9 @@ void ComputeAndGraphics::createDescriptorSetLayout() { |
|
|
void ComputeAndGraphics::createComputeDescriptorSetLayout() { |
|
|
void ComputeAndGraphics::createComputeDescriptorSetLayout() { |
|
|
VkDescriptorSetLayoutBinding uboLayoutBinding = createLayoutBindingInfo(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
VkDescriptorSetLayoutBinding uboLayoutBinding = createLayoutBindingInfo(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBinding computeLayoutBinding1 = createLayoutBindingInfo(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
VkDescriptorSetLayoutBinding computeLayoutBinding1 = createLayoutBindingInfo(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutBinding computeLayoutBinding2 = createLayoutBindingInfo(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
VkDescriptorSetLayoutBinding computeLayoutBinding2 = createLayoutBindingInfo(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); |
|
|
|
|
|
|
|
|
std::vector<VkDescriptorSetLayoutBinding> bindings = {uboLayoutBinding, computeLayoutBinding1, computeLayoutBinding2}; |
|
|
std::vector<VkDescriptorSetLayoutBinding> bindings = {uboLayoutBinding, computeLayoutBinding1, computeLayoutBinding2}; |
|
|
VkDescriptorSetLayoutCreateInfo layoutInfo{}; |
|
|
VkDescriptorSetLayoutCreateInfo layoutInfo{}; |
|
@ -1022,6 +1022,9 @@ void ComputeAndGraphics::createTextureImage() { |
|
|
int texWidth, texHeight, texChannels; |
|
|
int texWidth, texHeight, texChannels; |
|
|
stbi_uc* pixels = stbi_load("/home/ali-mehrabani/Qt_projects/VkTest/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); |
|
|
stbi_uc* pixels = stbi_load("/home/ali-mehrabani/Qt_projects/VkTest/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); |
|
|
VkDeviceSize imageSize = texWidth * texHeight * 4; |
|
|
VkDeviceSize imageSize = texWidth * texHeight * 4; |
|
|
|
|
|
// qDebug() << imageSize;
|
|
|
|
|
|
// qDebug() << texWidth;
|
|
|
|
|
|
// qDebug() << texHeight;
|
|
|
|
|
|
|
|
|
if (!pixels) { |
|
|
if (!pixels) { |
|
|
throw std::runtime_error("failed to load texture image!"); |
|
|
throw std::runtime_error("failed to load texture image!"); |
|
@ -1034,13 +1037,13 @@ void ComputeAndGraphics::createTextureImage() { |
|
|
|
|
|
|
|
|
stbi_image_free(pixels); |
|
|
stbi_image_free(pixels); |
|
|
|
|
|
|
|
|
createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL |
|
|
createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_LINEAR |
|
|
, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
|
, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
|
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _textureImage, _textureImageMemory); |
|
|
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _textureImage, _textureImageMemory); |
|
|
|
|
|
|
|
|
transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1); |
|
|
// transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1);
|
|
|
copyBufferToImage(stagingBuffer, _textureImage, static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight)); |
|
|
// copyBufferToImage(stagingBuffer, _textureImage, static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight));
|
|
|
transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); |
|
|
// transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1);
|
|
|
|
|
|
|
|
|
vkDestroyBuffer(_device, stagingBuffer, nullptr); |
|
|
vkDestroyBuffer(_device, stagingBuffer, nullptr); |
|
|
vkFreeMemory(_device, stagingBufferMemory, nullptr); |
|
|
vkFreeMemory(_device, stagingBufferMemory, nullptr); |
|
@ -1428,61 +1431,42 @@ uint32_t ComputeAndGraphics::findMemoryType(uint32_t typeFilter, VkMemoryPropert |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::createShaderStorageBuffers() { |
|
|
void ComputeAndGraphics::createShaderStorageBuffers() { |
|
|
|
|
|
int texWidth, texHeight, texChannels; |
|
|
|
|
|
stbi_uc* pixels = stbi_load("/home/ali-mehrabani/Qt_projects/VkTest/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); |
|
|
|
|
|
_textureImageSize = texWidth * texHeight * 4; |
|
|
|
|
|
_textureImageWidth = texWidth; |
|
|
|
|
|
_textureImageHeight = texHeight; |
|
|
|
|
|
|
|
|
|
|
|
if (!pixels) { |
|
|
|
|
|
throw std::runtime_error("failed to load texture image!"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
VkBuffer stagingBuffer; |
|
|
VkBuffer stagingBuffer; |
|
|
VkDeviceMemory stagingBufferMemory; |
|
|
VkDeviceMemory stagingBufferMemory; |
|
|
copyParticlesToStagingBuffer(stagingBuffer, stagingBufferMemory); |
|
|
copyImageToStagingBuffer(stagingBuffer, stagingBufferMemory, pixels, _textureImageSize); |
|
|
|
|
|
|
|
|
initShaderStorageBuffers(stagingBuffer); |
|
|
initShaderStorageBuffers(stagingBuffer, _textureImageSize); |
|
|
|
|
|
|
|
|
vkDestroyBuffer(_device, stagingBuffer, nullptr); |
|
|
vkDestroyBuffer(_device, stagingBuffer, nullptr); |
|
|
vkFreeMemory(_device, stagingBufferMemory, nullptr); |
|
|
vkFreeMemory(_device, stagingBufferMemory, nullptr); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::initShaderStorageBuffers(VkBuffer& stagingBuffer) |
|
|
void ComputeAndGraphics::initShaderStorageBuffers(VkBuffer& stagingBuffer, VkDeviceSize bufferSize) |
|
|
{ |
|
|
{ |
|
|
VkDeviceSize bufferSize = sizeof(Particle) * PARTICLE_COUNT; |
|
|
_shaderRawStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
_shaderStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
_shaderRawStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
_shaderStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
_shaderTransformedStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
|
|
|
_shaderTransformedStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
|
|
|
|
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
|
createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
|
createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
|
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderStorageBuffers[i], _shaderStorageBuffersMemory[i]); |
|
|
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderRawStorageBuffers[i], _shaderRawStorageBuffersMemory[i]); |
|
|
copyBuffer(stagingBuffer, _shaderStorageBuffers[i], bufferSize); |
|
|
copyBuffer(stagingBuffer, _shaderRawStorageBuffers[i], bufferSize); |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ComputeAndGraphics::copyParticlesToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory) |
|
|
createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
|
{ |
|
|
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderTransformedStorageBuffers[i], _shaderTransformedStorageBuffersMemory[i]); |
|
|
std::vector<Particle> particles = initParticles(); |
|
|
copyBuffer(stagingBuffer, _shaderTransformedStorageBuffers[i], bufferSize); |
|
|
|
|
|
|
|
|
VkDeviceSize bufferSize = sizeof(Particle) * PARTICLE_COUNT; |
|
|
|
|
|
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
|
|
|
|
, stagingBuffer, stagingBufferMemory); |
|
|
|
|
|
|
|
|
|
|
|
void* data; |
|
|
|
|
|
vkMapMemory(_device, stagingBufferMemory, 0, bufferSize, 0, &data); |
|
|
|
|
|
memcpy(data, particles.data(), reinterpret_cast<size_t>(bufferSize)); |
|
|
|
|
|
vkUnmapMemory(_device, stagingBufferMemory); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::vector<Particle> ComputeAndGraphics::initParticles() |
|
|
|
|
|
{ |
|
|
|
|
|
std::default_random_engine rndEngine(static_cast<unsigned>(time(nullptr))); |
|
|
|
|
|
std::uniform_real_distribution<float> rndDist(0.0f, 1.0f); |
|
|
|
|
|
|
|
|
|
|
|
std::vector<Particle> particles(PARTICLE_COUNT); |
|
|
|
|
|
for (auto& particle : particles) { |
|
|
|
|
|
float r = 0.25f * sqrt(rndDist(rndEngine)); |
|
|
|
|
|
float theta = rndDist(rndEngine) * 2.0f * 3.14159265358979323846f; |
|
|
|
|
|
float x = r * cos(theta) * HEIGHT / WIDTH; |
|
|
|
|
|
float y = r * sin(theta); |
|
|
|
|
|
particle.position = glm::vec2(x, y); |
|
|
|
|
|
particle.velocity = glm::normalize(glm::vec2(x,y)) * 0.00025f; |
|
|
|
|
|
particle.color = glm::vec4(rndDist(rndEngine), rndDist(rndEngine), rndDist(rndEngine), 1.0f); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return particles; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::createUniformBuffers() { |
|
|
void ComputeAndGraphics::createUniformBuffers() { |
|
@ -1547,19 +1531,19 @@ void ComputeAndGraphics::createDescriptorSets() |
|
|
|
|
|
|
|
|
std::array<VkWriteDescriptorSet, 2> descriptorWrites{}; |
|
|
std::array<VkWriteDescriptorSet, 2> descriptorWrites{}; |
|
|
|
|
|
|
|
|
addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, i, 0); |
|
|
addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, _descriptorSets[i], 0); |
|
|
|
|
|
|
|
|
addImageWriteDescriptor(descriptorWrites[1], &imageInfo, i, 1); |
|
|
addImageWriteDescriptor(descriptorWrites[1], &imageInfo, _descriptorSets[i], 1); |
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(_device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); |
|
|
vkUpdateDescriptorSets(_device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index |
|
|
void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet |
|
|
, uint32_t dstBinding) |
|
|
, uint32_t dstBinding) |
|
|
{ |
|
|
{ |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.dstSet = _descriptorSets[index]; |
|
|
descriptorWrite.dstSet = dstSet; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; |
|
@ -1567,11 +1551,11 @@ void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& d |
|
|
descriptorWrite.pBufferInfo = bufferInfo; |
|
|
descriptorWrite.pBufferInfo = bufferInfo; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, size_t index |
|
|
void ComputeAndGraphics::addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, VkDescriptorSet dstSet |
|
|
, uint32_t dstBinding) |
|
|
, uint32_t dstBinding) |
|
|
{ |
|
|
{ |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.dstSet = _descriptorSets[index]; |
|
|
descriptorWrite.dstSet = dstSet; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
|
@ -1623,24 +1607,23 @@ void ComputeAndGraphics::createComputeDescriptorSets() |
|
|
|
|
|
|
|
|
std::array<VkWriteDescriptorSet, 3> descriptorWrites{}; |
|
|
std::array<VkWriteDescriptorSet, 3> descriptorWrites{}; |
|
|
|
|
|
|
|
|
addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, i, 0); |
|
|
addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, _computeDescriptorSets[i], 0); |
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo storageBufferInfoLastFrame = createDescriptorBufferInfo(_shaderStorageBuffers[(i - 1) % MAX_FRAMES_IN_FLIGHT] |
|
|
VkDescriptorBufferInfo storageBufferInfoLastFrame = createDescriptorBufferInfo(_shaderRawStorageBuffers[i], _textureImageSize); |
|
|
, sizeof(Particle) * PARTICLE_COUNT); |
|
|
addStorageBufferWriteDescriptor(descriptorWrites[1], &storageBufferInfoLastFrame, _computeDescriptorSets[i], 1); |
|
|
addStorageBufferWriteDescriptor(descriptorWrites[1], &storageBufferInfoLastFrame, i, 1); |
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorBufferInfo storageBufferInfoCurrentFrame = createDescriptorBufferInfo(_shaderStorageBuffers[i], sizeof(Particle) * PARTICLE_COUNT); |
|
|
VkDescriptorBufferInfo storageBufferInfoCurrentFrame = createDescriptorBufferInfo(_shaderTransformedStorageBuffers[i], _textureImageSize); |
|
|
addStorageBufferWriteDescriptor(descriptorWrites[2], &storageBufferInfoCurrentFrame, i, 2); |
|
|
addStorageBufferWriteDescriptor(descriptorWrites[2], &storageBufferInfoCurrentFrame, _computeDescriptorSets[i], 2); |
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(_device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); |
|
|
vkUpdateDescriptorSets(_device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index |
|
|
void ComputeAndGraphics::addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet |
|
|
, uint32_t dstBinding) |
|
|
, uint32_t dstBinding) |
|
|
{ |
|
|
{ |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; |
|
|
descriptorWrite.dstSet = _descriptorSets[index]; |
|
|
descriptorWrite.dstSet = dstSet; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstBinding = dstBinding; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.dstArrayElement = 0; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; |
|
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; |
|
@ -1657,7 +1640,7 @@ void ComputeAndGraphics::allocateComputeDescriptorSets() |
|
|
allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT); |
|
|
allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT); |
|
|
allocInfo.pSetLayouts = layouts.data(); |
|
|
allocInfo.pSetLayouts = layouts.data(); |
|
|
|
|
|
|
|
|
_descriptorSets.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
_computeDescriptorSets.resize(MAX_FRAMES_IN_FLIGHT); |
|
|
if (vkAllocateDescriptorSets(_device, &allocInfo, _computeDescriptorSets.data()) != VK_SUCCESS) { |
|
|
if (vkAllocateDescriptorSets(_device, &allocInfo, _computeDescriptorSets.data()) != VK_SUCCESS) { |
|
|
throw std::runtime_error("failed to allocate descriptor sets!"); |
|
|
throw std::runtime_error("failed to allocate descriptor sets!"); |
|
|
} |
|
|
} |
|
@ -1733,7 +1716,9 @@ void ComputeAndGraphics::mainLoop() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::drawFrame(){ |
|
|
void ComputeAndGraphics::drawFrame(){ |
|
|
// computeSubmission();
|
|
|
computeSubmission(); |
|
|
|
|
|
|
|
|
|
|
|
copyTransformedBufferToTextureImage(); |
|
|
|
|
|
|
|
|
VkResult result = graphicsSubmission(); |
|
|
VkResult result = graphicsSubmission(); |
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR) |
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR) |
|
@ -1744,12 +1729,17 @@ void ComputeAndGraphics::drawFrame(){ |
|
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; |
|
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ComputeAndGraphics::copyTransformedBufferToTextureImage() |
|
|
|
|
|
{ |
|
|
|
|
|
transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1); |
|
|
|
|
|
copyBufferToImage(_shaderTransformedStorageBuffers[currentFrame], _textureImage, _textureImageWidth, _textureImageHeight); |
|
|
|
|
|
transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::computeSubmission() |
|
|
void ComputeAndGraphics::computeSubmission() |
|
|
{ |
|
|
{ |
|
|
vkWaitForFences(_device, 1, &_computeInFlightFences[currentFrame], VK_TRUE, UINT64_MAX); |
|
|
vkWaitForFences(_device, 1, &_computeInFlightFences[currentFrame], VK_TRUE, UINT64_MAX); |
|
|
|
|
|
|
|
|
updateUniformBuffer(currentFrame); |
|
|
|
|
|
|
|
|
|
|
|
vkResetFences(_device, 1, &_computeInFlightFences[currentFrame]); |
|
|
vkResetFences(_device, 1, &_computeInFlightFences[currentFrame]); |
|
|
|
|
|
|
|
|
vkResetCommandBuffer(_computeCommandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0); |
|
|
vkResetCommandBuffer(_computeCommandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0); |
|
@ -1790,10 +1780,10 @@ VkResult ComputeAndGraphics::graphicsSubmission() |
|
|
throw std::runtime_error("failed to acquire swap chain image!"); |
|
|
throw std::runtime_error("failed to acquire swap chain image!"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// VkSemaphore waitSemaphores[] = {_computeFinishedSemaphores[currentFrame], _imageAvailableSemaphores[currentFrame]};
|
|
|
VkSemaphore waitSemaphores[] = {_computeFinishedSemaphores[currentFrame], _imageAvailableSemaphores[currentFrame]}; |
|
|
// VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; |
|
|
VkSemaphore waitSemaphores[] = {_imageAvailableSemaphores[currentFrame]}; |
|
|
// VkSemaphore waitSemaphores[] = {_imageAvailableSemaphores[currentFrame]};
|
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; |
|
|
// VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
|
VkSemaphore signalSemaphores[] = {_renderFinishedSemaphores[currentFrame]}; |
|
|
VkSemaphore signalSemaphores[] = {_renderFinishedSemaphores[currentFrame]}; |
|
|
|
|
|
|
|
|
drawSubmission(imageIndex, waitSemaphores, waitStages, signalSemaphores); |
|
|
drawSubmission(imageIndex, waitSemaphores, waitStages, signalSemaphores); |
|
@ -1825,7 +1815,7 @@ VkSubmitInfo ComputeAndGraphics::createDrawSubmitInfo(VkSemaphore* waitSemaphore |
|
|
VkSubmitInfo submitInfo{}; |
|
|
VkSubmitInfo submitInfo{}; |
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
|
|
|
|
submitInfo.waitSemaphoreCount = 1; |
|
|
submitInfo.waitSemaphoreCount = 2; |
|
|
submitInfo.pWaitSemaphores = waitSemaphores; |
|
|
submitInfo.pWaitSemaphores = waitSemaphores; |
|
|
submitInfo.pWaitDstStageMask = waitStages; |
|
|
submitInfo.pWaitDstStageMask = waitStages; |
|
|
|
|
|
|
|
@ -1958,7 +1948,7 @@ void ComputeAndGraphics::recordComputeCommandBuffer(VkCommandBuffer commandBuffe |
|
|
|
|
|
|
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, _computePipelineLayout, 0, 1, &_computeDescriptorSets[currentFrame], 0, nullptr); |
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, _computePipelineLayout, 0, 1, &_computeDescriptorSets[currentFrame], 0, nullptr); |
|
|
|
|
|
|
|
|
vkCmdDispatch(commandBuffer, PARTICLE_COUNT / 256, 1, 1); |
|
|
vkCmdDispatch(commandBuffer, static_cast<uint32_t>(_textureImageSize / 8), 1, 1); |
|
|
|
|
|
|
|
|
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { |
|
|
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { |
|
|
throw std::runtime_error("failed to record compute command buffer!"); |
|
|
throw std::runtime_error("failed to record compute command buffer!"); |
|
@ -1973,8 +1963,8 @@ void ComputeAndGraphics::updateUniformBuffer(uint32_t currentImage) { |
|
|
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count(); |
|
|
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count(); |
|
|
|
|
|
|
|
|
UniformBufferObject ubo{}; |
|
|
UniformBufferObject ubo{}; |
|
|
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(22.5f), glm::vec3(0.0f, 0.0f, 1.0f)); |
|
|
ubo.model = glm::rotate(glm::mat4(1.0f), glm::radians(0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); |
|
|
ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); |
|
|
ubo.view = glm::lookAt(glm::vec3(0.001f, 0.001f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); |
|
|
ubo.proj = glm::perspective(glm::radians(45.0f), _swapChainExtent.width / static_cast<float>(_swapChainExtent.height), 0.1f, 10.0f); |
|
|
ubo.proj = glm::perspective(glm::radians(45.0f), _swapChainExtent.width / static_cast<float>(_swapChainExtent.height), 0.1f, 10.0f); |
|
|
ubo.proj[1][1] *= -1; |
|
|
ubo.proj[1][1] *= -1; |
|
|
|
|
|
|
|
@ -2030,8 +2020,10 @@ void ComputeAndGraphics::cleanPipeline() |
|
|
void ComputeAndGraphics::cleanBuffers() |
|
|
void ComputeAndGraphics::cleanBuffers() |
|
|
{ |
|
|
{ |
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
|
vkDestroyBuffer(_device, _shaderStorageBuffers[i], nullptr); |
|
|
vkDestroyBuffer(_device, _shaderRawStorageBuffers[i], nullptr); |
|
|
vkFreeMemory(_device, _shaderStorageBuffersMemory[i], nullptr); |
|
|
vkFreeMemory(_device, _shaderRawStorageBuffersMemory[i], nullptr); |
|
|
|
|
|
vkDestroyBuffer(_device, _shaderTransformedStorageBuffers[i], nullptr); |
|
|
|
|
|
vkFreeMemory(_device, _shaderTransformedStorageBuffersMemory[i], nullptr); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { |
|
@ -2075,6 +2067,15 @@ void ComputeAndGraphics::cleanBase() |
|
|
glfwTerminate(); |
|
|
glfwTerminate(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ComputeAndGraphics::cleanDescriptors() |
|
|
|
|
|
{ |
|
|
|
|
|
vkDestroyDescriptorPool(_device, _descriptorPool, nullptr); |
|
|
|
|
|
vkDestroyDescriptorSetLayout(_device, _descriptorSetLayout, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
vkDestroyDescriptorPool(_device, _computeDescriptorPool, nullptr); |
|
|
|
|
|
vkDestroyDescriptorSetLayout(_device, _computeDescriptorSetLayout, nullptr); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void ComputeAndGraphics::cleanup() |
|
|
void ComputeAndGraphics::cleanup() |
|
|
{ |
|
|
{ |
|
|
cleanupSwapChain(); |
|
|
cleanupSwapChain(); |
|
@ -2085,9 +2086,7 @@ void ComputeAndGraphics::cleanup() |
|
|
vkDestroyImage(_device, _textureImage, nullptr); |
|
|
vkDestroyImage(_device, _textureImage, nullptr); |
|
|
vkFreeMemory(_device, _textureImageMemory, nullptr); |
|
|
vkFreeMemory(_device, _textureImageMemory, nullptr); |
|
|
|
|
|
|
|
|
vkDestroyDescriptorPool(_device, _descriptorPool, nullptr); |
|
|
cleanDescriptors(); |
|
|
|
|
|
|
|
|
vkDestroyDescriptorSetLayout(_device, _descriptorSetLayout, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
cleanBuffers(); |
|
|
cleanBuffers(); |
|
|
|
|
|
|
|
|