yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
43d0c2100
master
1#if 0 2// Duplicated: This test is identical to slang-rhi\tests\test-cmd-copy-texture.cpp 3 4#include "core/slang-basic.h" 5#include "gfx-test-texture-util.h" 6#include "gfx-test-util.h" 7#include "slang-rhi.h" 8#include "slang-rhi/shader-cursor.h" 9#include "unit-test/slang-unit-test.h" 10 11#if SLANG_WINDOWS_FAMILY 12#include <d3d12.h> 13#endif 14 15using namespace Slang ; 16using namespace rhi ; 17 18namespace gfx_test 19{ 20struct TextureToTextureCopyInfo 21{ 22SubresourceRange srcSubresource ; 23SubresourceRange dstSubresource ; 24Extents extent ; 25Offset3D srcOffset ; 26Offset3D dstOffset ; 27}; 28 29struct TextureToBufferCopyInfo 30{ 31SubresourceRange srcSubresource ; 32Extents extent ; 33Offset3D textureOffset ; 34Offset bufferOffset ; 35Offset bufferSize ; 36}; 37 38struct BaseCopyTextureTest 39{ 40IDevice * device ; 41UnitTestContext * context ; 42 43 rhi::Size alignedRowStride ; 44 45RefPtr < TextureInfo > srcTextureInfo ; 46RefPtr < TextureInfo > dstTextureInfo ; 47TextureToTextureCopyInfo texCopyInfo ; 48TextureToBufferCopyInfo bufferCopyInfo ; 49 50ComPtr < ITexture > srcTexture ; 51ComPtr < ITexture > dstTexture ; 52ComPtr < IBuffer > resultsBuffer ; 53 54RefPtr < ValidationTextureFormatBase > validationFormat ; 55 56void init ( 57IDevice * device , 58UnitTestContext * context , 59Format format , 60RefPtr < ValidationTextureFormatBase > validationFormat , 61TextureType type ) 62 { 63this -> device = device ; 64this -> context = context ; 65this -> validationFormat = validationFormat ; 66 67this -> srcTextureInfo = new TextureInfo (); 68this -> srcTextureInfo -> format = format ; 69this -> srcTextureInfo -> textureType = type ; 70 71this -> dstTextureInfo = new TextureInfo (); 72this -> dstTextureInfo -> format = format ; 73this -> dstTextureInfo -> textureType = type ; 74 } 75 76void createRequiredResources () 77 { 78TextureDesc srcTexDesc = {}; 79srcTexDesc .type = srcTextureInfo -> textureType ; 80srcTexDesc .mipCount = srcTextureInfo -> mipLevelCount ; 81srcTexDesc .arraySize = srcTextureInfo -> arrayLayerCount ; 82srcTexDesc .extent = srcTextureInfo -> extents ; 83srcTexDesc .defaultState = ResourceState ::ShaderResource ; 84srcTexDesc .format = srcTextureInfo -> format ; 85 86GFX_CHECK_CALL_ABORT (device -> createTexture ( 87srcTexDesc , 88srcTextureInfo -> subresourceDatas .getBuffer (), 89srcTexture .writeRef ())); 90 91TextureDesc dstTexDesc = {}; 92dstTexDesc .type = dstTextureInfo -> textureType ; 93dstTexDesc .mipCount = dstTextureInfo -> mipLevelCount ; 94dstTexDesc .arraySize = dstTextureInfo -> arrayLayerCount ; 95dstTexDesc .extent = dstTextureInfo -> extents ; 96dstTexDesc .defaultState = ResourceState ::CopyDestination ; 97dstTexDesc .format = dstTextureInfo -> format ; 98 99GFX_CHECK_CALL_ABORT (device -> createTexture ( 100dstTexDesc , 101dstTextureInfo -> subresourceDatas .getBuffer (), 102dstTexture .writeRef ())); 103 104auto bufferCopyExtents = bufferCopyInfo .extent ; 105auto texelSize = getTexelSize (dstTextureInfo -> format ); 106size_t alignment ; 107device -> getTextureRowAlignment (& alignment ); 108alignedRowStride = (bufferCopyExtents .width * texelSize + alignment - 1 )& ~(alignment - 1 ); 109BufferDesc bufferDesc = {}; 110bufferDesc .size = 111bufferCopyExtents .height * bufferCopyExtents .depth * alignedRowStride ; 112bufferDesc .format = Format ::Unknown ; 113bufferDesc .elementSize = 0 ; 114bufferDesc .defaultState = ResourceState ::CopyDestination ; 115bufferDesc .memoryType = MemoryType ::DeviceLocal ; 116 117GFX_CHECK_CALL_ABORT ( 118device -> createBuffer (bufferDesc ,nullptr ,resultsBuffer .writeRef ())); 119 120bufferCopyInfo .bufferSize = bufferDesc .size ; 121 } 122 123void submitGPUWork () 124 { 125ICommandQueue ::Desc queueDesc = {ICommandQueue ::QueueType ::Graphics }; 126auto queue = device -> createCommandQueue (queueDesc ); 127 128auto commandBuffer = queue -> createCommandBuffer (); 129auto encoder = commandBuffer -> encodeResourceCommands (); 130 131encoder -> textureBarrier ( 132srcTexture , 133texCopyInfo .srcSubresource , 134ResourceState ::ShaderResource , 135ResourceState ::CopySource ); 136encoder -> copyTexture ( 137dstTexture , 138texCopyInfo .dstSubresource , 139texCopyInfo .dstOffset , 140srcTexture , 141texCopyInfo .srcSubresource , 142texCopyInfo .srcOffset , 143texCopyInfo .extent ); 144 145encoder -> textureBarrier ( 146dstTexture , 147bufferCopyInfo .srcSubresource , 148ResourceState ::CopyDestination , 149ResourceState ::CopySource ); 150encoder -> copyTextureToBuffer ( 151resultsBuffer , 152bufferCopyInfo .bufferOffset , 153bufferCopyInfo .bufferSize , 154alignedRowStride , 155dstTexture , 156bufferCopyInfo .srcSubresource , 157bufferCopyInfo .textureOffset , 158bufferCopyInfo .extent ); 159 160encoder -> endEncoding (); 161commandBuffer -> close (); 162queue -> executeCommandBuffer (commandBuffer ); 163queue -> waitOnHost (); 164 } 165 166bool isWithinCopyBounds (GfxIndex x ,GfxIndex y ,GfxIndex z ) 167 { 168auto copyExtents = texCopyInfo .extent ; 169auto copyOffset = texCopyInfo .dstOffset ; 170 171auto xLowerBound = copyOffset .x ; 172auto xUpperBound = copyOffset .x + copyExtents .width ; 173auto yLowerBound = copyOffset .y ; 174auto yUpperBound = copyOffset .y + copyExtents .height ; 175auto zLowerBound = copyOffset .z ; 176auto zUpperBound = copyOffset .z + copyExtents .depth ; 177 178if (x < xLowerBound || x >=xUpperBound || y < yLowerBound || y >=yUpperBound || 179z < zLowerBound || z >=zUpperBound ) 180return false; 181else 182return true; 183 } 184 185void validateTestResults ( 186ValidationTextureData actual , 187ValidationTextureData expectedCopied , 188ValidationTextureData expectedOriginal ) 189 { 190auto actualExtents = actual .extents ; 191auto copyExtent = texCopyInfo .extent ; 192auto srcTexOffset = texCopyInfo .srcOffset ; 193auto dstTexOffset = texCopyInfo .dstOffset ; 194 195for (GfxIndex x = 0 ;x < actualExtents .width ;++ x ) 196 { 197for (GfxIndex y = 0 ;y < actualExtents .height ;++ y ) 198 { 199for (GfxIndex z = 0 ;z < actualExtents .depth ;++ z ) 200 { 201auto actualBlock = actual .getBlockAt (x ,y ,z ); 202if (isWithinCopyBounds (x ,y ,z )) 203 { 204// Block is located within the bounds of the source texture 205auto xSource = x + srcTexOffset .x - dstTexOffset .x ; 206auto ySource = y + srcTexOffset .y - dstTexOffset .y ; 207auto zSource = z + srcTexOffset .z - dstTexOffset .z ; 208auto expectedBlock = expectedCopied .getBlockAt (xSource ,ySource ,zSource ); 209validationFormat -> validateBlocksEqual (actualBlock ,expectedBlock ); 210 } 211else 212 { 213// Block is located outside the bounds of the source texture and should be 214// compared against known expected values for the destination texture. 215auto expectedBlock = expectedOriginal .getBlockAt (x ,y ,z ); 216validationFormat -> validateBlocksEqual (actualBlock ,expectedBlock ); 217 } 218 } 219 } 220 } 221 } 222 223void checkTestResults ( 224Extents srcMipExtent , 225const void * expectedCopiedData , 226const void * expectedOriginalData ) 227 { 228ComPtr < ISlangBlob > resultBlob ; 229GFX_CHECK_CALL_ABORT (device -> readBuffer ( 230resultsBuffer , 2310 , 232bufferCopyInfo .bufferSize , 233resultBlob .writeRef ())); 234auto results = resultBlob -> getBufferPointer (); 235 236ValidationTextureData actual ; 237actual .extents = bufferCopyInfo .extent ; 238actual .textureData = results ; 239actual .strides .x = getTexelSize (dstTextureInfo -> format ); 240actual .strides .y = alignedRowStride ; 241actual .strides .z = actual .extents .height * actual .strides .y ; 242 243ValidationTextureData expectedCopied ; 244expectedCopied .extents = srcMipExtent ; 245expectedCopied .textureData = expectedCopiedData ; 246expectedCopied .strides .x = getTexelSize (srcTextureInfo -> format ); 247expectedCopied .strides .y = expectedCopied .extents .width * expectedCopied .strides .x ; 248expectedCopied .strides .z = expectedCopied .extents .height * expectedCopied .strides .y ; 249 250ValidationTextureData expectedOriginal ; 251if (expectedOriginalData ) 252 { 253expectedOriginal .extents = bufferCopyInfo .extent ; 254expectedOriginal .textureData = expectedOriginalData ; 255expectedOriginal .strides .x = getTexelSize (dstTextureInfo -> format ); 256expectedOriginal .strides .y = 257expectedOriginal .extents .width * expectedOriginal .strides .x ; 258expectedOriginal .strides .z = 259expectedOriginal .extents .height * expectedOriginal .strides .y ; 260 } 261 262validateTestResults (actual ,expectedCopied ,expectedOriginal ); 263 } 264}; 265 266struct SimpleCopyTexture :BaseCopyTextureTest 267{ 268void run () 269 { 270auto textureType = srcTextureInfo -> textureType ; 271auto format = srcTextureInfo -> format ; 272 273srcTextureInfo -> extents .width = 4 ; 274srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :4 ; 275srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 276srcTextureInfo -> mipLevelCount = 1 ; 277srcTextureInfo -> arrayLayerCount = 1 ; 278 279dstTextureInfo = srcTextureInfo ; 280 281generateTextureData (srcTextureInfo ,validationFormat ); 282 283SubresourceRange srcSubresource = {}; 284srcSubresource .aspectMask = getTextureAspect (format ); 285srcSubresource .mipLevel = 0 ; 286srcSubresource .mipLevelCount = 1 ; 287srcSubresource .baseArrayLayer = 0 ; 288srcSubresource .layerCount = 1 ; 289 290SubresourceRange dstSubresource = {}; 291dstSubresource .aspectMask = getTextureAspect (format ); 292dstSubresource .mipLevel = 0 ; 293dstSubresource .mipLevelCount = 1 ; 294dstSubresource .baseArrayLayer = 0 ; 295dstSubresource .layerCount = 1 ; 296 297texCopyInfo .srcSubresource = srcSubresource ; 298texCopyInfo .dstSubresource = dstSubresource ; 299texCopyInfo .extent = srcTextureInfo -> extents ; 300texCopyInfo .srcOffset = {0 ,0 ,0 }; 301texCopyInfo .dstOffset = {0 ,0 ,0 }; 302 303bufferCopyInfo .srcSubresource = dstSubresource ; 304bufferCopyInfo .extent = dstTextureInfo -> extents ; 305bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 306bufferCopyInfo .bufferOffset = 0 ; 307 308createRequiredResources (); 309submitGPUWork (); 310 311auto subresourceIndex = getSubresourceIndex ( 312srcSubresource .mipLevel , 313srcTextureInfo -> mipLevelCount , 314srcSubresource .baseArrayLayer ); 315auto expectedData = srcTextureInfo -> subresourceDatas [subresourceIndex ]; 316checkTestResults (srcTextureInfo -> extents ,expectedData .data ,nullptr ); 317 } 318}; 319 320struct CopyTextureSection :BaseCopyTextureTest 321{ 322void run () 323 { 324auto textureType = srcTextureInfo -> textureType ; 325auto format = srcTextureInfo -> format ; 326 327srcTextureInfo -> extents .width = 4 ; 328srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :4 ; 329srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 330srcTextureInfo -> mipLevelCount = 2 ; 331srcTextureInfo -> arrayLayerCount = 332 (textureType == TextureType ::Texture3D ) ?1 :2 ; 333 334dstTextureInfo = srcTextureInfo ; 335 336generateTextureData (srcTextureInfo ,validationFormat ); 337 338SubresourceRange srcSubresource = {}; 339srcSubresource .aspectMask = getTextureAspect (format ); 340srcSubresource .mipLevel = 0 ; 341srcSubresource .mipLevelCount = 1 ; 342srcSubresource .baseArrayLayer = (textureType == TextureType ::Texture3D ) ?0 :1 ; 343srcSubresource .layerCount = 1 ; 344 345SubresourceRange dstSubresource = {}; 346dstSubresource .aspectMask = getTextureAspect (format ); 347dstSubresource .mipLevel = 0 ; 348dstSubresource .mipLevelCount = 1 ; 349dstSubresource .baseArrayLayer = 0 ; 350dstSubresource .layerCount = 1 ; 351 352texCopyInfo .srcSubresource = srcSubresource ; 353texCopyInfo .dstSubresource = dstSubresource ; 354texCopyInfo .extent = srcTextureInfo -> extents ; 355texCopyInfo .srcOffset = {0 ,0 ,0 }; 356texCopyInfo .dstOffset = {0 ,0 ,0 }; 357 358bufferCopyInfo .srcSubresource = dstSubresource ; 359bufferCopyInfo .extent = dstTextureInfo -> extents ; 360bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 361bufferCopyInfo .bufferOffset = 0 ; 362 363createRequiredResources (); 364submitGPUWork (); 365 366auto subresourceIndex = getSubresourceIndex ( 367srcSubresource .mipLevel , 368srcTextureInfo -> mipLevelCount , 369srcSubresource .baseArrayLayer ); 370SubresourceData expectedData = 371srcTextureInfo -> subresourceDatas [subresourceIndex ]; 372checkTestResults (srcTextureInfo -> extents ,expectedData .data ,nullptr ); 373 } 374}; 375 376struct LargeSrcToSmallDst :BaseCopyTextureTest 377{ 378void run () 379 { 380auto textureType = srcTextureInfo -> textureType ; 381auto format = srcTextureInfo -> format ; 382 383srcTextureInfo -> extents .width = 8 ; 384srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :8 ; 385srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 386srcTextureInfo -> mipLevelCount = 1 ; 387srcTextureInfo -> arrayLayerCount = 1 ; 388 389generateTextureData (srcTextureInfo ,validationFormat ); 390 391dstTextureInfo -> extents .width = 4 ; 392dstTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :4 ; 393dstTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 394dstTextureInfo -> mipLevelCount = 1 ; 395dstTextureInfo -> arrayLayerCount = 1 ; 396 397SubresourceRange srcSubresource = {}; 398srcSubresource .aspectMask = getTextureAspect (format ); 399srcSubresource .mipLevel = 0 ; 400srcSubresource .mipLevelCount = 1 ; 401srcSubresource .baseArrayLayer = 0 ; 402srcSubresource .layerCount = 1 ; 403 404SubresourceRange dstSubresource = {}; 405dstSubresource .aspectMask = getTextureAspect (format ); 406dstSubresource .mipLevel = 0 ; 407dstSubresource .mipLevelCount = 1 ; 408dstSubresource .baseArrayLayer = 0 ; 409dstSubresource .layerCount = 1 ; 410 411texCopyInfo .srcSubresource = srcSubresource ; 412texCopyInfo .dstSubresource = dstSubresource ; 413texCopyInfo .extent = dstTextureInfo -> extents ; 414texCopyInfo .srcOffset = {0 ,0 ,0 }; 415texCopyInfo .dstOffset = {0 ,0 ,0 }; 416 417bufferCopyInfo .srcSubresource = dstSubresource ; 418bufferCopyInfo .extent = dstTextureInfo -> extents ; 419bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 420bufferCopyInfo .bufferOffset = 0 ; 421 422createRequiredResources (); 423submitGPUWork (); 424 425auto subresourceIndex = getSubresourceIndex ( 426srcSubresource .mipLevel , 427srcTextureInfo -> mipLevelCount , 428srcSubresource .baseArrayLayer ); 429SubresourceData expectedData = 430srcTextureInfo -> subresourceDatas [subresourceIndex ]; 431checkTestResults (srcTextureInfo -> extents ,expectedData .data ,nullptr ); 432 } 433}; 434 435struct SmallSrcToLargeDst :BaseCopyTextureTest 436{ 437void run () 438 { 439auto textureType = srcTextureInfo -> textureType ; 440auto format = srcTextureInfo -> format ; 441 442srcTextureInfo -> extents .width = 4 ; 443srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :4 ; 444srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 445srcTextureInfo -> mipLevelCount = 1 ; 446srcTextureInfo -> arrayLayerCount = 1 ; 447 448generateTextureData (srcTextureInfo ,validationFormat ); 449 450dstTextureInfo -> extents .width = 8 ; 451dstTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :8 ; 452dstTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 453dstTextureInfo -> mipLevelCount = 1 ; 454dstTextureInfo -> arrayLayerCount = 1 ; 455 456generateTextureData (dstTextureInfo ,validationFormat ); 457 458SubresourceRange srcSubresource = {}; 459srcSubresource .aspectMask = getTextureAspect (format ); 460srcSubresource .mipLevel = 0 ; 461srcSubresource .mipLevelCount = 1 ; 462srcSubresource .baseArrayLayer = 0 ; 463srcSubresource .layerCount = 1 ; 464 465SubresourceRange dstSubresource = {}; 466dstSubresource .aspectMask = getTextureAspect (format ); 467dstSubresource .mipLevel = 0 ; 468dstSubresource .mipLevelCount = 1 ; 469dstSubresource .baseArrayLayer = 0 ; 470dstSubresource .layerCount = 1 ; 471 472texCopyInfo .srcSubresource = srcSubresource ; 473texCopyInfo .dstSubresource = dstSubresource ; 474texCopyInfo .extent = srcTextureInfo -> extents ; 475texCopyInfo .srcOffset = {0 ,0 ,0 }; 476texCopyInfo .dstOffset = {0 ,0 ,0 }; 477 478bufferCopyInfo .srcSubresource = dstSubresource ; 479bufferCopyInfo .extent = dstTextureInfo -> extents ; 480bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 481bufferCopyInfo .bufferOffset = 0 ; 482 483createRequiredResources (); 484submitGPUWork (); 485 486auto copiedSubresourceIndex = getSubresourceIndex ( 487srcSubresource .mipLevel , 488srcTextureInfo -> mipLevelCount , 489srcSubresource .baseArrayLayer ); 490SubresourceData expectedCopiedData = 491srcTextureInfo -> subresourceDatas [copiedSubresourceIndex ]; 492auto originalSubresourceIndex = getSubresourceIndex ( 493dstSubresource .mipLevel , 494dstTextureInfo -> mipLevelCount , 495dstSubresource .baseArrayLayer ); 496SubresourceData expectedOriginalData = 497dstTextureInfo -> subresourceDatas [originalSubresourceIndex ]; 498checkTestResults ( 499srcTextureInfo -> extents , 500expectedCopiedData .data , 501expectedOriginalData .data ); 502 } 503}; 504 505struct CopyBetweenMips :BaseCopyTextureTest 506{ 507void run () 508 { 509auto textureType = srcTextureInfo -> textureType ; 510auto format = srcTextureInfo -> format ; 511 512srcTextureInfo -> extents .width = 16 ; 513srcTextureInfo -> extents .height = 514 (textureType == TextureType ::Texture1D ) ?1 :16 ; 515srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 516srcTextureInfo -> mipLevelCount = 4 ; 517srcTextureInfo -> arrayLayerCount = 1 ; 518 519generateTextureData (srcTextureInfo ,validationFormat ); 520 521dstTextureInfo -> extents .width = 16 ; 522dstTextureInfo -> extents .height = 523 (textureType == TextureType ::Texture1D ) ?1 :16 ; 524dstTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 525dstTextureInfo -> mipLevelCount = 4 ; 526dstTextureInfo -> arrayLayerCount = 1 ; 527 528generateTextureData (dstTextureInfo ,validationFormat ); 529 530SubresourceRange srcSubresource = {}; 531srcSubresource .aspectMask = getTextureAspect (format ); 532srcSubresource .mipLevel = 2 ; 533srcSubresource .mipLevelCount = 1 ; 534srcSubresource .baseArrayLayer = 0 ; 535srcSubresource .layerCount = 1 ; 536 537SubresourceRange dstSubresource = {}; 538dstSubresource .aspectMask = getTextureAspect (format ); 539dstSubresource .mipLevel = 1 ; 540dstSubresource .mipLevelCount = 1 ; 541dstSubresource .baseArrayLayer = 0 ; 542dstSubresource .layerCount = 1 ; 543 544auto copiedSubresourceIndex = getSubresourceIndex ( 545srcSubresource .mipLevel , 546srcTextureInfo -> mipLevelCount , 547srcSubresource .baseArrayLayer ); 548auto originalSubresourceIndex = getSubresourceIndex ( 549dstSubresource .mipLevel , 550dstTextureInfo -> mipLevelCount , 551dstSubresource .baseArrayLayer ); 552 553texCopyInfo .srcSubresource = srcSubresource ; 554texCopyInfo .dstSubresource = dstSubresource ; 555texCopyInfo .extent = srcTextureInfo -> subresourceObjects [copiedSubresourceIndex ]-> extents ; 556texCopyInfo .srcOffset = {0 ,0 ,0 }; 557texCopyInfo .dstOffset = {0 ,0 ,0 }; 558 559bufferCopyInfo .srcSubresource = dstSubresource ; 560bufferCopyInfo .extent = 561dstTextureInfo -> subresourceObjects [originalSubresourceIndex ]-> extents ; 562bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 563bufferCopyInfo .bufferOffset = 0 ; 564 565createRequiredResources (); 566submitGPUWork (); 567 568SubresourceData expectedCopiedData = 569srcTextureInfo -> subresourceDatas [copiedSubresourceIndex ]; 570SubresourceData expectedOriginalData = 571dstTextureInfo -> subresourceDatas [originalSubresourceIndex ]; 572auto srcMipExtent = srcTextureInfo -> subresourceObjects [2 ]-> extents ; 573checkTestResults (srcMipExtent ,expectedCopiedData .data ,expectedOriginalData .data ); 574 } 575}; 576 577struct CopyBetweenLayers :BaseCopyTextureTest 578{ 579void run () 580 { 581auto textureType = srcTextureInfo -> textureType ; 582auto format = srcTextureInfo -> format ; 583 584srcTextureInfo -> extents .width = 4 ; 585srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :4 ; 586srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 587srcTextureInfo -> mipLevelCount = 1 ; 588srcTextureInfo -> arrayLayerCount = 589 (textureType == TextureType ::Texture3D ) ?1 :2 ; 590 591generateTextureData (srcTextureInfo ,validationFormat ); 592dstTextureInfo = srcTextureInfo ; 593 594SubresourceRange srcSubresource = {}; 595srcSubresource .aspectMask = getTextureAspect (format ); 596srcSubresource .mipLevel = 0 ; 597srcSubresource .mipLevelCount = 1 ; 598srcSubresource .baseArrayLayer = 0 ; 599srcSubresource .layerCount = 1 ; 600 601SubresourceRange dstSubresource = {}; 602dstSubresource .aspectMask = getTextureAspect (format ); 603dstSubresource .mipLevel = 0 ; 604dstSubresource .mipLevelCount = 1 ; 605dstSubresource .baseArrayLayer = (textureType == TextureType ::Texture3D ) ?0 :1 ; 606dstSubresource .layerCount = 1 ; 607 608texCopyInfo .srcSubresource = srcSubresource ; 609texCopyInfo .dstSubresource = dstSubresource ; 610texCopyInfo .extent = srcTextureInfo -> extents ; 611texCopyInfo .srcOffset = {0 ,0 ,0 }; 612texCopyInfo .dstOffset = {0 ,0 ,0 }; 613 614bufferCopyInfo .srcSubresource = dstSubresource ; 615bufferCopyInfo .extent = dstTextureInfo -> extents ; 616bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 617bufferCopyInfo .bufferOffset = 0 ; 618 619createRequiredResources (); 620submitGPUWork (); 621 622auto copiedSubresourceIndex = getSubresourceIndex ( 623srcSubresource .mipLevel , 624srcTextureInfo -> mipLevelCount , 625srcSubresource .baseArrayLayer ); 626SubresourceData expectedCopiedData = 627srcTextureInfo -> subresourceDatas [copiedSubresourceIndex ]; 628auto originalSubresourceIndex = getSubresourceIndex ( 629dstSubresource .mipLevel , 630dstTextureInfo -> mipLevelCount , 631dstSubresource .baseArrayLayer ); 632SubresourceData expectedOriginalData = 633dstTextureInfo -> subresourceDatas [originalSubresourceIndex ]; 634checkTestResults ( 635srcTextureInfo -> extents , 636expectedCopiedData .data , 637expectedOriginalData .data ); 638 } 639}; 640 641struct CopyWithOffsets :BaseCopyTextureTest 642{ 643void run () 644 { 645auto textureType = srcTextureInfo -> textureType ; 646auto format = srcTextureInfo -> format ; 647 648srcTextureInfo -> extents .width = 8 ; 649srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :8 ; 650srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 651srcTextureInfo -> mipLevelCount = 1 ; 652srcTextureInfo -> arrayLayerCount = 1 ; 653 654generateTextureData (srcTextureInfo ,validationFormat ); 655 656dstTextureInfo -> extents .width = 16 ; 657dstTextureInfo -> extents .height = 658 (textureType == TextureType ::Texture1D ) ?1 :16 ; 659dstTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?4 :1 ; 660dstTextureInfo -> mipLevelCount = 1 ; 661dstTextureInfo -> arrayLayerCount = 1 ; 662 663generateTextureData (dstTextureInfo ,validationFormat ); 664 665SubresourceRange srcSubresource = {}; 666srcSubresource .aspectMask = getTextureAspect (format ); 667srcSubresource .mipLevel = 0 ; 668srcSubresource .mipLevelCount = 1 ; 669srcSubresource .baseArrayLayer = 0 ; 670srcSubresource .layerCount = 1 ; 671 672SubresourceRange dstSubresource = {}; 673dstSubresource .aspectMask = getTextureAspect (format ); 674dstSubresource .mipLevel = 0 ; 675dstSubresource .mipLevelCount = 1 ; 676dstSubresource .baseArrayLayer = 0 ; 677dstSubresource .layerCount = 1 ; 678 679texCopyInfo .srcSubresource = srcSubresource ; 680texCopyInfo .dstSubresource = dstSubresource ; 681texCopyInfo .extent .width = 4 ; 682texCopyInfo .extent .height = 4 ; 683texCopyInfo .extent .depth = 1 ; 684texCopyInfo .srcOffset = {2 ,2 ,0 }; 685texCopyInfo .dstOffset = {4 ,4 ,0 }; 686 687if (textureType == TextureType ::Texture1D ) 688 { 689texCopyInfo .extent .height = 1 ; 690texCopyInfo .srcOffset .y = 0 ; 691texCopyInfo .dstOffset .y = 0 ; 692 } 693else if (textureType == TextureType ::Texture3D ) 694 { 695texCopyInfo .extent .depth = srcTextureInfo -> extents .depth ; 696texCopyInfo .dstOffset .z = 1 ; 697 } 698 699bufferCopyInfo .srcSubresource = dstSubresource ; 700bufferCopyInfo .extent = dstTextureInfo -> extents ; 701bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 702bufferCopyInfo .bufferOffset = 0 ; 703 704createRequiredResources (); 705submitGPUWork (); 706 707auto copiedSubresourceIndex = getSubresourceIndex ( 708srcSubresource .mipLevel , 709srcTextureInfo -> mipLevelCount , 710srcSubresource .baseArrayLayer ); 711SubresourceData expectedCopiedData = 712srcTextureInfo -> subresourceDatas [copiedSubresourceIndex ]; 713auto originalSubresourceIndex = getSubresourceIndex ( 714dstSubresource .mipLevel , 715dstTextureInfo -> mipLevelCount , 716dstSubresource .baseArrayLayer ); 717SubresourceData expectedOriginalData = 718dstTextureInfo -> subresourceDatas [originalSubresourceIndex ]; 719checkTestResults ( 720srcTextureInfo -> extents , 721expectedCopiedData .data , 722expectedOriginalData .data ); 723 } 724}; 725 726struct CopySectionWithSetExtent :BaseCopyTextureTest 727{ 728void run () 729 { 730auto textureType = srcTextureInfo -> textureType ; 731auto format = srcTextureInfo -> format ; 732 733srcTextureInfo -> extents .width = 8 ; 734srcTextureInfo -> extents .height = (textureType == TextureType ::Texture1D ) ?1 :8 ; 735srcTextureInfo -> extents .depth = (textureType == TextureType ::Texture3D ) ?2 :1 ; 736srcTextureInfo -> mipLevelCount = 1 ; 737srcTextureInfo -> arrayLayerCount = 1 ; 738 739generateTextureData (srcTextureInfo ,validationFormat ); 740dstTextureInfo = srcTextureInfo ; 741 742SubresourceRange srcSubresource = {}; 743srcSubresource .aspectMask = getTextureAspect (format ); 744srcSubresource .mipLevel = 0 ; 745srcSubresource .mipLevelCount = 1 ; 746srcSubresource .baseArrayLayer = 0 ; 747srcSubresource .layerCount = 1 ; 748 749SubresourceRange dstSubresource = {}; 750dstSubresource .aspectMask = getTextureAspect (format ); 751dstSubresource .mipLevel = 0 ; 752dstSubresource .mipLevelCount = 1 ; 753dstSubresource .baseArrayLayer = 0 ; 754dstSubresource .layerCount = 1 ; 755 756texCopyInfo .srcSubresource = srcSubresource ; 757texCopyInfo .dstSubresource = dstSubresource ; 758texCopyInfo .extent .width = 4 ; 759texCopyInfo .extent .height = 4 ; 760texCopyInfo .extent .depth = 1 ; 761texCopyInfo .srcOffset = {0 ,0 ,0 }; 762texCopyInfo .dstOffset = {4 ,4 ,0 }; 763 764if (textureType == TextureType ::Texture1D ) 765 { 766texCopyInfo .extent .height = 1 ; 767texCopyInfo .dstOffset .y = 0 ; 768 } 769else if (textureType == TextureType ::Texture3D ) 770 { 771texCopyInfo .extent .depth = srcTextureInfo -> extents .depth ; 772 } 773 774bufferCopyInfo .srcSubresource = dstSubresource ; 775bufferCopyInfo .extent = dstTextureInfo -> extents ; 776bufferCopyInfo .textureOffset = {0 ,0 ,0 }; 777bufferCopyInfo .bufferOffset = 0 ; 778 779createRequiredResources (); 780submitGPUWork (); 781 782auto copiedSubresourceIndex = getSubresourceIndex ( 783srcSubresource .mipLevel , 784srcTextureInfo -> mipLevelCount , 785srcSubresource .baseArrayLayer ); 786SubresourceData expectedCopiedData = 787srcTextureInfo -> subresourceDatas [copiedSubresourceIndex ]; 788auto originalSubresourceIndex = getSubresourceIndex ( 789dstSubresource .mipLevel , 790dstTextureInfo -> mipLevelCount , 791dstSubresource .baseArrayLayer ); 792SubresourceData expectedOriginalData = 793dstTextureInfo -> subresourceDatas [originalSubresourceIndex ]; 794checkTestResults ( 795srcTextureInfo -> extents , 796expectedCopiedData .data , 797expectedOriginalData .data ); 798 } 799}; 800 801template < typename T > 802void copyTextureTestImpl (IDevice * device ,UnitTestContext * context ) 803{ 804const bool isVkd3d = 805SLANG_ENABLE_VKD3D && strcmp (device -> getDeviceInfo ().apiName ,"Direct3D 12" )== 0 ; 806 807// Skip Type::Unknown and Type::Buffer as well as Format::Unknown 808// TODO: Add support for TextureCube 809Format formats []= { 810Format ::R8G8B8A8_UNORM , 811Format ::R16_FLOAT , 812Format ::R16G16_FLOAT , 813Format ::R10G10B10A2_UNORM , 814Format ::B5G5R5A1_UNORM }; 815for (uint32_t i = 2 ;i < (uint32_t )TextureType ::_Count - 1 ;++ i ) 816 { 817for (auto format :formats ) 818 { 819// Fails validation VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251 820if (isVkd3d && 821 (format == Format ::R32G32B32_TYPELESS || format == Format ::R32G32B32_FLOAT || 822format == Format ::R32G32B32_UINT || format == Format ::R32G32B32_SINT )) 823 { 824continue ; 825 } 826auto type = (TextureType )i ; 827auto validationFormat = getValidationTextureFormat (format ); 828if (!validationFormat ) 829continue ; 830 831T test ; 832test .init (device ,context ,format ,validationFormat ,type ); 833test .run (); 834 } 835 } 836} 837 838SLANG_UNIT_TEST (copyTextureSimple ) 839{ 840runTestImpl ( 841copyTextureTestImpl < SimpleCopyTexture > , 842unitTestContext , 843Slang ::RenderApiFlag ::D3D12 ); 844runTestImpl ( 845copyTextureTestImpl < SimpleCopyTexture > , 846unitTestContext , 847Slang ::RenderApiFlag ::Vulkan ); 848} 849 850SLANG_UNIT_TEST (copyTextureSection ) 851{ 852runTestImpl ( 853copyTextureTestImpl < CopyTextureSection > , 854unitTestContext , 855Slang ::RenderApiFlag ::D3D12 ); 856runTestImpl ( 857copyTextureTestImpl < CopyTextureSection > , 858unitTestContext , 859Slang ::RenderApiFlag ::Vulkan ); 860} 861 862SLANG_UNIT_TEST (copyLargeToSmallTexture ) 863{ 864runTestImpl ( 865copyTextureTestImpl < LargeSrcToSmallDst > , 866unitTestContext , 867Slang ::RenderApiFlag ::D3D12 ); 868runTestImpl ( 869copyTextureTestImpl < LargeSrcToSmallDst > , 870unitTestContext , 871Slang ::RenderApiFlag ::Vulkan ); 872} 873 874SLANG_UNIT_TEST (copySmallToLargeTexture ) 875{ 876runTestImpl ( 877copyTextureTestImpl < SmallSrcToLargeDst > , 878unitTestContext , 879Slang ::RenderApiFlag ::D3D12 ); 880runTestImpl ( 881copyTextureTestImpl < SmallSrcToLargeDst > , 882unitTestContext , 883Slang ::RenderApiFlag ::Vulkan ); 884} 885 886SLANG_UNIT_TEST (copyBetweenMips ) 887{ 888runTestImpl (copyTextureTestImpl < CopyBetweenMips > ,unitTestContext ,Slang ::RenderApiFlag ::D3D12 ); 889runTestImpl ( 890copyTextureTestImpl < CopyBetweenMips > , 891unitTestContext , 892Slang ::RenderApiFlag ::Vulkan ); 893} 894 895SLANG_UNIT_TEST (copyBetweenLayers ) 896{ 897runTestImpl ( 898copyTextureTestImpl < CopyBetweenLayers > , 899unitTestContext , 900Slang ::RenderApiFlag ::D3D12 ); 901runTestImpl ( 902copyTextureTestImpl < CopyBetweenLayers > , 903unitTestContext , 904Slang ::RenderApiFlag ::Vulkan ); 905} 906 907SLANG_UNIT_TEST (copyWithOffsets ) 908{ 909runTestImpl (copyTextureTestImpl < CopyWithOffsets > ,unitTestContext ,Slang ::RenderApiFlag ::D3D12 ); 910runTestImpl ( 911copyTextureTestImpl < CopyWithOffsets > , 912unitTestContext , 913Slang ::RenderApiFlag ::Vulkan ); 914} 915 916SLANG_UNIT_TEST (copySectionWithSetExtent ) 917{ 918runTestImpl ( 919copyTextureTestImpl < CopySectionWithSetExtent > , 920unitTestContext , 921Slang ::RenderApiFlag ::D3D12 ); 922runTestImpl ( 923copyTextureTestImpl < CopySectionWithSetExtent > , 924unitTestContext , 925Slang ::RenderApiFlag ::Vulkan ); 926} 927}// namespace gfx_test 928#endif