recreate descriptors

This commit is contained in:
tylermurphy534 2022-09-20 23:04:33 -04:00
parent 249f6c9fa3
commit b6438c6779
6 changed files with 103 additions and 95 deletions

View file

@ -12,11 +12,13 @@ namespace xe {
XeImage::XeImage(XeDevice &xeDevice, const std::string &filename) : xeDevice{xeDevice} { XeImage::XeImage(XeDevice &xeDevice, const std::string &filename) : xeDevice{xeDevice} {
createTextureImage(filename); createTextureImage(filename);
createTextureImageView();
} }
XeImage::~XeImage() { XeImage::~XeImage() {
vkDestroyImage(xeDevice.device(), textureImage, nullptr); vkDestroyImage(xeDevice.device(), textureImage, nullptr);
vkFreeMemory(xeDevice.device(), textureImageMemory, nullptr); vkFreeMemory(xeDevice.device(), textureImageMemory, nullptr);
vkDestroyImageView(xeDevice.device(), textureImageView, nullptr);
} }
void XeImage::createTextureImage(const std::string &filename) { void XeImage::createTextureImage(const std::string &filename) {
@ -94,73 +96,90 @@ void XeImage::createImage(uint32_t width, uint32_t height, VkFormat format, VkIm
} }
void XeImage::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { void XeImage::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) {
VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands();
VkImageMemoryBarrier barrier{}; VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = oldLayout; barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout; barrier.newLayout = newLayout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image; barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1; barrier.subresourceRange.layerCount = 1;
VkPipelineStageFlags sourceStage; VkPipelineStageFlags sourceStage;
VkPipelineStageFlags destinationStage; VkPipelineStageFlags destinationStage;
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
barrier.srcAccessMask = 0; barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
} else { } else {
throw std::invalid_argument("unsupported layout transition!"); throw std::invalid_argument("unsupported layout transition!");
}
vkCmdPipelineBarrier(
commandBuffer,
sourceStage, destinationStage,
0,
0, nullptr,
0, nullptr,
1, &barrier
);
xeDevice.endSingleTimeCommands(commandBuffer);
} }
void XeImage::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) { vkCmdPipelineBarrier(
VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands(); commandBuffer,
sourceStage, destinationStage,
0,
0, nullptr,
0, nullptr,
1, &barrier
);
VkBufferImageCopy region{}; xeDevice.endSingleTimeCommands(commandBuffer);
region.bufferOffset = 0; }
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = {0, 0, 0};
region.imageExtent = {
width,
height,
1
};
vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); void XeImage::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) {
VkCommandBuffer commandBuffer = xeDevice.beginSingleTimeCommands();
xeDevice.endSingleTimeCommands(commandBuffer); VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = {0, 0, 0};
region.imageExtent = {
width,
height,
1
};
vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
xeDevice.endSingleTimeCommands(commandBuffer);
}
void XeImage::createTextureImageView() {
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = textureImage;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(xeDevice.device(), &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
} }
}
} }

View file

@ -22,10 +22,12 @@ class XeImage {
void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory); void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory);
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout); void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height); void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height);
void createTextureImageView();
XeDevice &xeDevice; XeDevice &xeDevice;
VkImage textureImage; VkImage textureImage;
VkImageView textureImageView;
VkDeviceMemory textureImageMemory; VkDeviceMemory textureImageMemory;
friend class XeRenderSystem; friend class XeRenderSystem;

View file

