forked from RichDavisonNCL/VulkanRendering
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVulkanTexture.cpp
72 lines (62 loc) · 2.98 KB
/
VulkanTexture.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/******************************************************************************
This file is part of the Newcastle Vulkan Tutorial Series
Author:Rich Davison
Contact:[email protected]
License: MIT (see LICENSE file at the top of the source tree)
*//////////////////////////////////////////////////////////////////////////////
#include "VulkanTexture.h"
#include "Vulkanrenderer.h"
#include "TextureLoader.h"
#include "VulkanUtils.h"
#include "VulkanBuffers.h"
#include "VulkanBufferBuilder.h"
using namespace NCL;
using namespace Rendering;
using namespace Vulkan;
VulkanTexture::VulkanTexture() {
mipCount = 0;
layerCount = 0;
format = vk::Format::eUndefined;
}
VulkanTexture::~VulkanTexture() {
if (image) {
vmaDestroyImage(allocator, image, allocationHandle);
}
}
void VulkanTexture::GenerateMipMaps(vk::CommandBuffer buffer, vk::ImageLayout endLayout, vk::PipelineStageFlags2 endFlags) {
for (int layer = 0; layer < layerCount; ++layer) {
ImageTransitionBarrier(buffer, image,
vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferSrcOptimal,
aspectType,
vk::PipelineStageFlagBits2::eAllCommands, vk::PipelineStageFlagBits2::eTransfer,
0, 1, layer, 1);
for (uint32_t mip = 1; mip < mipCount; ++mip) {
vk::ImageBlit blitData;
blitData.srcSubresource.setAspectMask(vk::ImageAspectFlagBits::eColor)
.setMipLevel(mip - 1)
.setBaseArrayLayer(layer)
.setLayerCount(1);
blitData.srcOffsets[0] = vk::Offset3D(0, 0, 0);
blitData.srcOffsets[1].x = std::max(dimensions.x >> (mip - 1), (uint32_t)1);
blitData.srcOffsets[1].y = std::max(dimensions.y >> (mip - 1), (uint32_t)1);
blitData.srcOffsets[1].z = 1;
blitData.dstSubresource.setAspectMask(vk::ImageAspectFlagBits::eColor)
.setMipLevel(mip)
.setLayerCount(1)
.setBaseArrayLayer(layer);
blitData.dstOffsets[0] = vk::Offset3D(0, 0, 0);
blitData.dstOffsets[1].x = std::max(dimensions.x >> mip, (uint32_t)1);
blitData.dstOffsets[1].y = std::max(dimensions.y >> mip, (uint32_t)1);
blitData.dstOffsets[1].z = 1;
ImageTransitionBarrier(buffer, image, vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, aspectType, vk::PipelineStageFlagBits2::eHost, vk::PipelineStageFlagBits2::eTransfer, mip, 1, layer, 1);
buffer.blitImage(image, vk::ImageLayout::eTransferSrcOptimal, image, vk::ImageLayout::eTransferDstOptimal, blitData, vk::Filter::eLinear);
ImageTransitionBarrier(buffer, image, vk::ImageLayout::eTransferSrcOptimal, endLayout, aspectType, vk::PipelineStageFlagBits2::eTransfer, endFlags, mip - 1, 1, layer, 1);
if (mip < this->mipCount - 1) {
ImageTransitionBarrier(buffer, image, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eTransferSrcOptimal, aspectType, vk::PipelineStageFlagBits2::eTransfer, vk::PipelineStageFlagBits2::eTransfer, mip, 1, layer, 1);
}
else {
ImageTransitionBarrier(buffer, image, vk::ImageLayout::eTransferDstOptimal, endLayout, aspectType, vk::PipelineStageFlagBits2::eTransfer, endFlags, mip, 1, layer, 1);
}
}
}
}