1/************************************************************************** 2 * 3 * Copyright 2012-2021 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 **************************************************************************/ 27 28/* 29 * Resource.cpp -- 30 * Functions that manipulate GPU resources. 31 */ 32 33 34#include "Resource.h" 35#include "Format.h" 36#include "State.h" 37#include "Query.h" 38 39#include "Debug.h" 40 41#include "util/u_math.h" 42#include "util/u_rect.h" 43#include "util/u_surface.h" 44 45 46/* 47 * ---------------------------------------------------------------------- 48 * 49 * CalcPrivateResourceSize -- 50 * 51 * The CalcPrivateResourceSize function determines the size of 52 * the user-mode display driver's private region of memory 53 * (that is, the size of internal driver structures, not the 54 * size of the resource video memory). 55 * 56 * ---------------------------------------------------------------------- 57 */ 58 59SIZE_T APIENTRY 60CalcPrivateResourceSize(D3D10DDI_HDEVICE hDevice, // IN 61 __in const D3D10DDIARG_CREATERESOURCE *pCreateResource) // IN 62{ 63 LOG_ENTRYPOINT(); 64 return sizeof(Resource); 65} 66 67 68static unsigned 69translate_resource_usage( unsigned usage ) 70{ 71 unsigned resource_usage = 0; 72 73 switch (usage) { 74 case D3D10_DDI_USAGE_DEFAULT: 75 resource_usage = PIPE_USAGE_DEFAULT; 76 break; 77 case D3D10_DDI_USAGE_IMMUTABLE: 78 resource_usage = PIPE_USAGE_IMMUTABLE; 79 break; 80 case D3D10_DDI_USAGE_DYNAMIC: 81 resource_usage = PIPE_USAGE_DYNAMIC; 82 break; 83 case D3D10_DDI_USAGE_STAGING: 84 resource_usage = PIPE_USAGE_STAGING; 85 break; 86 default: 87 assert(0); 88 break; 89 } 90 91 return resource_usage; 92} 93 94 95static unsigned 96translate_resource_flags(UINT flags) 97{ 98 unsigned bind = 0; 99 100 if (flags & D3D10_DDI_BIND_VERTEX_BUFFER) 101 bind |= PIPE_BIND_VERTEX_BUFFER; 102 103 if (flags & D3D10_DDI_BIND_INDEX_BUFFER) 104 bind |= PIPE_BIND_INDEX_BUFFER; 105 106 if (flags & D3D10_DDI_BIND_CONSTANT_BUFFER) 107 bind |= PIPE_BIND_CONSTANT_BUFFER; 108 109 if (flags & D3D10_DDI_BIND_SHADER_RESOURCE) 110 bind |= PIPE_BIND_SAMPLER_VIEW; 111 112 if (flags & D3D10_DDI_BIND_RENDER_TARGET) 113 bind |= PIPE_BIND_RENDER_TARGET; 114 115 if (flags & D3D10_DDI_BIND_DEPTH_STENCIL) 116 bind |= PIPE_BIND_DEPTH_STENCIL; 117 118 if (flags & D3D10_DDI_BIND_STREAM_OUTPUT) 119 bind |= PIPE_BIND_STREAM_OUTPUT; 120 121 return bind; 122} 123 124 125static enum pipe_texture_target 126translate_texture_target( D3D10DDIRESOURCE_TYPE ResourceDimension, 127 UINT ArraySize) 128{ 129 assert(ArraySize >= 1); 130 switch(ResourceDimension) { 131 case D3D10DDIRESOURCE_BUFFER: 132 assert(ArraySize == 1); 133 return PIPE_BUFFER; 134 case D3D10DDIRESOURCE_TEXTURE1D: 135 return ArraySize > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D; 136 case D3D10DDIRESOURCE_TEXTURE2D: 137 return ArraySize > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D; 138 case D3D10DDIRESOURCE_TEXTURE3D: 139 assert(ArraySize == 1); 140 return PIPE_TEXTURE_3D; 141 case D3D10DDIRESOURCE_TEXTURECUBE: 142 assert(ArraySize % 6 == 0); 143 return ArraySize > 6 ? PIPE_TEXTURE_CUBE_ARRAY : PIPE_TEXTURE_CUBE; 144 default: 145 assert(0); 146 return PIPE_TEXTURE_1D; 147 } 148} 149 150 151static void 152subResourceBox(struct pipe_resource *resource, // IN 153 UINT SubResource, // IN 154 unsigned *pLevel, // OUT 155 struct pipe_box *pBox) // OUT 156{ 157 UINT MipLevels = resource->last_level + 1; 158 unsigned layer; 159 unsigned width; 160 unsigned height; 161 unsigned depth; 162 163 *pLevel = SubResource % MipLevels; 164 layer = SubResource / MipLevels; 165 166 width = u_minify(resource->width0, *pLevel); 167 height = u_minify(resource->height0, *pLevel); 168 depth = u_minify(resource->depth0, *pLevel); 169 170 pBox->x = 0; 171 pBox->y = 0; 172 pBox->z = 0 + layer; 173 pBox->width = width; 174 pBox->height = height; 175 pBox->depth = depth; 176} 177 178 179/* 180 * ---------------------------------------------------------------------- 181 * 182 * CreateResource -- 183 * 184 * The CreateResource function creates a resource. 185 * 186 * ---------------------------------------------------------------------- 187 */ 188 189void APIENTRY 190CreateResource(D3D10DDI_HDEVICE hDevice, // IN 191 __in const D3D10DDIARG_CREATERESOURCE *pCreateResource, // IN 192 D3D10DDI_HRESOURCE hResource, // IN 193 D3D10DDI_HRTRESOURCE hRTResource) // IN 194{ 195 LOG_ENTRYPOINT(); 196 197 if ((pCreateResource->MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED) || 198 (pCreateResource->pPrimaryDesc && 199 pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) { 200 201 DebugPrintf("%s(%dx%dx%d hResource=%p)\n", 202 __FUNCTION__, 203 pCreateResource->pMipInfoList[0].TexelWidth, 204 pCreateResource->pMipInfoList[0].TexelHeight, 205 pCreateResource->pMipInfoList[0].TexelDepth, 206 hResource.pDrvPrivate); 207 DebugPrintf(" ResourceDimension = %u\n", 208 pCreateResource->ResourceDimension); 209 DebugPrintf(" Usage = %u\n", 210 pCreateResource->Usage); 211 DebugPrintf(" BindFlags = 0x%x\n", 212 pCreateResource->BindFlags); 213 DebugPrintf(" MapFlags = 0x%x\n", 214 pCreateResource->MapFlags); 215 DebugPrintf(" MiscFlags = 0x%x\n", 216 pCreateResource->MiscFlags); 217 DebugPrintf(" Format = %s\n", 218 FormatToName(pCreateResource->Format)); 219 DebugPrintf(" SampleDesc.Count = %u\n", pCreateResource->SampleDesc.Count); 220 DebugPrintf(" SampleDesc.Quality = %u\n", pCreateResource->SampleDesc.Quality); 221 DebugPrintf(" MipLevels = %u\n", pCreateResource->MipLevels); 222 DebugPrintf(" ArraySize = %u\n", pCreateResource->ArraySize); 223 DebugPrintf(" pPrimaryDesc = %p\n", pCreateResource->pPrimaryDesc); 224 if (pCreateResource->pPrimaryDesc) { 225 DebugPrintf(" Flags = 0x%x\n", 226 pCreateResource->pPrimaryDesc->Flags); 227 DebugPrintf(" VidPnSourceId = %u\n", pCreateResource->pPrimaryDesc->VidPnSourceId); 228 DebugPrintf(" ModeDesc.Width = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Width); 229 DebugPrintf(" ModeDesc.Height = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Height); 230 DebugPrintf(" ModeDesc.Format = %u)\n", 231 pCreateResource->pPrimaryDesc->ModeDesc.Format); 232 DebugPrintf(" ModeDesc.RefreshRate.Numerator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Numerator); 233 DebugPrintf(" ModeDesc.RefreshRate.Denominator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Denominator); 234 DebugPrintf(" ModeDesc.ScanlineOrdering = %u\n", 235 pCreateResource->pPrimaryDesc->ModeDesc.ScanlineOrdering); 236 DebugPrintf(" ModeDesc.Rotation = %u\n", 237 pCreateResource->pPrimaryDesc->ModeDesc.Rotation); 238 DebugPrintf(" ModeDesc.Scaling = %u\n", 239 pCreateResource->pPrimaryDesc->ModeDesc.Scaling); 240 DebugPrintf(" DriverFlags = 0x%x\n", 241 pCreateResource->pPrimaryDesc->DriverFlags); 242 } 243 244 } 245 246 struct pipe_context *pipe = CastPipeContext(hDevice); 247 struct pipe_screen *screen = pipe->screen; 248 249 Resource *pResource = CastResource(hResource); 250 251 memset(pResource, 0, sizeof *pResource); 252 253#if 0 254 if (pCreateResource->pPrimaryDesc) { 255 pCreateResource->pPrimaryDesc->DriverFlags = DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT; 256 if (!(pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) { 257 // http://msdn.microsoft.com/en-us/library/windows/hardware/ff568846.aspx 258 SetError(hDevice, DXGI_DDI_ERR_UNSUPPORTED); 259 return; 260 } 261 } 262#endif 263 264 pResource->Format = pCreateResource->Format; 265 pResource->MipLevels = pCreateResource->MipLevels; 266 267 struct pipe_resource templat; 268 269 memset(&templat, 0, sizeof templat); 270 271 templat.target = translate_texture_target( pCreateResource->ResourceDimension, 272 pCreateResource->ArraySize ); 273 pResource->buffer = templat.target == PIPE_BUFFER; 274 275 if (pCreateResource->Format == DXGI_FORMAT_UNKNOWN) { 276 assert(pCreateResource->ResourceDimension == D3D10DDIRESOURCE_BUFFER); 277 templat.format = PIPE_FORMAT_R8_UINT; 278 } else { 279 BOOL bindDepthStencil = !!(pCreateResource->BindFlags & D3D10_DDI_BIND_DEPTH_STENCIL); 280 templat.format = FormatTranslate(pCreateResource->Format, bindDepthStencil); 281 } 282 283 templat.width0 = pCreateResource->pMipInfoList[0].TexelWidth; 284 templat.height0 = pCreateResource->pMipInfoList[0].TexelHeight; 285 templat.depth0 = pCreateResource->pMipInfoList[0].TexelDepth; 286 templat.array_size = pCreateResource->ArraySize; 287 templat.last_level = pCreateResource->MipLevels - 1; 288 templat.nr_samples = pCreateResource->SampleDesc.Count; 289 templat.nr_storage_samples = pCreateResource->SampleDesc.Count; 290 templat.bind = translate_resource_flags(pCreateResource->BindFlags); 291 templat.usage = translate_resource_usage(pCreateResource->Usage); 292 293 if (templat.target != PIPE_BUFFER) { 294 if (!screen->is_format_supported(screen, 295 templat.format, 296 templat.target, 297 templat.nr_samples, 298 templat.nr_storage_samples, 299 templat.bind)) { 300 debug_printf("%s: unsupported format %s\n", 301 __FUNCTION__, util_format_name(templat.format)); 302 SetError(hDevice, E_OUTOFMEMORY); 303 return; 304 } 305 } 306 307 pResource->resource = screen->resource_create(screen, &templat); 308 if (!pResource) { 309 DebugPrintf("%s: failed to create resource\n", __FUNCTION__); 310 SetError(hDevice, E_OUTOFMEMORY); 311 return; 312 } 313 314 pResource->NumSubResources = pCreateResource->MipLevels * pCreateResource->ArraySize; 315 pResource->transfers = (struct pipe_transfer **)calloc(pResource->NumSubResources, 316 sizeof *pResource->transfers); 317 318 if (pCreateResource->pInitialDataUP) { 319 if (pResource->buffer) { 320 assert(pResource->NumSubResources == 1); 321 const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP = 322 &pCreateResource->pInitialDataUP[0]; 323 324 unsigned level; 325 struct pipe_box box; 326 subResourceBox(pResource->resource, 0, &level, &box); 327 328 struct pipe_transfer *transfer; 329 void *map; 330 map = pipe->buffer_map(pipe, 331 pResource->resource, 332 level, 333 PIPE_MAP_WRITE | 334 PIPE_MAP_UNSYNCHRONIZED, 335 &box, 336 &transfer); 337 assert(map); 338 if (map) { 339 memcpy(map, pInitialDataUP->pSysMem, box.width); 340 pipe_buffer_unmap(pipe, transfer); 341 } 342 } else { 343 for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 344 const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP = 345 &pCreateResource->pInitialDataUP[SubResource]; 346 347 unsigned level; 348 struct pipe_box box; 349 subResourceBox(pResource->resource, SubResource, &level, &box); 350 351 struct pipe_transfer *transfer; 352 void *map; 353 map = pipe->texture_map(pipe, 354 pResource->resource, 355 level, 356 PIPE_MAP_WRITE | 357 PIPE_MAP_UNSYNCHRONIZED, 358 &box, 359 &transfer); 360 assert(map); 361 if (map) { 362 for (int z = 0; z < box.depth; ++z) { 363 ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 364 const ubyte *src = (const ubyte*)pInitialDataUP->pSysMem + z*pInitialDataUP->SysMemSlicePitch; 365 util_copy_rect(dst, 366 templat.format, 367 transfer->stride, 368 0, 0, box.width, box.height, 369 src, 370 pInitialDataUP->SysMemPitch, 371 0, 0); 372 } 373 pipe_texture_unmap(pipe, transfer); 374 } 375 } 376 } 377 } 378} 379 380 381/* 382 * ---------------------------------------------------------------------- 383 * 384 * CalcPrivateOpenedResourceSize -- 385 * 386 * The CalcPrivateOpenedResourceSize function determines the size 387 * of the user-mode display driver's private shared region of memory 388 * (that is, the size of internal driver structures, not the size 389 * of the resource video memory) for an opened resource. 390 * 391 * ---------------------------------------------------------------------- 392 */ 393 394SIZE_T APIENTRY 395CalcPrivateOpenedResourceSize(D3D10DDI_HDEVICE hDevice, // IN 396 __in const D3D10DDIARG_OPENRESOURCE *pOpenResource) // IN 397{ 398 return sizeof(Resource); 399} 400 401 402/* 403 * ---------------------------------------------------------------------- 404 * 405 * OpenResource -- 406 * 407 * The OpenResource function opens a shared resource. 408 * 409 * ---------------------------------------------------------------------- 410 */ 411 412void APIENTRY 413OpenResource(D3D10DDI_HDEVICE hDevice, // IN 414 __in const D3D10DDIARG_OPENRESOURCE *pOpenResource, // IN 415 D3D10DDI_HRESOURCE hResource, // IN 416 D3D10DDI_HRTRESOURCE hRTResource) // IN 417{ 418 LOG_UNSUPPORTED_ENTRYPOINT(); 419 SetError(hDevice, E_OUTOFMEMORY); 420} 421 422 423/* 424 * ---------------------------------------------------------------------- 425 * 426 * DestroyResource -- 427 * 428 * The DestroyResource function destroys the specified resource 429 * object. The resource object can be destoyed only if it is not 430 * currently bound to a display device, and if all views that 431 * refer to the resource are also destroyed. 432 * 433 * ---------------------------------------------------------------------- 434 */ 435 436 437void APIENTRY 438DestroyResource(D3D10DDI_HDEVICE hDevice, // IN 439 D3D10DDI_HRESOURCE hResource) // IN 440{ 441 LOG_ENTRYPOINT(); 442 443 struct pipe_context *pipe = CastPipeContext(hDevice); 444 Resource *pResource = CastResource(hResource); 445 446 if (pResource->so_target) { 447 pipe_so_target_reference(&pResource->so_target, NULL); 448 } 449 450 for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 451 if (pResource->transfers[SubResource]) { 452 if (pResource->buffer) { 453 pipe_buffer_unmap(pipe, pResource->transfers[SubResource]); 454 } else { 455 pipe_texture_unmap(pipe, pResource->transfers[SubResource]); 456 } 457 pResource->transfers[SubResource] = NULL; 458 } 459 } 460 free(pResource->transfers); 461 462 pipe_resource_reference(&pResource->resource, NULL); 463} 464 465 466/* 467 * ---------------------------------------------------------------------- 468 * 469 * ResourceMap -- 470 * 471 * The ResourceMap function maps a subresource of a resource. 472 * 473 * ---------------------------------------------------------------------- 474 */ 475 476void APIENTRY 477ResourceMap(D3D10DDI_HDEVICE hDevice, // IN 478 D3D10DDI_HRESOURCE hResource, // IN 479 UINT SubResource, // IN 480 D3D10_DDI_MAP DDIMap, // IN 481 UINT Flags, // IN 482 __out D3D10DDI_MAPPED_SUBRESOURCE *pMappedSubResource) // OUT 483{ 484 LOG_ENTRYPOINT(); 485 486 struct pipe_context *pipe = CastPipeContext(hDevice); 487 Resource *pResource = CastResource(hResource); 488 struct pipe_resource *resource = pResource->resource; 489 490 unsigned usage; 491 switch (DDIMap) { 492 case D3D10_DDI_MAP_READ: 493 usage = PIPE_MAP_READ; 494 break; 495 case D3D10_DDI_MAP_READWRITE: 496 usage = PIPE_MAP_READ | PIPE_MAP_WRITE; 497 break; 498 case D3D10_DDI_MAP_WRITE: 499 usage = PIPE_MAP_WRITE; 500 break; 501 case D3D10_DDI_MAP_WRITE_DISCARD: 502 usage = PIPE_MAP_WRITE; 503 if (resource->last_level == 0 && resource->array_size == 1) { 504 usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; 505 } else { 506 usage |= PIPE_MAP_DISCARD_RANGE; 507 } 508 break; 509 case D3D10_DDI_MAP_WRITE_NOOVERWRITE: 510 usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED; 511 break; 512 default: 513 assert(0); 514 return; 515 } 516 517 assert(SubResource < pResource->NumSubResources); 518 519 unsigned level; 520 struct pipe_box box; 521 subResourceBox(resource, SubResource, &level, &box); 522 523 assert(!pResource->transfers[SubResource]); 524 525 void *map; 526 if (pResource->buffer) { 527 map = pipe->buffer_map(pipe, 528 resource, 529 level, 530 usage, 531 &box, 532 &pResource->transfers[SubResource]); 533 } else { 534 map = pipe->texture_map(pipe, 535 resource, 536 level, 537 usage, 538 &box, 539 &pResource->transfers[SubResource]); 540 } 541 if (!map) { 542 DebugPrintf("%s: failed to map resource\n", __FUNCTION__); 543 SetError(hDevice, E_FAIL); 544 return; 545 } 546 547 pMappedSubResource->pData = map; 548 pMappedSubResource->RowPitch = pResource->transfers[SubResource]->stride; 549 pMappedSubResource->DepthPitch = pResource->transfers[SubResource]->layer_stride; 550} 551 552 553/* 554 * ---------------------------------------------------------------------- 555 * 556 * ResourceUnmap -- 557 * 558 * The ResourceUnmap function unmaps a subresource of a resource. 559 * 560 * ---------------------------------------------------------------------- 561 */ 562 563void APIENTRY 564ResourceUnmap(D3D10DDI_HDEVICE hDevice, // IN 565 D3D10DDI_HRESOURCE hResource, // IN 566 UINT SubResource) // IN 567{ 568 LOG_ENTRYPOINT(); 569 570 struct pipe_context *pipe = CastPipeContext(hDevice); 571 Resource *pResource = CastResource(hResource); 572 573 assert(SubResource < pResource->NumSubResources); 574 575 if (pResource->transfers[SubResource]) { 576 if (pResource->buffer) { 577 pipe_buffer_unmap(pipe, pResource->transfers[SubResource]); 578 } else { 579 pipe_texture_unmap(pipe, pResource->transfers[SubResource]); 580 } 581 pResource->transfers[SubResource] = NULL; 582 } 583} 584 585 586/* 587 *---------------------------------------------------------------------- 588 * 589 * areResourcesCompatible -- 590 * 591 * Check whether two resources can be safely passed to 592 * pipe_context::resource_copy_region method. 593 * 594 * Results: 595 * As above. 596 * 597 * Side effects: 598 * None. 599 * 600 *---------------------------------------------------------------------- 601 */ 602 603static bool 604areResourcesCompatible(const struct pipe_resource *src_resource, // IN 605 const struct pipe_resource *dst_resource) // IN 606{ 607 if (src_resource->format == dst_resource->format) { 608 /* 609 * Trivial. 610 */ 611 612 return TRUE; 613 } else if (src_resource->target == PIPE_BUFFER && 614 dst_resource->target == PIPE_BUFFER) { 615 /* 616 * Buffer resources are merely a collection of bytes. 617 */ 618 619 return TRUE; 620 } else { 621 /* 622 * Check whether the formats are supported by 623 * the resource_copy_region method. 624 */ 625 626 const struct util_format_description *src_format_desc; 627 const struct util_format_description *dst_format_desc; 628 629 src_format_desc = util_format_description(src_resource->format); 630 dst_format_desc = util_format_description(dst_resource->format); 631 632 assert(src_format_desc->block.width == dst_format_desc->block.width); 633 assert(src_format_desc->block.height == dst_format_desc->block.height); 634 assert(src_format_desc->block.bits == dst_format_desc->block.bits); 635 636 return util_is_format_compatible(src_format_desc, dst_format_desc); 637 } 638} 639 640 641/* 642 * ---------------------------------------------------------------------- 643 * 644 * ResourceCopy -- 645 * 646 * The ResourceCopy function copies an entire source 647 * resource to a destination resource. 648 * 649 * ---------------------------------------------------------------------- 650 */ 651 652void APIENTRY 653ResourceCopy(D3D10DDI_HDEVICE hDevice, // IN 654 D3D10DDI_HRESOURCE hDstResource, // IN 655 D3D10DDI_HRESOURCE hSrcResource) // IN 656{ 657 LOG_ENTRYPOINT(); 658 659 Device *pDevice = CastDevice(hDevice); 660 if (!CheckPredicate(pDevice)) { 661 return; 662 } 663 664 struct pipe_context *pipe = pDevice->pipe; 665 Resource *pDstResource = CastResource(hDstResource); 666 Resource *pSrcResource = CastResource(hSrcResource); 667 struct pipe_resource *dst_resource = pDstResource->resource; 668 struct pipe_resource *src_resource = pSrcResource->resource; 669 bool compatible; 670 671 assert(dst_resource->target == src_resource->target); 672 assert(dst_resource->width0 == src_resource->width0); 673 assert(dst_resource->height0 == src_resource->height0); 674 assert(dst_resource->depth0 == src_resource->depth0); 675 assert(dst_resource->last_level == src_resource->last_level); 676 assert(dst_resource->array_size == src_resource->array_size); 677 678 compatible = areResourcesCompatible(src_resource, dst_resource); 679 680 /* could also use one 3d copy for arrays */ 681 for (unsigned layer = 0; layer < dst_resource->array_size; ++layer) { 682 for (unsigned level = 0; level <= dst_resource->last_level; ++level) { 683 struct pipe_box box; 684 box.x = 0; 685 box.y = 0; 686 box.z = 0 + layer; 687 box.width = u_minify(dst_resource->width0, level); 688 box.height = u_minify(dst_resource->height0, level); 689 box.depth = u_minify(dst_resource->depth0, level); 690 691 if (compatible) { 692 pipe->resource_copy_region(pipe, 693 dst_resource, level, 694 0, 0, layer, 695 src_resource, level, 696 &box); 697 } else { 698 util_resource_copy_region(pipe, 699 dst_resource, level, 700 0, 0, layer, 701 src_resource, level, 702 &box); 703 } 704 } 705 } 706} 707 708 709/* 710 * ---------------------------------------------------------------------- 711 * 712 * ResourceCopyRegion -- 713 * 714 * The ResourceCopyRegion function copies a source subresource 715 * region to a location on a destination subresource. 716 * 717 * ---------------------------------------------------------------------- 718 */ 719 720void APIENTRY 721ResourceCopyRegion(D3D10DDI_HDEVICE hDevice, // IN 722 D3D10DDI_HRESOURCE hDstResource, // IN 723 UINT DstSubResource, // IN 724 UINT DstX, // IN 725 UINT DstY, // IN 726 UINT DstZ, // IN 727 D3D10DDI_HRESOURCE hSrcResource, // IN 728 UINT SrcSubResource, // IN 729 __in_opt const D3D10_DDI_BOX *pSrcBox) // IN (optional) 730{ 731 LOG_ENTRYPOINT(); 732 733 Device *pDevice = CastDevice(hDevice); 734 if (!CheckPredicate(pDevice)) { 735 return; 736 } 737 738 struct pipe_context *pipe = pDevice->pipe; 739 Resource *pDstResource = CastResource(hDstResource); 740 Resource *pSrcResource = CastResource(hSrcResource); 741 struct pipe_resource *dst_resource = pDstResource->resource; 742 struct pipe_resource *src_resource = pSrcResource->resource; 743 744 unsigned dst_level = DstSubResource % (dst_resource->last_level + 1); 745 unsigned dst_layer = DstSubResource / (dst_resource->last_level + 1); 746 unsigned src_level = SrcSubResource % (src_resource->last_level + 1); 747 unsigned src_layer = SrcSubResource / (src_resource->last_level + 1); 748 749 struct pipe_box src_box; 750 if (pSrcBox) { 751 src_box.x = pSrcBox->left; 752 src_box.y = pSrcBox->top; 753 src_box.z = pSrcBox->front + src_layer; 754 src_box.width = pSrcBox->right - pSrcBox->left; 755 src_box.height = pSrcBox->bottom - pSrcBox->top; 756 src_box.depth = pSrcBox->back - pSrcBox->front; 757 } else { 758 src_box.x = 0; 759 src_box.y = 0; 760 src_box.z = 0 + src_layer; 761 src_box.width = u_minify(src_resource->width0, src_level); 762 src_box.height = u_minify(src_resource->height0, src_level); 763 src_box.depth = u_minify(src_resource->depth0, src_level); 764 } 765 766 if (areResourcesCompatible(src_resource, dst_resource)) { 767 pipe->resource_copy_region(pipe, 768 dst_resource, dst_level, 769 DstX, DstY, DstZ + dst_layer, 770 src_resource, src_level, 771 &src_box); 772 } else { 773 util_resource_copy_region(pipe, 774 dst_resource, dst_level, 775 DstX, DstY, DstZ + dst_layer, 776 src_resource, src_level, 777 &src_box); 778 } 779} 780 781 782/* 783 * ---------------------------------------------------------------------- 784 * 785 * ResourceResolveSubResource -- 786 * 787 * The ResourceResolveSubResource function resolves 788 * multiple samples to one pixel. 789 * 790 * ---------------------------------------------------------------------- 791 */ 792 793void APIENTRY 794ResourceResolveSubResource(D3D10DDI_HDEVICE hDevice, // IN 795 D3D10DDI_HRESOURCE hDstResource, // IN 796 UINT DstSubResource, // IN 797 D3D10DDI_HRESOURCE hSrcResource, // IN 798 UINT SrcSubResource, // IN 799 DXGI_FORMAT ResolveFormat) // IN 800{ 801 LOG_UNSUPPORTED_ENTRYPOINT(); 802} 803 804 805/* 806 * ---------------------------------------------------------------------- 807 * 808 * ResourceIsStagingBusy -- 809 * 810 * The ResourceIsStagingBusy function determines whether a 811 * resource is currently being used by the graphics pipeline. 812 * 813 * ---------------------------------------------------------------------- 814 */ 815 816BOOL APIENTRY 817ResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice, // IN 818 D3D10DDI_HRESOURCE hResource) // IN 819{ 820 LOG_ENTRYPOINT(); 821 822 /* ignore */ 823 824 return FALSE; 825} 826 827 828/* 829 * ---------------------------------------------------------------------- 830 * 831 * ResourceReadAfterWriteHazard -- 832 * 833 * The ResourceReadAfterWriteHazard function informs the user-mode 834 * display driver that the specified resource was used as an output 835 * from the graphics processing unit (GPU) and that the resource 836 * will be used as an input to the GPU. 837 * 838 * ---------------------------------------------------------------------- 839 */ 840 841void APIENTRY 842ResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN 843 D3D10DDI_HRESOURCE hResource) // IN 844{ 845 LOG_ENTRYPOINT(); 846 847 /* Not actually necessary */ 848} 849 850 851/* 852 * ---------------------------------------------------------------------- 853 * 854 * ResourceUpdateSubResourceUP -- 855 * 856 * The ResourceUpdateSubresourceUP function updates a 857 * destination subresource region from a source 858 * system memory region. 859 * 860 * ---------------------------------------------------------------------- 861 */ 862 863void APIENTRY 864ResourceUpdateSubResourceUP(D3D10DDI_HDEVICE hDevice, // IN 865 D3D10DDI_HRESOURCE hDstResource, // IN 866 UINT DstSubResource, // IN 867 __in_opt const D3D10_DDI_BOX *pDstBox, // IN 868 __in const void *pSysMemUP, // IN 869 UINT RowPitch, // IN 870 UINT DepthPitch) // IN 871{ 872 LOG_ENTRYPOINT(); 873 874 Device *pDevice = CastDevice(hDevice); 875 if (!CheckPredicate(pDevice)) { 876 return; 877 } 878 879 struct pipe_context *pipe = pDevice->pipe; 880 Resource *pDstResource = CastResource(hDstResource); 881 struct pipe_resource *dst_resource = pDstResource->resource; 882 883 unsigned level; 884 struct pipe_box box; 885 886 if (pDstBox) { 887 UINT DstMipLevels = dst_resource->last_level + 1; 888 level = DstSubResource % DstMipLevels; 889 unsigned dst_layer = DstSubResource / DstMipLevels; 890 box.x = pDstBox->left; 891 box.y = pDstBox->top; 892 box.z = pDstBox->front + dst_layer; 893 box.width = pDstBox->right - pDstBox->left; 894 box.height = pDstBox->bottom - pDstBox->top; 895 box.depth = pDstBox->back - pDstBox->front; 896 } else { 897 subResourceBox(dst_resource, DstSubResource, &level, &box); 898 } 899 900 struct pipe_transfer *transfer; 901 void *map; 902 if (pDstResource->buffer) { 903 map = pipe->buffer_map(pipe, 904 dst_resource, 905 level, 906 PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE, 907 &box, 908 &transfer); 909 } else { 910 map = pipe->texture_map(pipe, 911 dst_resource, 912 level, 913 PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE, 914 &box, 915 &transfer); 916 } 917 assert(map); 918 if (map) { 919 for (int z = 0; z < box.depth; ++z) { 920 ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 921 const ubyte *src = (const ubyte*)pSysMemUP + z*DepthPitch; 922 util_copy_rect(dst, 923 dst_resource->format, 924 transfer->stride, 925 0, 0, box.width, box.height, 926 src, 927 RowPitch, 928 0, 0); 929 } 930 if (pDstResource->buffer) { 931 pipe_buffer_unmap(pipe, transfer); 932 } else { 933 pipe_texture_unmap(pipe, transfer); 934 } 935 } 936} 937 938