-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathVulkanTexture.cpp
85 lines (72 loc) · 3.01 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
73
74
75
76
77
78
79
80
81
82
83
84
85
/******************************************************************************
This file is part of the Newcastle Vulkan Tutorial Series
Author:Rich Davison
Contact:richgdavison@gmail.com
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() {
}
VulkanTexture::~VulkanTexture() {
if (image) {
vmaDestroyImage(allocator, image, allocationHandle);
}
}
void VulkanTexture::GenerateMipMaps(vk::CommandBuffer buffer, vk::ImageLayout startLayout, vk::ImageLayout endLayout, vk::PipelineStageFlags2 endFlags) {
for (int layer = 0; layer < layerCount; ++layer) {
ImageTransitionBarrier(buffer, image,
startLayout, vk::ImageLayout::eTransferSrcOptimal,
aspectType,
vk::PipelineStageFlagBits2::eAllCommands, vk::PipelineStageFlagBits2::eTransfer,
0, 1, layer, 1);
vk::ImageBlit blitData;
blitData.srcSubresource.setAspectMask(vk::ImageAspectFlagBits::eColor)
.setMipLevel(0)
.setBaseArrayLayer(layer)
.setLayerCount(1);
blitData.srcOffsets[0] = vk::Offset3D(0, 0, 0);
blitData.srcOffsets[1] = vk::Offset3D(dimensions.x, dimensions.y, 1);
blitData.dstOffsets[0] = vk::Offset3D(0, 0, 0);
blitData.dstOffsets[1] = vk::Offset3D(dimensions.x, dimensions.y, 1);
for (uint32_t mip = 1; mip < mipCount; ++mip) {
blitData.dstSubresource.setAspectMask(vk::ImageAspectFlagBits::eColor)
.setMipLevel(mip)
.setBaseArrayLayer(layer)
.setLayerCount(1);
blitData.dstOffsets[1].x = std::max(dimensions.x >> mip, 1u);
blitData.dstOffsets[1].y = std::max(dimensions.y >> mip, 1u);
//Prepare the new mip level to receive the blitted data
ImageTransitionBarrier(buffer, image,
vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal,
aspectType,
vk::PipelineStageFlagBits2::eTransfer, vk::PipelineStageFlagBits2::eTransfer,
mip, 1, layer, 1);
buffer.blitImage(image, vk::ImageLayout::eTransferSrcOptimal,
image, vk::ImageLayout::eTransferDstOptimal,
blitData, vk::Filter::eLinear);
//The new mip is then transitioned again to be able to act as a source
//for the next level
ImageTransitionBarrier(buffer, image,
vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eTransferSrcOptimal,
aspectType,
vk::PipelineStageFlagBits2::eTransfer, vk::PipelineStageFlagBits2::eTransfer,
mip, 1, layer, 1);
blitData.srcOffsets = blitData.dstOffsets;
blitData.srcSubresource = blitData.dstSubresource;
}
//Now that this layer's mipchain is complete, transition the whole lot to final layout
ImageTransitionBarrier(buffer, image,
vk::ImageLayout::eTransferSrcOptimal, endLayout,
aspectType,
vk::PipelineStageFlagBits2::eTransfer, endFlags,
0, mipCount, layer, 1);
}
}