1
1
2
2
#include < ri/Texture.h>
3
3
4
+ #include < ri/Buffer.h>
4
5
#include < ri/CommandBuffer.h>
5
6
#include < ri/DeviceContext.h>
6
7
@@ -36,6 +37,25 @@ namespace detail
36
37
37
38
return flags;
38
39
}
40
+
41
+ VkImageType getImageType (int type)
42
+ {
43
+ switch (type)
44
+ {
45
+ case ri::TextureType::e1D:
46
+ case ri::TextureType::eArray1D:
47
+ return VK_IMAGE_TYPE_1D;
48
+ case ri::TextureType::e2D:
49
+ case ri::TextureType::eArray2D:
50
+ case ri::TextureType::eCube:
51
+ return VK_IMAGE_TYPE_2D;
52
+ case ri::TextureType::e3D:
53
+ return VK_IMAGE_TYPE_3D;
54
+ default :
55
+ assert (false );
56
+ return VK_IMAGE_TYPE_2D;
57
+ }
58
+ }
39
59
}
40
60
41
61
namespace
@@ -60,9 +80,10 @@ Texture::Texture(const DeviceContext& device, const TextureParams& params)
60
80
, m_size(params.size)
61
81
, m_mipLevels(params.mipLevels ? params.mipLevels
62
82
: (uint32_t )floor(log2(std::max(params.size.width, params.size.height))) + 1 )
83
+ , m_arrayLevels(m_type == TextureType::eCube ? 6 : params.arrayLevels)
63
84
{
64
85
#ifndef NDEBUG
65
- TextureProperties props =
86
+ const TextureProperties props =
66
87
device.textureProperties (params.format , params.type , TextureTiling::eOptimal, params.flags );
67
88
assert (props.sampleCounts >= params.samples );
68
89
assert (props.maxExtent .width >= params.size .width );
@@ -90,6 +111,7 @@ Texture::Texture(VkImage handle, TextureType type, ColorFormat format, const Siz
90
111
, m_type(type)
91
112
, m_format(format)
92
113
, m_size(size)
114
+ , m_arrayLevels(0 )
93
115
{
94
116
}
95
117
@@ -113,22 +135,27 @@ void Texture::copy(const Buffer& src, const CopyParams& params, CommandBuffer& c
113
135
transitionImageLayout (params.oldLayout , params.transferLayout , commandBuffer);
114
136
115
137
// copy buffer to image
116
- VkBufferImageCopy region = {};
117
- // TODO: expose these
118
- region.bufferOffset = 0 ;
138
+
139
+ assert ((m_arrayLevels * m_size.pixelCount () * sizeof (uint32_t )) < src.bytes ());
140
+
141
+ std::vector<VkBufferImageCopy> bufferCopyRegions;
142
+ VkBufferImageCopy region = {};
143
+ region.bufferOffset = params.bufferOffset ;
119
144
region.bufferRowLength = 0 ;
120
145
region.bufferImageHeight = 0 ;
121
146
region.imageSubresource .aspectMask = detail::getImageAspectFlags ((VkFormat)m_format);
122
- region.imageSubresource .mipLevel = 0 ;
123
- region.imageSubresource .baseArrayLayer = 0 ;
124
- region.imageSubresource .layerCount = 1 ;
147
+ region.imageSubresource .mipLevel = params.mipLevel ;
148
+ region.imageSubresource .baseArrayLayer = params.baseArrayLayer ;
149
+ region.imageSubresource .layerCount = m_arrayLevels;
150
+ const Sizei size = params.size .width == 0 || params.size .height == 0 ? m_size : params.size ;
151
+ region.imageOffset = {params.offsetX , params.offsetY , params.offsetZ };
152
+ region.imageExtent = {size.width , size.height , params.depth };
125
153
126
- const Sizei size = params.size .width == 0 || params.size .height == 0 ? m_size : params.size ;
127
- region.imageOffset = {params.offsetX , params.offsetY , params.offsetZ };
128
- region.imageExtent = {size.width , size.height , params.depth };
154
+ bufferCopyRegions.push_back (region);
129
155
130
156
vkCmdCopyBufferToImage (detail::getVkHandle (commandBuffer), detail::getVkHandle (src), m_handle,
131
- (VkImageLayout)TextureLayoutType::eTransferDstOptimal, 1 , ®ion);
157
+ (VkImageLayout)TextureLayoutType::eTransferDstOptimal, bufferCopyRegions.size (),
158
+ bufferCopyRegions.data ());
132
159
133
160
if (params.transferLayout != params.finalLayout )
134
161
transitionImageLayout (params.transferLayout , params.finalLayout , false , commandBuffer);
@@ -139,6 +166,8 @@ void Texture::generateMipMaps(CommandBuffer& commandBuffer)
139
166
assert (m_format != ColorFormat::eDepth32 && m_format != ColorFormat::eDepth24Stencil8 &&
140
167
m_format != ColorFormat::eDepth32Stencil8);
141
168
169
+ // TODO: handle 2D arrays
170
+
142
171
// Copy down mips from n-1 to n
143
172
for (uint32_t i = 1 ; i < m_mipLevels; i++)
144
173
{
@@ -200,12 +229,12 @@ inline void Texture::createImage(const TextureParams& params)
200
229
{
201
230
VkImageCreateInfo imageInfo = {};
202
231
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
203
- imageInfo.imageType = (VkImageType) params.type ;
232
+ imageInfo.imageType = detail::getImageType ( params.type . get ()) ;
204
233
imageInfo.extent .width = static_cast <uint32_t >(params.size .width );
205
234
imageInfo.extent .height = static_cast <uint32_t >(params.size .height );
206
235
imageInfo.extent .depth = params.depth ;
207
236
imageInfo.mipLevels = m_mipLevels;
208
- imageInfo.arrayLayers = params.arrayLevels ;
237
+ imageInfo.arrayLayers = m_type == TextureType::eCube ? 6 : params.arrayLevels ;
209
238
imageInfo.format = (VkFormat)params.format ;
210
239
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
211
240
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -215,6 +244,8 @@ inline void Texture::createImage(const TextureParams& params)
215
244
assert (math::isPowerOfTwo (params.samples ));
216
245
imageInfo.samples = (VkSampleCountFlagBits)params.samples ;
217
246
imageInfo.flags = 0 ;
247
+ if (m_type == TextureType::eCube)
248
+ imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
218
249
219
250
RI_CHECK_RESULT_MSG (" failed to create image" ) = vkCreateImage (m_device, &imageInfo, nullptr , &m_handle);
220
251
}
@@ -233,7 +264,7 @@ void Texture::createImageView(const TextureParams& params, VkImageAspectFlags as
233
264
viewInfo.subresourceRange .baseMipLevel = 0 ;
234
265
viewInfo.subresourceRange .levelCount = m_mipLevels;
235
266
viewInfo.subresourceRange .baseArrayLayer = 0 ;
236
- viewInfo.subresourceRange .layerCount = 1 ;
267
+ viewInfo.subresourceRange .layerCount = m_type == TextureType::eCube ? 6 : 1 ;
237
268
238
269
RI_CHECK_RESULT_MSG (" failed to create image view" ) = vkCreateImageView (m_device, &viewInfo, nullptr , &m_view);
239
270
}
@@ -406,9 +437,9 @@ void Texture::transitionImageLayout(TextureLayoutType oldLayout, TextureLayoutTy
406
437
VkImageSubresourceRange subresourceRange = {};
407
438
subresourceRange.aspectMask = detail::getImageAspectFlags ((VkFormat)m_format);
408
439
subresourceRange.baseMipLevel = 0 ;
409
- subresourceRange.levelCount = 1 ;
440
+ subresourceRange.levelCount = m_mipLevels ;
410
441
subresourceRange.baseArrayLayer = 0 ;
411
- subresourceRange.layerCount = 1 ;
442
+ subresourceRange.layerCount = m_arrayLevels ;
412
443
413
444
const PipelineBarrierSettings settings =
414
445
getPipelineBarrierSettings (oldLayout, newLayout, readAccess, subresourceRange);
0 commit comments