Skip to content

Commit c06fbdc

Browse files
Add BC1 tests for texture updates from buffer
1 parent 9e1bff0 commit c06fbdc

File tree

1 file changed

+78
-35
lines changed

1 file changed

+78
-35
lines changed

Tests/DiligentCoreAPITest/src/UpdateTextureFromBufferTest.cpp

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,6 @@ struct AxisSplit
5959
Uint32 Size = 0;
6060
};
6161

62-
Uint32 GetMipDimension(Uint32 BaseDim, Uint32 Mip)
63-
{
64-
return std::max(BaseDim >> Mip, 1u);
65-
}
66-
6762
AxisSplit GetAxisSplit(Uint32 Dim, Uint32 Split)
6863
{
6964
if (Dim <= 1)
@@ -77,6 +72,7 @@ AxisSplit GetAxisSplit(Uint32 Dim, Uint32 Split)
7772

7873
TextureDesc CreateTestTextureDesc(const char* Name,
7974
RESOURCE_DIMENSION Type,
75+
TEXTURE_FORMAT Format,
8076
Uint32 Width,
8177
Uint32 Height,
8278
Uint32 ArraySizeOrDepth,
@@ -85,7 +81,7 @@ TextureDesc CreateTestTextureDesc(const char* Name,
8581
TextureDesc TexDesc;
8682
TexDesc.Name = Name;
8783
TexDesc.Type = Type;
88-
TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
84+
TexDesc.Format = Format;
8985
TexDesc.BindFlags = BIND_SHADER_RESOURCE;
9086
TexDesc.Width = Width;
9187
TexDesc.Height = Height;
@@ -107,12 +103,9 @@ void ForEachSubresource(const TextureDesc& TexDesc, Fn&& Callback)
107103

108104
for (Uint32 mip = 0; mip < TexDesc.MipLevels; ++mip)
109105
{
110-
const Uint32 MipWidth = GetMipDimension(TexDesc.Width, mip);
111-
const Uint32 MipHeight = GetMipDimension(TexDesc.Height, mip);
112-
const Uint32 MipDepth = TexDesc.Is3D() ? GetMipDimension(TexDesc.Depth, mip) : 1u;
113-
106+
MipLevelProperties Mip = GetMipLevelProperties(TexDesc, mip);
114107
for (Uint32 slice = 0; slice < NumSlices; ++slice)
115-
Callback(mip, slice, MipWidth, MipHeight, MipDepth);
108+
Callback(mip, slice, Mip);
116109
}
117110
}
118111

@@ -130,7 +123,7 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
130123

131124
const Uint32 TextureUpdateOffsetAlignment = pDevice->GetAdapterInfo().Buffer.TextureUpdateOffsetAlignment;
132125
const Uint32 TextureUpdateStrideAlignment = pDevice->GetAdapterInfo().Buffer.TextureUpdateStrideAlignment;
133-
const Uint32 NumSlices = BaseTexDesc.IsArray() ? BaseTexDesc.ArraySize : 1u;
126+
const Uint32 NumSlices = BaseTexDesc.GetArraySize();
134127

135128
for (USAGE BufferUsage : {USAGE_DEFAULT, USAGE_STAGING})
136129
{
@@ -148,22 +141,34 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
148141
pDevice->CreateTexture(StagingTexDesc, nullptr, &pStagingTexture);
149142
ASSERT_NE(pStagingTexture, nullptr);
150143

151-
std::vector<std::vector<Uint32>> RefSubresources(BaseTexDesc.MipLevels * NumSlices);
152-
std::vector<Uint8> UploadData;
153-
std::vector<UploadRegion> UploadRegions;
144+
std::vector<std::vector<Uint8>> RefSubresources(BaseTexDesc.MipLevels * NumSlices);
145+
std::vector<Uint8> UploadData;
146+
std::vector<UploadRegion> UploadRegions;
154147

155148
auto GetSubresourceIndex = [NumSlices](Uint32 Mip, Uint32 Slice) {
156149
return Mip * NumSlices + Slice;
157150
};
158151

159-
FastRandInt rnd{0, 0, 32766};
152+
FastRandInt rnd{0, 0, 255};
160153

161-
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, Uint32 MipWidth, Uint32 MipHeight, Uint32 MipDepth) {
154+
const TextureFormatAttribs& FmtAttribs = pDevice->GetTextureFormatInfo(BaseTexDesc.Format);
155+
156+
const Uint32 ElementSize = FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED ?
157+
FmtAttribs.ComponentSize :
158+
FmtAttribs.ComponentSize * FmtAttribs.NumComponents;
159+
160+
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, const MipLevelProperties& Mip) {
162161
auto& Subres = RefSubresources[GetSubresourceIndex(mip, slice)];
163-
Subres.resize(static_cast<size_t>(MipWidth) * MipHeight * MipDepth);
162+
Subres.resize(static_cast<size_t>(Mip.MipSize));
163+
164+
const Uint32 MipWidth = Mip.LogicalWidth;
165+
const Uint32 MipHeight = Mip.LogicalHeight;
166+
const Uint32 MipDepth = Mip.Depth;
167+
VERIFY((MipWidth % FmtAttribs.BlockWidth) == 0, "Logical mip width (", MipWidth, ") is expected to be a multiple of block width (", FmtAttribs.BlockWidth, ")");
168+
VERIFY((MipHeight % FmtAttribs.BlockHeight) == 0, "Logical mip height (", MipHeight, ") is expected to be a multiple of block height (", FmtAttribs.BlockHeight, ")");
164169

165-
for (Uint32& pixel : Subres)
166-
pixel = rnd() | (rnd() << 16);
170+
for (Uint8& pixel : Subres)
171+
pixel = static_cast<Uint8>(rnd());
167172

168173
const Uint32 NumXSplits = MipWidth > 1 ? 2u : 1u;
169174
const Uint32 NumYSplits = MipHeight > 1 ? 2u : 1u;
@@ -185,27 +190,30 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
185190
static_cast<Uint64>(TextureUpdateOffsetAlignment));
186191
UploadData.resize(static_cast<size_t>(AlignedOffset));
187192

188-
const Uint32 Stride = AlignUp(MipWidth * Uint32{sizeof(Uint32)}, TextureUpdateStrideAlignment);
189-
const Uint32 DepthStride = Y.Size * Stride;
193+
const Uint32 Stride = AlignUp(X.Size / FmtAttribs.BlockWidth * ElementSize, TextureUpdateStrideAlignment);
194+
const Uint32 DepthStride = Y.Size / FmtAttribs.BlockHeight * Stride;
190195
const Uint64 SrcOffset = static_cast<Uint64>(UploadData.size());
191196
const Uint64 RegionSize = static_cast<Uint64>(Z.Size) * DepthStride;
192197

193198
UploadData.resize(static_cast<size_t>(SrcOffset + RegionSize));
194199

195200
for (Uint32 z = 0; z < Z.Size; ++z)
196201
{
197-
for (Uint32 row = 0; row < Y.Size; ++row)
202+
for (Uint32 row = 0; row < Y.Size / FmtAttribs.BlockHeight; ++row)
198203
{
199-
const Uint32* pSrcRow =
200-
&Subres[((Z.Offset + z) * MipHeight + (Y.Offset + row)) * MipWidth + X.Offset];
204+
const Uint8* pSrcRow =
205+
&Subres[static_cast<size_t>(
206+
(Z.Offset + z) * Mip.DepthSliceSize +
207+
(Y.Offset / FmtAttribs.BlockHeight + row) * Mip.RowSize +
208+
X.Offset / FmtAttribs.BlockWidth * ElementSize)];
201209

202210
Uint8* pDstRow =
203211
UploadData.data() +
204212
static_cast<size_t>(SrcOffset) +
205213
static_cast<size_t>(z) * DepthStride +
206214
static_cast<size_t>(row) * Stride;
207215

208-
memcpy(pDstRow, pSrcRow, X.Size * sizeof(Uint32));
216+
memcpy(pDstRow, pSrcRow, X.Size / FmtAttribs.BlockWidth * ElementSize);
209217
}
210218
}
211219

@@ -272,9 +280,15 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
272280
RESOURCE_STATE_TRANSITION_MODE_VERIFY);
273281
}
274282

