@@ -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-
6762AxisSplit GetAxisSplit (Uint32 Dim, Uint32 Split)
6863{
6964 if (Dim <= 1 )
@@ -77,6 +72,7 @@ AxisSplit GetAxisSplit(Uint32 Dim, Uint32 Split)
7772
7873TextureDesc 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,29 @@ 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[(Z.Offset + z) * Mip.DepthSliceSize +
206+ (Y.Offset / FmtAttribs.BlockHeight + row) * Mip.RowSize +
207+ X.Offset / FmtAttribs.BlockWidth * ElementSize];
201208
202209 Uint8* pDstRow =
203210 UploadData.data () +
204211 static_cast <size_t >(SrcOffset) +
205212 static_cast <size_t >(z) * DepthStride +
206213 static_cast <size_t >(row) * Stride;
207214
208- memcpy (pDstRow, pSrcRow, X.Size * sizeof (Uint32) );
215+ memcpy (pDstRow, pSrcRow, X.Size / FmtAttribs. BlockWidth * ElementSize );
209216 }
210217 }
211218
@@ -272,9 +279,15 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
272279 RESOURCE_STATE_TRANSITION_MODE_VERIFY);
273280 }
274281
282+ if (pDevice->GetDeviceInfo ().IsGLDevice () && FmtAttribs.ComponentType == COMPONENT_TYPE_COMPRESSED)
283+ {
284+ // Readback of compressed textures is not supported in OpenGL backend, so we cannot verify texture data on CPU.
285+ continue ;
286+ }
287+
275288 pContext->TransitionResourceState ({pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_SOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE});
276289 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 ) {
290+ ForEachSubresource (BaseTexDesc, [&](Uint32 mip, Uint32 slice, const MipLevelProperties& ) {
278291 CopyTextureAttribs CopyAttribs;
279292 CopyAttribs.pSrcTexture = pTexture;
280293 CopyAttribs.SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_VERIFY;
@@ -289,23 +302,23 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
289302
290303 pContext->WaitForIdle ();
291304
292- ForEachSubresource (BaseTexDesc, [&](Uint32 mip, Uint32 slice, Uint32 MipWidth, Uint32 MipHeight, Uint32 MipDepth ) {
305+ ForEachSubresource (BaseTexDesc, [&](Uint32 mip, Uint32 slice, const MipLevelProperties& Mip ) {
293306 const auto & Subres = RefSubresources[GetSubresourceIndex (mip, slice)];
294307
295308 MappedTextureSubresource MappedData;
296309 pContext->MapTextureSubresource (pStagingTexture, mip, slice, MAP_READ, MAP_FLAG_DO_NOT_WAIT, nullptr , MappedData);
297310
298- for (Uint32 z = 0 ; z < MipDepth ; ++z)
311+ for (Uint32 z = 0 ; z < Mip. Depth ; ++z)
299312 {
300- for (Uint32 row = 0 ; row < MipHeight ; ++row)
313+ for (Uint32 row = 0 ; row < Mip. LogicalHeight / FmtAttribs. BlockHeight ; ++row)
301314 {
302- const void * pRefRow = &Subres[( z * MipHeight + row) * MipWidth ];
315+ const void * pRefRow = &Subres[z * Mip. DepthSliceSize + row * Mip. RowSize ];
303316 const void * pTexRow =
304317 reinterpret_cast <const Uint8*>(MappedData.pData ) +
305318 static_cast <size_t >(z) * static_cast <size_t >(MappedData.DepthStride ) +
306319 static_cast <size_t >(row) * static_cast <size_t >(MappedData.Stride );
307320
308- EXPECT_EQ (memcmp (pRefRow, pTexRow, MipWidth * sizeof (Uint32) ), 0 )
321+ EXPECT_EQ (memcmp (pRefRow, pTexRow, Mip. RowSize ), 0 )
309322 << " Mip level: " << mip
310323 << " , slice: " << slice
311324 << " , z: " << z
@@ -318,33 +331,62 @@ void RunCopyBufferToTextureTest(const TextureDesc& BaseTexDesc)
318331 }
319332}
320333
321- TEST (UpdateTextureFromBuffer, Texture2D )
334+ TEST (UpdateTextureFromBuffer, Texture2D_RGBA8 )
322335{
323336 RunCopyBufferToTextureTest (
324337 CreateTestTextureDesc (" UpdateTextureFromBuffer.Texture2D" ,
325338 RESOURCE_DIM_TEX_2D,
339+ TEX_FORMAT_RGBA8_UNORM,
326340 128 ,
327341 128 ,
328342 1 ,
329343 4 ));
330344}
331345
332- TEST (UpdateTextureFromBuffer, Texture2DArray)
346+
347+ TEST (UpdateTextureFromBuffer, Texture2D_BC1)
348+ {
349+ RunCopyBufferToTextureTest (
350+ CreateTestTextureDesc (" UpdateTextureFromBuffer.Texture2D" ,
351+ RESOURCE_DIM_TEX_2D,
352+ TEX_FORMAT_BC1_UNORM,
353+ 512 ,
354+ 512 ,
355+ 1 ,
356+ 4 ));
357+ }
358+
359+ TEST (UpdateTextureFromBuffer, Texture2DArray_RGBA8)
333360{
334361 RunCopyBufferToTextureTest (
335362 CreateTestTextureDesc (" UpdateTextureFromBuffer.Texture2DArray" ,
336363 RESOURCE_DIM_TEX_2D_ARRAY,
364+ TEX_FORMAT_RGBA8_UNORM,
337365 128 ,
338366 128 ,
339367 4 ,
340368 4 ));
341369}
342370
343- TEST (UpdateTextureFromBuffer, Texture3D)
371+
372+ TEST (UpdateTextureFromBuffer, Texture2DArray_BC1)
373+ {
374+ RunCopyBufferToTextureTest (
375+ CreateTestTextureDesc (" UpdateTextureFromBuffer.Texture2DArray" ,
376+ RESOURCE_DIM_TEX_2D_ARRAY,
377+ TEX_FORMAT_BC1_UNORM,
378+ 512 ,
379+ 512 ,
380+ 4 ,
381+ 4 ));
382+ }
383+
384+ TEST (UpdateTextureFromBuffer, Texture3D_RGBA8)
344385{
345386 RunCopyBufferToTextureTest (
346387 CreateTestTextureDesc (" UpdateTextureFromBuffer.Texture3D" ,
347388 RESOURCE_DIM_TEX_3D,
389+ TEX_FORMAT_RGBA8_UNORM,
348390 128 ,
349391 128 ,
350392 8 ,
0 commit comments