Resource.cpp revision 7ec681f3
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 274 if (pCreateResource->Format == DXGI_FORMAT_UNKNOWN) { 275 assert(pCreateResource->ResourceDimension == D3D10DDIRESOURCE_BUFFER); 276 templat.format = PIPE_FORMAT_R8_UINT; 277 } else { 278 BOOL bindDepthStencil = !!(pCreateResource->BindFlags & D3D10_DDI_BIND_DEPTH_STENCIL); 279 templat.format = FormatTranslate(pCreateResource->Format, bindDepthStencil); 280 } 281 282 templat.width0 = pCreateResource->pMipInfoList[0].TexelWidth; 283 templat.height0 = pCreateResource->pMipInfoList[0].TexelHeight; 284 templat.depth0 = pCreateResource->pMipInfoList[0].TexelDepth; 285 templat.array_size = pCreateResource->ArraySize; 286 templat.last_level = pCreateResource->MipLevels - 1; 287 templat.nr_samples = pCreateResource->SampleDesc.Count; 288 templat.nr_storage_samples = pCreateResource->SampleDesc.Count; 289 templat.bind = translate_resource_flags(pCreateResource->BindFlags); 290 templat.usage = translate_resource_usage(pCreateResource->Usage); 291 292 if (templat.target != PIPE_BUFFER) { 293 if (!screen->is_format_supported(screen, 294 templat.format, 295 templat.target, 296 templat.nr_samples, 297 templat.nr_storage_samples, 298 templat.bind)) { 299 debug_printf("%s: unsupported format %s\n", 300 __FUNCTION__, util_format_name(templat.format)); 301 SetError(hDevice, E_OUTOFMEMORY); 302 return; 303 } 304 } 305 306 pResource->resource = screen->resource_create(screen, &templat); 307 if (!pResource) { 308 DebugPrintf("%s: failed to create resource\n", __FUNCTION__); 309 SetError(hDevice, E_OUTOFMEMORY); 310 return; 311 } 312 313 pResource->NumSubResources = pCreateResource->MipLevels * pCreateResource->ArraySize; 314 pResource->transfers = (struct pipe_transfer **)calloc(pResource->NumSubResources, 315 sizeof *pResource->transfers); 316 317 if (pCreateResource->pInitialDataUP) { 318 for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 319 const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP = 320 &pCreateResource->pInitialDataUP[SubResource]; 321 322 unsigned level; 323 struct pipe_box box; 324 subResourceBox(pResource->resource, SubResource, &level, &box); 325 326 struct pipe_transfer *transfer; 327 void *map; 328 map = pipe->transfer_map(pipe, 329 pResource->resource, 330 level, 331 PIPE_MAP_WRITE | 332 PIPE_MAP_UNSYNCHRONIZED, 333 &box, 334 &transfer); 335 assert(map); 336 if (map) { 337 for (int z = 0; z < box.depth; ++z) { 338 ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 339 const ubyte *src = (const ubyte*)pInitialDataUP->pSysMem + z*pInitialDataUP->SysMemSlicePitch; 340 util_copy_rect(dst, 341 templat.format, 342 transfer->stride, 343 0, 0, box.width, box.height, 344 src, 345 pInitialDataUP->SysMemPitch, 346 0, 0); 347 } 348 pipe_transfer_unmap(pipe, transfer); 349 } 350 } 351 } 352} 353 354 355/* 356 * ---------------------------------------------------------------------- 357 * 358 * CalcPrivateOpenedResourceSize -- 359 * 360 * The CalcPrivateOpenedResourceSize function determines the size 361 * of the user-mode display driver's private shared region of memory 362 * (that is, the size of internal driver structures, not the size 363 * of the resource video memory) for an opened resource. 364 * 365 * ---------------------------------------------------------------------- 366 */ 367 368SIZE_T APIENTRY 369CalcPrivateOpenedResourceSize(D3D10DDI_HDEVICE hDevice, // IN 370 __in const D3D10DDIARG_OPENRESOURCE *pOpenResource) // IN 371{ 372 return sizeof(Resource); 373} 374 375 376/* 377 * ---------------------------------------------------------------------- 378 * 379 * OpenResource -- 380 * 381 * The OpenResource function opens a shared resource. 382 * 383 * ---------------------------------------------------------------------- 384 */ 385 386void APIENTRY 387OpenResource(D3D10DDI_HDEVICE hDevice, // IN 388 __in const D3D10DDIARG_OPENRESOURCE *pOpenResource, // IN 389 D3D10DDI_HRESOURCE hResource, // IN 390 D3D10DDI_HRTRESOURCE hRTResource) // IN 391{ 392 LOG_UNSUPPORTED_ENTRYPOINT(); 393 SetError(hDevice, E_OUTOFMEMORY); 394} 395 396 397/* 398 * ---------------------------------------------------------------------- 399 * 400 * DestroyResource -- 401 * 402 * The DestroyResource function destroys the specified resource 403 * object. The resource object can be destoyed only if it is not 404 * currently bound to a display device, and if all views that 405 * refer to the resource are also destroyed. 406 * 407 * ---------------------------------------------------------------------- 408 */ 409 410 411void APIENTRY 412DestroyResource(D3D10DDI_HDEVICE hDevice, // IN 413 D3D10DDI_HRESOURCE hResource) // IN 414{ 415 LOG_ENTRYPOINT(); 416 417 struct pipe_context *pipe = CastPipeContext(hDevice); 418 Resource *pResource = CastResource(hResource); 419 420 if (pResource->so_target) { 421 pipe_so_target_reference(&pResource->so_target, NULL); 422 } 423 424 for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 425 if (pResource->transfers[SubResource]) { 426 pipe_transfer_unmap(pipe, pResource->transfers[SubResource]); 427 pResource->transfers[SubResource] = NULL; 428 } 429 } 430 free(pResource->transfers); 431 432 pipe_resource_reference(&pResource->resource, NULL); 433} 434 435 436/* 437 * ---------------------------------------------------------------------- 438 * 439 * ResourceMap -- 440 * 441 * The ResourceMap function maps a subresource of a resource. 442 * 443 * ---------------------------------------------------------------------- 444 */ 445 446void APIENTRY 447ResourceMap(D3D10DDI_HDEVICE hDevice, // IN 448 D3D10DDI_HRESOURCE hResource, // IN 449 UINT SubResource, // IN 450 D3D10_DDI_MAP DDIMap, // IN 451 UINT Flags, // IN 452 __out D3D10DDI_MAPPED_SUBRESOURCE *pMappedSubResource) // OUT 453{ 454 LOG_ENTRYPOINT(); 455 456 struct pipe_context *pipe = CastPipeContext(hDevice); 457 Resource *pResource = CastResource(hResource); 458 struct pipe_resource *resource = pResource->resource; 459 460 unsigned usage; 461 switch (DDIMap) { 462 case D3D10_DDI_MAP_READ: 463 usage = PIPE_MAP_READ; 464 break; 465 case D3D10_DDI_MAP_READWRITE: 466 usage = PIPE_MAP_READ | PIPE_MAP_WRITE; 467 break; 468 case D3D10_DDI_MAP_WRITE: 469 usage = PIPE_MAP_WRITE; 470 break; 471 case D3D10_DDI_MAP_WRITE_DISCARD: 472 usage = PIPE_MAP_WRITE; 473 if (resource->last_level == 0 && resource->array_size == 1) { 474 usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; 475 } else { 476 usage |= PIPE_MAP_DISCARD_RANGE; 477 } 478 break; 479 case D3D10_DDI_MAP_WRITE_NOOVERWRITE: 480 usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED; 481 break; 482 default: 483 assert(0); 484 return; 485 } 486 487 assert(SubResource < pResource->NumSubResources); 488 489 unsigned level; 490 struct pipe_box box; 491 subResourceBox(resource, SubResource, &level, &box); 492 493 assert(!pResource->transfers[SubResource]); 494 495 void *map; 496 map = pipe->transfer_map(pipe, 497 resource, 498 level, 499 usage, 500 &box, 501 &pResource->transfers[SubResource]); 502 if (!map) { 503 DebugPrintf("%s: failed to map resource\n", __FUNCTION__); 504 SetError(hDevice, E_FAIL); 505 return; 506 } 507 508 pMappedSubResource->pData = map; 509 pMappedSubResource->RowPitch = pResource->transfers[SubResource]->stride; 510 pMappedSubResource->DepthPitch = pResource->transfers[SubResource]->layer_stride; 511} 512 513 514/* 515 * ---------------------------------------------------------------------- 516 * 517 * ResourceUnmap -- 518 * 519 * The ResourceUnmap function unmaps a subresource of a resource. 520 * 521 * ---------------------------------------------------------------------- 522 */ 523 524void APIENTRY 525ResourceUnmap(D3D10DDI_HDEVICE hDevice, // IN 526 D3D10DDI_HRESOURCE hResource, // IN 527 UINT SubResource) // IN 528{ 529 LOG_ENTRYPOINT(); 530 531 struct pipe_context *pipe = CastPipeContext(hDevice); 532 Resource *pResource = CastResource(hResource); 533 534 assert(SubResource < pResource->NumSubResources); 535 536 if (pResource->transfers[SubResource]) { 537 pipe_transfer_unmap(pipe, pResource->transfers[SubResource]); 538 pResource->transfers[SubResource] = NULL; 539 } 540} 541 542 543/* 544 *---------------------------------------------------------------------- 545 * 546 * areResourcesCompatible -- 547 * 548 * Check whether two resources can be safely passed to 549 * pipe_context::resource_copy_region method. 550 * 551 * Results: 552 * As above. 553 * 554 * Side effects: 555 * None. 556 * 557 *---------------------------------------------------------------------- 558 */ 559 560static bool 561areResourcesCompatible(const struct pipe_resource *src_resource, // IN 562 const struct pipe_resource *dst_resource) // IN 563{ 564 if (src_resource->format == dst_resource->format) { 565 /* 566 * Trivial. 567 */ 568 569 return TRUE; 570 } else if (src_resource->target == PIPE_BUFFER && 571 dst_resource->target == PIPE_BUFFER) { 572 /* 573 * Buffer resources are merely a collection of bytes. 574 */ 575 576 return TRUE; 577 } else { 578 /* 579 * Check whether the formats are supported by 580 * the resource_copy_region method. 581 */ 582 583 const struct util_format_description *src_format_desc; 584 const struct util_format_description *dst_format_desc; 585 586 src_format_desc = util_format_description(src_resource->format); 587 dst_format_desc = util_format_description(dst_resource->format); 588 589 assert(src_format_desc->block.width == dst_format_desc->block.width); 590 assert(src_format_desc->block.height == dst_format_desc->block.height); 591 assert(src_format_desc->block.bits == dst_format_desc->block.bits); 592 593 return util_is_format_compatible(src_format_desc, dst_format_desc); 594 } 595} 596 597 598/* 599 * ---------------------------------------------------------------------- 600 * 601 * ResourceCopy -- 602 * 603 * The ResourceCopy function copies an entire source 604 * resource to a destination resource. 605 * 606 * ---------------------------------------------------------------------- 607 */ 608 609void APIENTRY 610ResourceCopy(D3D10DDI_HDEVICE hDevice, // IN 611 D3D10DDI_HRESOURCE hDstResource, // IN 612 D3D10DDI_HRESOURCE hSrcResource) // IN 613{ 614 LOG_ENTRYPOINT(); 615 616 Device *pDevice = CastDevice(hDevice); 617 if (!CheckPredicate(pDevice)) { 618 return; 619 } 620 621 struct pipe_context *pipe = pDevice->pipe; 622 Resource *pDstResource = CastResource(hDstResource); 623 Resource *pSrcResource = CastResource(hSrcResource); 624 struct pipe_resource *dst_resource = pDstResource->resource; 625 struct pipe_resource *src_resource = pSrcResource->resource; 626 bool compatible; 627 628 assert(dst_resource->target == src_resource->target); 629 assert(dst_resource->width0 == src_resource->width0); 630 assert(dst_resource->height0 == src_resource->height0); 631 assert(dst_resource->depth0 == src_resource->depth0); 632 assert(dst_resource->last_level == src_resource->last_level); 633 assert(dst_resource->array_size == src_resource->array_size); 634 635 compatible = areResourcesCompatible(src_resource, dst_resource); 636 637 /* could also use one 3d copy for arrays */ 638 for (unsigned layer = 0; layer < dst_resource->array_size; ++layer) { 639 for (unsigned level = 0; level <= dst_resource->last_level; ++level) { 640 struct pipe_box box; 641 box.x = 0; 642 box.y = 0; 643 box.z = 0 + layer; 644 box.width = u_minify(dst_resource->width0, level); 645 box.height = u_minify(dst_resource->height0, level); 646 box.depth = u_minify(dst_resource->depth0, level); 647 648 if (compatible) { 649 pipe->resource_copy_region(pipe, 650 dst_resource, level, 651 0, 0, layer, 652 src_resource, level, 653 &box); 654 } else { 655 util_resource_copy_region(pipe, 656 dst_resource, level, 657 0, 0, layer, 658 src_resource, level, 659 &box); 660 } 661 } 662 } 663} 664 665 666/* 667 * ---------------------------------------------------------------------- 668 * 669 * ResourceCopyRegion -- 670 * 671 * The ResourceCopyRegion function copies a source subresource 672 * region to a location on a destination subresource. 673 * 674 * ---------------------------------------------------------------------- 675 */ 676 677void APIENTRY 678ResourceCopyRegion(D3D10DDI_HDEVICE hDevice, // IN 679 D3D10DDI_HRESOURCE hDstResource, // IN 680 UINT DstSubResource, // IN 681 UINT DstX, // IN 682 UINT DstY, // IN 683 UINT DstZ, // IN 684 D3D10DDI_HRESOURCE hSrcResource, // IN 685 UINT SrcSubResource, // IN 686 __in_opt const D3D10_DDI_BOX *pSrcBox) // IN (optional) 687{ 688 LOG_ENTRYPOINT(); 689 690 Device *pDevice = CastDevice(hDevice); 691 if (!CheckPredicate(pDevice)) { 692 return; 693 } 694 695 struct pipe_context *pipe = pDevice->pipe; 696 Resource *pDstResource = CastResource(hDstResource); 697 Resource *pSrcResource = CastResource(hSrcResource); 698 struct pipe_resource *dst_resource = pDstResource->resource; 699 struct pipe_resource *src_resource = pSrcResource->resource; 700 701 unsigned dst_level = DstSubResource % (dst_resource->last_level + 1); 702 unsigned dst_layer = DstSubResource / (dst_resource->last_level + 1); 703 unsigned src_level = SrcSubResource % (src_resource->last_level + 1); 704 unsigned src_layer = SrcSubResource / (src_resource->last_level + 1); 705 706 struct pipe_box src_box; 707 if (pSrcBox) { 708 src_box.x = pSrcBox->left; 709 src_box.y = pSrcBox->top; 710 src_box.z = pSrcBox->front + src_layer; 711 src_box.width = pSrcBox->right - pSrcBox->left; 712 src_box.height = pSrcBox->bottom - pSrcBox->top; 713 src_box.depth = pSrcBox->back - pSrcBox->front; 714 } else { 715 src_box.x = 0; 716 src_box.y = 0; 717 src_box.z = 0 + src_layer; 718 src_box.width = u_minify(src_resource->width0, src_level); 719 src_box.height = u_minify(src_resource->height0, src_level); 720 src_box.depth = u_minify(src_resource->depth0, src_level); 721 } 722 723 if (areResourcesCompatible(src_resource, dst_resource)) { 724 pipe->resource_copy_region(pipe, 725 dst_resource, dst_level, 726 DstX, DstY, DstZ + dst_layer, 727 src_resource, src_level, 728 &src_box); 729 } else { 730 util_resource_copy_region(pipe, 731 dst_resource, dst_level, 732 DstX, DstY, DstZ + dst_layer, 733 src_resource, src_level, 734 &src_box); 735 } 736} 737 738 739/* 740 * ---------------------------------------------------------------------- 741 * 742 * ResourceResolveSubResource -- 743 * 744 * The ResourceResolveSubResource function resolves 745 * multiple samples to one pixel. 746 * 747 * ---------------------------------------------------------------------- 748 */ 749 750void APIENTRY 751ResourceResolveSubResource(D3D10DDI_HDEVICE hDevice, // IN 752 D3D10DDI_HRESOURCE hDstResource, // IN 753 UINT DstSubResource, // IN 754 D3D10DDI_HRESOURCE hSrcResource, // IN 755 UINT SrcSubResource, // IN 756 DXGI_FORMAT ResolveFormat) // IN 757{ 758 LOG_UNSUPPORTED_ENTRYPOINT(); 759} 760 761 762/* 763 * ---------------------------------------------------------------------- 764 * 765 * ResourceIsStagingBusy -- 766 * 767 * The ResourceIsStagingBusy function determines whether a 768 * resource is currently being used by the graphics pipeline. 769 * 770 * ---------------------------------------------------------------------- 771 */ 772 773BOOL APIENTRY 774ResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice, // IN 775 D3D10DDI_HRESOURCE hResource) // IN 776{ 777 LOG_ENTRYPOINT(); 778 779 /* ignore */ 780 781 return FALSE; 782} 783 784 785/* 786 * ---------------------------------------------------------------------- 787 * 788 * ResourceReadAfterWriteHazard -- 789 * 790 * The ResourceReadAfterWriteHazard function informs the user-mode 791 * display driver that the specified resource was used as an output 792 * from the graphics processing unit (GPU) and that the resource 793 * will be used as an input to the GPU. 794 * 795 * ---------------------------------------------------------------------- 796 */ 797 798void APIENTRY 799ResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN 800 D3D10DDI_HRESOURCE hResource) // IN 801{ 802 LOG_ENTRYPOINT(); 803 804 /* Not actually necessary */ 805} 806 807 808/* 809 * ---------------------------------------------------------------------- 810 * 811 * ResourceUpdateSubResourceUP -- 812 * 813 * The ResourceUpdateSubresourceUP function updates a 814 * destination subresource region from a source 815 * system memory region. 816 * 817 * ---------------------------------------------------------------------- 818 */ 819 820void APIENTRY 821ResourceUpdateSubResourceUP(D3D10DDI_HDEVICE hDevice, // IN 822 D3D10DDI_HRESOURCE hDstResource, // IN 823 UINT DstSubResource, // IN 824 __in_opt const D3D10_DDI_BOX *pDstBox, // IN 825 __in const void *pSysMemUP, // IN 826 UINT RowPitch, // IN 827 UINT DepthPitch) // IN 828{ 829 LOG_ENTRYPOINT(); 830 831 Device *pDevice = CastDevice(hDevice); 832 if (!CheckPredicate(pDevice)) { 833 return; 834 } 835 836 struct pipe_context *pipe = pDevice->pipe; 837 struct pipe_resource *dst_resource = CastPipeResource(hDstResource); 838 839 unsigned level; 840 struct pipe_box box; 841 842 if (pDstBox) { 843 UINT DstMipLevels = dst_resource->last_level + 1; 844 level = DstSubResource % DstMipLevels; 845 unsigned dst_layer = DstSubResource / DstMipLevels; 846 box.x = pDstBox->left; 847 box.y = pDstBox->top; 848 box.z = pDstBox->front + dst_layer; 849 box.width = pDstBox->right - pDstBox->left; 850 box.height = pDstBox->bottom - pDstBox->top; 851 box.depth = pDstBox->back - pDstBox->front; 852 } else { 853 subResourceBox(dst_resource, DstSubResource, &level, &box); 854 } 855 856 struct pipe_transfer *transfer; 857 void *map; 858 map = pipe->transfer_map(pipe, 859 dst_resource, 860 level, 861 PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE, 862 &box, 863 &transfer); 864 assert(map); 865 if (map) { 866 for (int z = 0; z < box.depth; ++z) { 867 ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 868 const ubyte *src = (const ubyte*)pSysMemUP + z*DepthPitch; 869 util_copy_rect(dst, 870 dst_resource->format, 871 transfer->stride, 872 0, 0, box.width, box.height, 873 src, 874 RowPitch, 875 0, 0); 876 } 877 pipe_transfer_unmap(pipe, transfer); 878 } 879} 880 881