283+
if (pDevice->GetDeviceInfo().IsGLDevice() && FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED)
284+
{
285+
// Readback of compressed textures is not supported in OpenGL backend, so we cannot verify texture data on CPU.
286+
continue;
287+
}
288+
275289
pContext->TransitionResourceState({pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_SOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE});
276290
pContext->TransitionResourceState({pStagingTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_DEST, STATE_TRANSITION_FLAG_UPDATE_STATE});
277-
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, Uint32, Uint32, Uint32) {
291+
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, const MipLevelProperties&) {
278292
CopyTextureAttribs CopyAttribs;
279293
CopyAttribs.pSrcTexture = pTexture;
280294
CopyAttribs.SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_VERIFY;
@@ -289,23 +303,23 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
289303

290304
pContext->WaitForIdle();
291305

292-
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, Uint32 MipWidth, Uint32 MipHeight, Uint32 MipDepth) {
306+
ForEachSubresource(BaseTexDesc, [&](Uint32 mip, Uint32 slice, const MipLevelProperties& Mip) {
293307
const auto& Subres = RefSubresources[GetSubresourceIndex(mip, slice)];
294308

295309
MappedTextureSubresource MappedData;
296310
pContext->MapTextureSubresource(pStagingTexture, mip, slice, MAP_READ, MAP_FLAG_DO_NOT_WAIT, nullptr, MappedData);
297311

298-
for (Uint32 z = 0; z < MipDepth; ++z)
312+
for (Uint32 z = 0; z < Mip.Depth; ++z)
299313
{
300-
for (Uint32 row = 0; row < MipHeight; ++row)
314+
for (Uint32 row = 0; row < Mip.LogicalHeight / FmtAttribs.BlockHeight; ++row)
301315
{
302-
const void* pRefRow = &Subres[(z * MipHeight + row) * MipWidth];
316+
const void* pRefRow = &Subres[static_cast<size_t>(z * Mip.DepthSliceSize + row * Mip.RowSize)];
303317
const void* pTexRow =
304318
reinterpret_cast<const Uint8*>(MappedData.pData) +
305319
static_cast<size_t>(z) * static_cast<size_t>(MappedData.DepthStride) +
306320
static_cast<size_t>(row) * static_cast<size_t>(MappedData.Stride);
307321

308-
EXPECT_EQ(memcmp(pRefRow, pTexRow, MipWidth * sizeof(Uint32)), 0)
322+
EXPECT_EQ(memcmp(pRefRow, pTexRow, static_cast<size_t>(Mip.RowSize)), 0)
309323
<< "Mip level: " << mip
310324
<< ", slice: " << slice
311325
<< ", z: " << z
@@ -318,33 +332,62 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
318332
}
319333
}
320334

321-
TEST(UpdateTextureFromBuffer, Texture2D)
335+
TEST(UpdateTextureFromBuffer, Texture2D_RGBA8)
322336
{
323337
RunCopyBufferToTextureTest(
324338
CreateTestTextureDesc("UpdateTextureFromBuffer.Texture2D",
325339
RESOURCE_DIM_TEX_2D,
340+
TEX_FORMAT_RGBA8_UNORM,
326341
128,
327342
128,
328343
1,
329344
4));
330345
}
331346

332-
TEST(UpdateTextureFromBuffer, Texture2DArray)
347+
348+
TEST(UpdateTextureFromBuffer, Texture2D_BC1)
349+
{
350+
RunCopyBufferToTextureTest(
351+
CreateTestTextureDesc("UpdateTextureFromBuffer.Texture2D",
352+
RESOURCE_DIM_TEX_2D,
353+
TEX_FORMAT_BC1_UNORM,
354+
512,
355+
512,
356+
1,
357+
4));
358+
}
359+
360+
TEST(UpdateTextureFromBuffer, Texture2DArray_RGBA8)
333361
{
334362
RunCopyBufferToTextureTest(
335363
CreateTestTextureDesc("UpdateTextureFromBuffer.Texture2DArray",
336364
RESOURCE_DIM_TEX_2D_ARRAY,
365+
TEX_FORMAT_RGBA8_UNORM,
337366
128,
338367
128,
339368
4,
340369
4));
341370
}
342371

343-
TEST(UpdateTextureFromBuffer, Texture3D)
372+
373+
TEST(UpdateTextureFromBuffer, Texture2DArray_BC1)
374+
{
375+
RunCopyBufferToTextureTest(
376+
CreateTestTextureDesc("UpdateTextureFromBuffer.Texture2DArray",
377+
RESOURCE_DIM_TEX_2D_ARRAY,
378+
TEX_FORMAT_BC1_UNORM,
379+
512,
380+
512,
381+
4,
382+
4));
383+
}
384+
385+
TEST(UpdateTextureFromBuffer, Texture3D_RGBA8)
344386
{
345387
RunCopyBufferToTextureTest(
346388
CreateTestTextureDesc("UpdateTextureFromBuffer.Texture3D",
347389
RESOURCE_DIM_TEX_3D,
390+
TEX_FORMAT_RGBA8_UNORM,
348391
128,
349392
128,
350393
8,

0 commit comments

Comments
 (0)