@ -25,13 +25,13 @@ XeRenderSystem::XeRenderSystem(
XeImage *image XeImage *image
) : xeDevice{xeEngine.xeDevice}, ) : xeDevice{xeEngine.xeDevice},
xeRenderer{xeEngine.xeRenderer}, xeRenderer{xeEngine.xeRenderer},
xeDescriptorPool{xeEngine.xeDescriptorPool},
pushCunstantDataSize{pushCunstantDataSize}, pushCunstantDataSize{pushCunstantDataSize},
uniformBufferDataSize{uniformBufferDataSize}, uniformBufferDataSize{uniformBufferDataSize},
textureSamplerBinding{image != nullptr} { textureSamplerBinding{image != nullptr} {
createDescriptorSetLayout(); createDescriptorSetLayout();
createUniformBuffers(); createUniformBuffers();
createTextureImageView(image); createDescriptorSets(image);
createDescriptorSets(*xeEngine.xeDescriptorPool);
createPipelineLayout(); createPipelineLayout();
createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag); createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag);
} }
@ -41,7 +41,6 @@ XeRenderSystem::~XeRenderSystem() {
vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr); vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr);
if ( textureSamplerBinding ) { if ( textureSamplerBinding ) {
vkDestroySampler(xeDevice.device(), textureSampler, nullptr); vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
vkDestroyImageView(xeDevice.device(), textureImageView, nullptr);
} }
}; };
@ -100,34 +99,18 @@ void XeRenderSystem::createUniformBuffers() {
} }
void XeRenderSystem::createTextureImageView(XeImage *image) { void XeRenderSystem::createDescriptorSets(XeImage *image) {
if (!textureSamplerBinding) {
return;
}
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image->textureImage;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(xeDevice.device(), &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
}
}
void XeRenderSystem::createDescriptorSets(XeDescriptorPool &xeDescriptorPool) {
descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT); descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
for (int i = 0; i < descriptorSets.size(); i++) { for (int i = 0; i < descriptorSets.size(); i++) {
auto bufferInfo = uboBuffers[i]->descriptorInfo(); updateDescriptorSet(image, i, true);
XeDescriptorWriter writer{*xeDescriptorSetLayout, xeDescriptorPool}; }
}
void XeRenderSystem::updateDescriptorSet(XeImage *image, int frameIndex, bool allocate) {
auto bufferInfo = uboBuffers[frameIndex]->descriptorInfo();
XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool};
int binding = 0; int binding = 0;
@ -139,13 +122,16 @@ void XeRenderSystem::createDescriptorSets(XeDescriptorPool &xeDescriptorPool) {
if (textureSamplerBinding) { if (textureSamplerBinding) {
VkDescriptorImageInfo imageInfo{}; VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfo.imageView = textureImageView; imageInfo.imageView = image->textureImageView;
imageInfo.sampler = textureSampler; imageInfo.sampler = textureSampler;
writer.writeImage(binding, &imageInfo); writer.writeImage(binding, &imageInfo);
binding += 1; binding += 1;
} }
writer.build(descriptorSets[i]); if (allocate) {
} writer.build(descriptorSets[frameIndex]);
} else {
writer.overwrite(descriptorSets[frameIndex]);
}
} }
@ -234,7 +220,7 @@ void XeRenderSystem::loadUniformObject(void *uniformBufferData) {
} }
void XeRenderSystem::loadTexture(XeImage *image) { void XeRenderSystem::loadTexture(XeImage *image) {
// createTextureImageView(image); updateDescriptorSet(image, xeRenderer.getFrameIndex(), false);
} }
void XeRenderSystem::render(XeGameObject &gameObject) { void XeRenderSystem::render(XeGameObject &gameObject) {

View file

@ -41,8 +41,8 @@ class XeRenderSystem {
void createDescriptorSetLayout(); void createDescriptorSetLayout();
void createUniformBuffers(); void createUniformBuffers();
void createTextureImageView(XeImage *image); void createDescriptorSets(XeImage *image);
void createDescriptorSets(XeDescriptorPool &xeDescriptorPool); void updateDescriptorSet(XeImage *image, int frameIndex, bool allocate);
void createPipelineLayout(); void createPipelineLayout();
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag); void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag);
@ -61,9 +61,9 @@ class XeRenderSystem {
std::vector<VkDescriptorSet> descriptorSets; std::vector<VkDescriptorSet> descriptorSets;
VkSampler textureSampler; VkSampler textureSampler;
VkImageView textureImageView;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool;
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout; std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;
}; };

View file

@ -13,7 +13,7 @@ namespace xe {
class XeSwapChain { class XeSwapChain {
public: public:
static constexpr int MAX_FRAMES_IN_FLIGHT = 3; static constexpr int MAX_FRAMES_IN_FLIGHT = 2;
XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent); XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent);
XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent, std::shared_ptr<XeSwapChain> previous); XeSwapChain(XeDevice &deviceRef, VkExtent2D windowExtent, std::shared_ptr<XeSwapChain> previous);

View file

@ -7,12 +7,13 @@ SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage)
void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) { void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) {
xeRenderSystem.loadTexture(xeImage);
xeRenderSystem.start(); xeRenderSystem.start();
UniformBuffer ubo{}; UniformBuffer ubo{};
ubo.projectionView = xeCamera.getProjection() * xeCamera.getView(); ubo.projectionView = xeCamera.getProjection() * xeCamera.getView();
xeRenderSystem.loadUniformObject(&ubo); xeRenderSystem.loadUniformObject(&ubo);
xeRenderSystem.loadTexture(xeImage);
for(auto &obj : gameObjects) { for(auto &obj : gameObjects) {
PushConstant pc{}; PushConstant pc{};