1export const description = ` 2copyTextureToTexture tests. 3 4Test Plan: (TODO(jiawei.shao@intel.com): add tests on aspects and 1D/3D textures) 5* the source and destination texture 6 - the {source, destination} texture is {invalid, valid}. 7 - mipLevel {>, =, <} the mipmap level count of the {source, destination} texture. 8 - the source texture is created {with, without} GPUTextureUsage::CopySrc. 9 - the destination texture is created {with, without} GPUTextureUsage::CopyDst. 10* sample count 11 - the sample count of the source texture {is, isn't} equal to the one of the destination texture 12 - when the sample count is greater than 1: 13 - it {is, isn't} a copy of the whole subresource of the source texture. 14 - it {is, isn't} a copy of the whole subresource of the destination texture. 15* texture format 16 - the format of the source texture {is, isn't} equal to the one of the destination texture. 17 - including: depth24plus-stencil8 to/from {depth24plus, stencil8}. 18 - for each depth and/or stencil format: a copy between two textures with same format: 19 - it {is, isn't} a copy of the whole subresource of the {source, destination} texture. 20* copy ranges 21 - if the texture dimension is 2D: 22 - (srcOrigin.x + copyExtent.width) {>, =, <} the width of the subresource size of source 23 textureCopyView. 24 - (srcOrigin.y + copyExtent.height) {>, =, <} the height of the subresource size of source 25 textureCopyView. 26 - (srcOrigin.z + copyExtent.depth) {>, =, <} the depth of the subresource size of source 27 textureCopyView. 28 - (dstOrigin.x + copyExtent.width) {>, =, <} the width of the subresource size of destination 29 textureCopyView. 30 - (dstOrigin.y + copyExtent.height) {>, =, <} the height of the subresource size of destination 31 textureCopyView. 32 - (dstOrigin.z + copyExtent.depth) {>, =, <} the depth of the subresource size of destination 33 textureCopyView. 34* when the source and destination texture are the same one: 35 - the set of source texture subresources {has, doesn't have} overlaps with the one of destination 36 texture subresources. 37`; 38 39import { poptions, params } from '../../../common/framework/params_builder.js'; 40import { makeTestGroup } from '../../../common/framework/test_group.js'; 41import { assert } from '../../../common/framework/util/util.js'; 42import { 43 kAllTextureFormatInfo, 44 kAllTextureFormats, 45 kCompressedTextureFormats, 46 kDepthStencilFormats, 47 kTextureUsages, 48} from '../../capability_info.js'; 49import { align } from '../../util/math.js'; 50 51import { ValidationTest } from './validation_test.js'; 52 53class F extends ValidationTest { 54 TestCopyTextureToTexture( 55 source: GPUTextureCopyView, 56 destination: GPUTextureCopyView, 57 copySize: GPUExtent3D, 58 isSuccess: boolean 59 ): void { 60 const commandEncoder = this.device.createCommandEncoder(); 61 commandEncoder.copyTextureToTexture(source, destination, copySize); 62 63 this.expectValidationError(() => { 64 commandEncoder.finish(); 65 }, !isSuccess); 66 } 67 68 GetPhysicalSubresourceSize( 69 textureSize: GPUExtent3DDict, 70 format: GPUTextureFormat, 71 mipLevel: number 72 ): GPUExtent3DDict { 73 const virtualWidthAtLevel = Math.max(textureSize.width >> mipLevel, 1); 74 const virtualHeightAtLevel = Math.max(textureSize.height >> mipLevel, 1); 75 const physicalWidthAtLevel = align( 76 virtualWidthAtLevel, 77 kAllTextureFormatInfo[format].blockWidth 78 ); 79 const physicalHeightAtLevel = align( 80 virtualHeightAtLevel, 81 kAllTextureFormatInfo[format].blockHeight 82 ); 83 return { width: physicalWidthAtLevel, height: physicalHeightAtLevel, depth: textureSize.depth }; 84 } 85} 86 87export const g = makeTestGroup(F); 88 89g.test('copy_with_invalid_texture').fn(async t => { 90 const validTexture = t.device.createTexture({ 91 size: { width: 4, height: 4, depth: 1 }, 92 format: 'rgba8unorm', 93 usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST, 94 }); 95 96 const errorTexture = t.getErrorTexture(); 97 98 t.TestCopyTextureToTexture( 99 { texture: errorTexture }, 100 { texture: validTexture }, 101 { width: 1, height: 1, depth: 1 }, 102 false 103 ); 104 t.TestCopyTextureToTexture( 105 { texture: validTexture }, 106 { texture: errorTexture }, 107 { width: 1, height: 1, depth: 1 }, 108 false 109 ); 110}); 111 112g.test('mipmap_level') 113 .params([ 114 { srcLevelCount: 1, dstLevelCount: 1, srcCopyLevel: 0, dstCopyLevel: 0 }, 115 { srcLevelCount: 1, dstLevelCount: 1, srcCopyLevel: 1, dstCopyLevel: 0 }, 116 { srcLevelCount: 1, dstLevelCount: 1, srcCopyLevel: 0, dstCopyLevel: 1 }, 117 { srcLevelCount: 3, dstLevelCount: 3, srcCopyLevel: 0, dstCopyLevel: 0 }, 118 { srcLevelCount: 3, dstLevelCount: 3, srcCopyLevel: 2, dstCopyLevel: 0 }, 119 { srcLevelCount: 3, dstLevelCount: 3, srcCopyLevel: 3, dstCopyLevel: 0 }, 120 { srcLevelCount: 3, dstLevelCount: 3, srcCopyLevel: 0, dstCopyLevel: 2 }, 121 { srcLevelCount: 3, dstLevelCount: 3, srcCopyLevel: 0, dstCopyLevel: 3 }, 122 ] as const) 123 .fn(async t => { 124 const { srcLevelCount, dstLevelCount, srcCopyLevel, dstCopyLevel } = t.params; 125 126 const srcTexture = t.device.createTexture({ 127 size: { width: 32, height: 32, depth: 1 }, 128 format: 'rgba8unorm', 129 usage: GPUTextureUsage.COPY_SRC, 130 mipLevelCount: srcLevelCount, 131 }); 132 const dstTexture = t.device.createTexture({ 133 size: { width: 32, height: 32, depth: 1 }, 134 format: 'rgba8unorm', 135 usage: GPUTextureUsage.COPY_DST, 136 mipLevelCount: dstLevelCount, 137 }); 138 139 const isSuccess = srcCopyLevel < srcLevelCount && dstCopyLevel < dstLevelCount; 140 t.TestCopyTextureToTexture( 141 { texture: srcTexture, mipLevel: srcCopyLevel }, 142 { texture: dstTexture, mipLevel: dstCopyLevel }, 143 { width: 1, height: 1, depth: 1 }, 144 isSuccess 145 ); 146 }); 147 148g.test('texture_usage') 149 .params( 150 params() 151 .combine(poptions('srcUsage', kTextureUsages)) 152 .combine(poptions('dstUsage', kTextureUsages)) 153 ) 154 .fn(async t => { 155 const { srcUsage, dstUsage } = t.params; 156 157 const srcTexture = t.device.createTexture({ 158 size: { width: 4, height: 4, depth: 1 }, 159 format: 'rgba8unorm', 160 usage: srcUsage, 161 }); 162 const dstTexture = t.device.createTexture({ 163 size: { width: 4, height: 4, depth: 1 }, 164 format: 'rgba8unorm', 165 usage: dstUsage, 166 }); 167 168 const isSuccess = 169 srcUsage === GPUTextureUsage.COPY_SRC && dstUsage === GPUTextureUsage.COPY_DST; 170 171 t.TestCopyTextureToTexture( 172 { texture: srcTexture }, 173 { texture: dstTexture }, 174 { width: 1, height: 1, depth: 1 }, 175 isSuccess 176 ); 177 }); 178 179g.test('sample_count') 180 .params( 181 params() 182 .combine(poptions('srcSampleCount', [1, 4])) 183 .combine(poptions('dstSampleCount', [1, 4])) 184 ) 185 .fn(async t => { 186 const { srcSampleCount, dstSampleCount } = t.params; 187 188 const srcTexture = t.device.createTexture({ 189 size: { width: 4, height: 4, depth: 1 }, 190 format: 'rgba8unorm', 191 usage: GPUTextureUsage.COPY_SRC, 192 sampleCount: srcSampleCount, 193 }); 194 const dstTexture = t.device.createTexture({ 195 size: { width: 4, height: 4, depth: 1 }, 196 format: 'rgba8unorm', 197 usage: GPUTextureUsage.COPY_DST, 198 sampleCount: dstSampleCount, 199 }); 200 201 const isSuccess = srcSampleCount === dstSampleCount; 202 t.TestCopyTextureToTexture( 203 { texture: srcTexture }, 204 { texture: dstTexture }, 205 { width: 4, height: 4, depth: 1 }, 206 isSuccess 207 ); 208 }); 209 210g.test('multisampled_copy_restrictions') 211 .params( 212 params() 213 .combine( 214 poptions('srcCopyOrigin', [ 215 { x: 0, y: 0, z: 0 }, 216 { x: 1, y: 0, z: 0 }, 217 { x: 0, y: 1, z: 0 }, 218 { x: 1, y: 1, z: 0 }, 219 ]) 220 ) 221 .combine( 222 poptions('dstCopyOrigin', [ 223 { x: 0, y: 0, z: 0 }, 224 { x: 1, y: 0, z: 0 }, 225 { x: 0, y: 1, z: 0 }, 226 { x: 1, y: 1, z: 0 }, 227 ]) 228 ) 229 .expand(p => poptions('copyWidth', [32 - Math.max(p.srcCopyOrigin.x, p.dstCopyOrigin.x), 16])) 230 .expand(p => poptions('copyHeight', [16 - Math.max(p.srcCopyOrigin.y, p.dstCopyOrigin.y), 8])) 231 ) 232 .fn(async t => { 233 const { srcCopyOrigin, dstCopyOrigin, copyWidth, copyHeight } = t.params; 234 235 const kWidth = 32; 236 const kHeight = 16; 237 238 // Currently we don't support multisampled 2D array textures and the mipmap level count of the 239 // multisampled textures must be 1. 240 const srcTexture = t.device.createTexture({ 241 size: { width: kWidth, height: kHeight, depth: 1 }, 242 format: 'rgba8unorm', 243 usage: GPUTextureUsage.COPY_SRC, 244 sampleCount: 4, 245 }); 246 const dstTexture = t.device.createTexture({ 247 size: { width: kWidth, height: kHeight, depth: 1 }, 248 format: 'rgba8unorm', 249 usage: GPUTextureUsage.COPY_DST, 250 sampleCount: 4, 251 }); 252 253 const isSuccess = copyWidth === kWidth && copyHeight === kHeight; 254 t.TestCopyTextureToTexture( 255 { texture: srcTexture, origin: srcCopyOrigin }, 256 { texture: dstTexture, origin: dstCopyOrigin }, 257 { width: copyWidth, height: copyHeight, depth: 1 }, 258 isSuccess 259 ); 260 }); 261 262g.test('texture_format_equality') 263 .params( 264 params() 265 .combine(poptions('srcFormat', kAllTextureFormats)) 266 .combine(poptions('dstFormat', kAllTextureFormats)) 267 ) 268 .fn(async t => { 269 const { srcFormat, dstFormat } = t.params; 270 const extensions: Array<GPUExtensionName> = []; 271 272 const srcFormatExtension = kAllTextureFormatInfo[srcFormat].extension; 273 if (srcFormatExtension !== undefined) { 274 extensions.push(srcFormatExtension); 275 } 276 const dstFormatExtension = kAllTextureFormatInfo[dstFormat].extension; 277 if (dstFormatExtension !== undefined) { 278 extensions.push(dstFormatExtension); 279 } 280 281 if (extensions.length) { 282 await t.selectDeviceOrSkipTestCase({ extensions }); 283 } 284 285 const kTextureSize = { width: 16, height: 16, depth: 1 }; 286 287 const srcTexture = t.device.createTexture({ 288 size: kTextureSize, 289 format: srcFormat, 290 usage: GPUTextureUsage.COPY_SRC, 291 }); 292 293 const dstTexture = t.device.createTexture({ 294 size: kTextureSize, 295 format: dstFormat, 296 usage: GPUTextureUsage.COPY_DST, 297 }); 298 299 const isSuccess = srcFormat === dstFormat; 300 t.TestCopyTextureToTexture( 301 { texture: srcTexture }, 302 { texture: dstTexture }, 303 kTextureSize, 304 isSuccess 305 ); 306 }); 307 308g.test('depth_stencil_copy_restrictions') 309 .params( 310 params() 311 .combine(poptions('format', kDepthStencilFormats)) 312 .combine( 313 poptions('copyBoxOffsets', [ 314 { x: 0, y: 0, width: 0, height: 0 }, 315 { x: 1, y: 0, width: 0, height: 0 }, 316 { x: 0, y: 1, width: 0, height: 0 }, 317 { x: 0, y: 0, width: -1, height: 0 }, 318 { x: 0, y: 0, width: 0, height: -1 }, 319 ]) 320 ) 321 .combine( 322 poptions('srcTextureSize', [ 323 { width: 64, height: 64, depth: 1 }, 324 { width: 64, height: 32, depth: 1 }, 325 { width: 32, height: 32, depth: 1 }, 326 ]) 327 ) 328 .combine( 329 poptions('dstTextureSize', [ 330 { width: 64, height: 64, depth: 1 }, 331 { width: 64, height: 32, depth: 1 }, 332 { width: 32, height: 32, depth: 1 }, 333 ]) 334 ) 335 .combine(poptions('srcCopyLevel', [1, 2])) 336 .combine(poptions('dstCopyLevel', [0, 1])) 337 ) 338 .fn(async t => { 339 const { 340 format, 341 copyBoxOffsets, 342 srcTextureSize, 343 dstTextureSize, 344 srcCopyLevel, 345 dstCopyLevel, 346 } = t.params; 347 348 const kMipLevelCount = 3; 349 const srcTexture = t.device.createTexture({ 350 size: { width: srcTextureSize.width, height: srcTextureSize.height, depth: 1 }, 351 format, 352 mipLevelCount: kMipLevelCount, 353 usage: GPUTextureUsage.COPY_SRC, 354 }); 355 const dstTexture = t.device.createTexture({ 356 size: { width: dstTextureSize.width, height: dstTextureSize.height, depth: 1 }, 357 format, 358 mipLevelCount: kMipLevelCount, 359 usage: GPUTextureUsage.COPY_DST, 360 }); 361 362 const srcSizeAtLevel = t.GetPhysicalSubresourceSize(srcTextureSize, format, srcCopyLevel); 363 const dstSizeAtLevel = t.GetPhysicalSubresourceSize(dstTextureSize, format, dstCopyLevel); 364 365 const copyOrigin = { x: copyBoxOffsets.x, y: copyBoxOffsets.y, z: 0 }; 366 367 const copyWidth = 368 Math.min(srcSizeAtLevel.width, dstSizeAtLevel.width) + copyBoxOffsets.width - copyOrigin.x; 369 const copyHeight = 370 Math.min(srcSizeAtLevel.height, dstSizeAtLevel.height) + copyBoxOffsets.height - copyOrigin.y; 371 372 // Depth/stencil copies must copy whole subresources. 373 const isSuccess = 374 copyOrigin.x === 0 && 375 copyOrigin.y === 0 && 376 copyWidth === srcSizeAtLevel.width && 377 copyHeight === srcSizeAtLevel.height && 378 copyWidth === dstSizeAtLevel.width && 379 copyHeight === dstSizeAtLevel.height; 380 t.TestCopyTextureToTexture( 381 { texture: srcTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: srcCopyLevel }, 382 { texture: dstTexture, origin: copyOrigin, mipLevel: dstCopyLevel }, 383 { width: copyWidth, height: copyHeight, depth: 1 }, 384 isSuccess 385 ); 386 t.TestCopyTextureToTexture( 387 { texture: srcTexture, origin: copyOrigin, mipLevel: srcCopyLevel }, 388 { texture: dstTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: dstCopyLevel }, 389 { width: copyWidth, height: copyHeight, depth: 1 }, 390 isSuccess 391 ); 392 }); 393 394g.test('copy_ranges') 395 .params( 396 params() 397 .combine( 398 poptions('copyBoxOffsets', [ 399 { x: 0, y: 0, z: 0, width: 0, height: 0, depth: -2 }, 400 { x: 1, y: 0, z: 0, width: 0, height: 0, depth: -2 }, 401 { x: 1, y: 0, z: 0, width: -1, height: 0, depth: -2 }, 402 { x: 0, y: 1, z: 0, width: 0, height: 0, depth: -2 }, 403 { x: 0, y: 1, z: 0, width: 0, height: -1, depth: -2 }, 404 { x: 0, y: 0, z: 1, width: 0, height: 1, depth: -2 }, 405 { x: 0, y: 0, z: 2, width: 0, height: 1, depth: 0 }, 406 { x: 0, y: 0, z: 0, width: 1, height: 0, depth: -2 }, 407 { x: 0, y: 0, z: 0, width: 0, height: 1, depth: -2 }, 408 { x: 0, y: 0, z: 0, width: 0, height: 0, depth: 1 }, 409 { x: 0, y: 0, z: 0, width: 0, height: 0, depth: 0 }, 410 { x: 0, y: 0, z: 1, width: 0, height: 0, depth: -1 }, 411 { x: 0, y: 0, z: 2, width: 0, height: 0, depth: -1 }, 412 ]) 413 ) 414 .combine(poptions('srcCopyLevel', [0, 1, 3])) 415 .combine(poptions('dstCopyLevel', [0, 1, 3])) 416 ) 417 .fn(async t => { 418 const { copyBoxOffsets, srcCopyLevel, dstCopyLevel } = t.params; 419 420 const kTextureSize = { width: 16, height: 8, depth: 3 }; 421 const kMipLevelCount = 4; 422 const kFormat = 'rgba8unorm'; 423 424 const srcTexture = t.device.createTexture({ 425 size: kTextureSize, 426 format: kFormat, 427 mipLevelCount: kMipLevelCount, 428 usage: GPUTextureUsage.COPY_SRC, 429 }); 430 const dstTexture = t.device.createTexture({ 431 size: kTextureSize, 432 format: kFormat, 433 mipLevelCount: kMipLevelCount, 434 usage: GPUTextureUsage.COPY_DST, 435 }); 436 437 const srcSizeAtLevel = t.GetPhysicalSubresourceSize(kTextureSize, kFormat, srcCopyLevel); 438 const dstSizeAtLevel = t.GetPhysicalSubresourceSize(kTextureSize, kFormat, dstCopyLevel); 439 440 const copyOrigin = { x: copyBoxOffsets.x, y: copyBoxOffsets.y, z: copyBoxOffsets.z }; 441 442 const copyWidth = Math.max( 443 Math.min(srcSizeAtLevel.width, dstSizeAtLevel.width) + copyBoxOffsets.width - copyOrigin.x, 444 0 445 ); 446 const copyHeight = Math.max( 447 Math.min(srcSizeAtLevel.height, dstSizeAtLevel.height) + copyBoxOffsets.height - copyOrigin.y, 448 0 449 ); 450 const copyDepth = kTextureSize.depth + copyBoxOffsets.depth - copyOrigin.z; 451 452 { 453 const isSuccess = 454 copyWidth <= srcSizeAtLevel.width && 455 copyHeight <= srcSizeAtLevel.height && 456 copyOrigin.x + copyWidth <= dstSizeAtLevel.width && 457 copyOrigin.y + copyHeight <= dstSizeAtLevel.height && 458 copyOrigin.z + copyDepth <= kTextureSize.depth; 459 460 t.TestCopyTextureToTexture( 461 { texture: srcTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: srcCopyLevel }, 462 { texture: dstTexture, origin: copyOrigin, mipLevel: dstCopyLevel }, 463 { width: copyWidth, height: copyHeight, depth: copyDepth }, 464 isSuccess 465 ); 466 } 467 468 { 469 const isSuccess = 470 copyOrigin.x + copyWidth <= srcSizeAtLevel.width && 471 copyOrigin.y + copyHeight <= srcSizeAtLevel.height && 472 copyWidth <= dstSizeAtLevel.width && 473 copyHeight <= dstSizeAtLevel.height && 474 copyOrigin.z + copyDepth <= kTextureSize.depth; 475 476 t.TestCopyTextureToTexture( 477 { texture: srcTexture, origin: copyOrigin, mipLevel: srcCopyLevel }, 478 { texture: dstTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: dstCopyLevel }, 479 { width: copyWidth, height: copyHeight, depth: copyDepth }, 480 isSuccess 481 ); 482 } 483 }); 484 485g.test('copy_within_same_texture') 486 .params( 487 params() 488 .combine(poptions('srcCopyOriginZ', [0, 2, 4])) 489 .combine(poptions('dstCopyOriginZ', [0, 2, 4])) 490 .combine(poptions('copyExtentDepth', [1, 2, 3])) 491 ) 492 .fn(async t => { 493 const { srcCopyOriginZ, dstCopyOriginZ, copyExtentDepth } = t.params; 494 495 const kArrayLayerCount = 7; 496 497 const testTexture = t.device.createTexture({ 498 size: { width: 16, height: 16, depth: kArrayLayerCount }, 499 format: 'rgba8unorm', 500 usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST, 501 }); 502 503 const isSuccess = 504 Math.min(srcCopyOriginZ, dstCopyOriginZ) + copyExtentDepth <= 505 Math.max(srcCopyOriginZ, dstCopyOriginZ); 506 t.TestCopyTextureToTexture( 507 { texture: testTexture, origin: { x: 0, y: 0, z: srcCopyOriginZ } }, 508 { texture: testTexture, origin: { x: 0, y: 0, z: dstCopyOriginZ } }, 509 { width: 16, height: 16, depth: copyExtentDepth }, 510 isSuccess 511 ); 512 }); 513 514g.test('copy_ranges_with_compressed_texture_formats') 515 .params( 516 params() 517 .combine(poptions('format', kCompressedTextureFormats)) 518 .combine( 519 poptions('copyBoxOffsets', [ 520 { x: 0, y: 0, z: 0, width: 0, height: 0, depth: -2 }, 521 { x: 1, y: 0, z: 0, width: 0, height: 0, depth: -2 }, 522 { x: 4, y: 0, z: 0, width: 0, height: 0, depth: -2 }, 523 { x: 0, y: 0, z: 0, width: -1, height: 0, depth: -2 }, 524 { x: 0, y: 0, z: 0, width: -4, height: 0, depth: -2 }, 525 { x: 0, y: 1, z: 0, width: 0, height: 0, depth: -2 }, 526 { x: 0, y: 4, z: 0, width: 0, height: 0, depth: -2 }, 527 { x: 0, y: 0, z: 0, width: 0, height: -1, depth: -2 }, 528 { x: 0, y: 0, z: 0, width: 0, height: -4, depth: -2 }, 529 { x: 0, y: 0, z: 0, width: 0, height: 0, depth: 0 }, 530 { x: 0, y: 0, z: 1, width: 0, height: 0, depth: -1 }, 531 ]) 532 ) 533 .combine(poptions('srcCopyLevel', [0, 1, 2])) 534 .combine(poptions('dstCopyLevel', [0, 1, 2])) 535 ) 536 .fn(async t => { 537 const { format, copyBoxOffsets, srcCopyLevel, dstCopyLevel } = t.params; 538 539 const extension: GPUExtensionName | undefined = kAllTextureFormatInfo[format].extension; 540 assert(extension !== undefined); 541 await t.selectDeviceOrSkipTestCase({ extensions: [extension] }); 542 543 const kTextureSize = { width: 60, height: 48, depth: 3 }; 544 const kMipLevelCount = 4; 545 546 const srcTexture = t.device.createTexture({ 547 size: kTextureSize, 548 format, 549 mipLevelCount: kMipLevelCount, 550 usage: GPUTextureUsage.COPY_SRC, 551 }); 552 const dstTexture = t.device.createTexture({ 553 size: kTextureSize, 554 format, 555 mipLevelCount: kMipLevelCount, 556 usage: GPUTextureUsage.COPY_DST, 557 }); 558 559 const srcSizeAtLevel = t.GetPhysicalSubresourceSize(kTextureSize, format, srcCopyLevel); 560 const dstSizeAtLevel = t.GetPhysicalSubresourceSize(kTextureSize, format, dstCopyLevel); 561 562 const copyOrigin = { x: copyBoxOffsets.x, y: copyBoxOffsets.y, z: copyBoxOffsets.z }; 563 564 const copyWidth = Math.max( 565 Math.min(srcSizeAtLevel.width, dstSizeAtLevel.width) + copyBoxOffsets.width - copyOrigin.x, 566 0 567 ); 568 const copyHeight = Math.max( 569 Math.min(srcSizeAtLevel.height, dstSizeAtLevel.height) + copyBoxOffsets.height - copyOrigin.y, 570 0 571 ); 572 const copyDepth = kTextureSize.depth + copyBoxOffsets.depth - copyOrigin.z; 573 574 const texelBlockWidth = kAllTextureFormatInfo[format].blockWidth; 575 const texelBlockHeight = kAllTextureFormatInfo[format].blockHeight; 576 577 const isSuccessForCompressedFormats = 578 copyOrigin.x % texelBlockWidth === 0 && 579 copyOrigin.y % texelBlockHeight === 0 && 580 copyWidth % texelBlockWidth === 0 && 581 copyHeight % texelBlockHeight === 0; 582 583 { 584 const isSuccess = 585 isSuccessForCompressedFormats && 586 copyWidth <= srcSizeAtLevel.width && 587 copyHeight <= srcSizeAtLevel.height && 588 copyOrigin.x + copyWidth <= dstSizeAtLevel.width && 589 copyOrigin.y + copyHeight <= dstSizeAtLevel.height && 590 copyOrigin.z + copyDepth <= kTextureSize.depth; 591 592 t.TestCopyTextureToTexture( 593 { texture: srcTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: srcCopyLevel }, 594 { texture: dstTexture, origin: copyOrigin, mipLevel: dstCopyLevel }, 595 { width: copyWidth, height: copyHeight, depth: copyDepth }, 596 isSuccess 597 ); 598 } 599 600 { 601 const isSuccess = 602 isSuccessForCompressedFormats && 603 copyOrigin.x + copyWidth <= srcSizeAtLevel.width && 604 copyOrigin.y + copyHeight <= srcSizeAtLevel.height && 605 copyWidth <= dstSizeAtLevel.width && 606 copyHeight <= dstSizeAtLevel.height && 607 copyOrigin.z + copyDepth <= kTextureSize.depth; 608 609 t.TestCopyTextureToTexture( 610 { texture: srcTexture, origin: copyOrigin, mipLevel: srcCopyLevel }, 611 { texture: dstTexture, origin: { x: 0, y: 0, z: 0 }, mipLevel: dstCopyLevel }, 612 { width: copyWidth, height: copyHeight, depth: copyDepth }, 613 isSuccess 614 ); 615 } 616 }); 617