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
59 SIZE_T APIENTRY
CalcPrivateResourceSize(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATERESOURCE * pCreateResource)60 CalcPrivateResourceSize(D3D10DDI_HDEVICE hDevice, // IN
61 __in const D3D10DDIARG_CREATERESOURCE *pCreateResource) // IN
62 {
63 LOG_ENTRYPOINT();
64 return sizeof(Resource);
65 }
66
67
68 static unsigned
translate_resource_usage(unsigned usage)69 translate_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
95 static unsigned
translate_resource_flags(UINT flags)96 translate_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
125 static enum pipe_texture_target
translate_texture_target(D3D10DDIRESOURCE_TYPE ResourceDimension,UINT ArraySize)126 translate_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
151 static void
subResourceBox(struct pipe_resource * resource,UINT SubResource,unsigned * pLevel,struct pipe_box * pBox)152 subResourceBox(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
189 void APIENTRY
CreateResource(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_CREATERESOURCE * pCreateResource,D3D10DDI_HRESOURCE hResource,D3D10DDI_HRTRESOURCE hRTResource)190 CreateResource(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
368 SIZE_T APIENTRY
CalcPrivateOpenedResourceSize(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_OPENRESOURCE * pOpenResource)369 CalcPrivateOpenedResourceSize(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
386 void APIENTRY
OpenResource(D3D10DDI_HDEVICE hDevice,__in const D3D10DDIARG_OPENRESOURCE * pOpenResource,D3D10DDI_HRESOURCE hResource,D3D10DDI_HRTRESOURCE hRTResource)387 OpenResource(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
411 void APIENTRY
DestroyResource(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hResource)412 DestroyResource(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
446 void APIENTRY
ResourceMap(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hResource,UINT SubResource,D3D10_DDI_MAP DDIMap,UINT Flags,__out D3D10DDI_MAPPED_SUBRESOURCE * pMappedSubResource)447 ResourceMap(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
524 void APIENTRY
ResourceUnmap(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hResource,UINT SubResource)525 ResourceUnmap(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
560 static bool
areResourcesCompatible(const struct pipe_resource * src_resource,const struct pipe_resource * dst_resource)561 areResourcesCompatible(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
609 void APIENTRY
ResourceCopy(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hDstResource,D3D10DDI_HRESOURCE hSrcResource)610 ResourceCopy(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
677 void APIENTRY
ResourceCopyRegion(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hDstResource,UINT DstSubResource,UINT DstX,UINT DstY,UINT DstZ,D3D10DDI_HRESOURCE hSrcResource,UINT SrcSubResource,__in_opt const D3D10_DDI_BOX * pSrcBox)678 ResourceCopyRegion(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
750 void APIENTRY
ResourceResolveSubResource(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hDstResource,UINT DstSubResource,D3D10DDI_HRESOURCE hSrcResource,UINT SrcSubResource,DXGI_FORMAT ResolveFormat)751 ResourceResolveSubResource(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
773 BOOL APIENTRY
ResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hResource)774 ResourceIsStagingBusy(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
798 void APIENTRY
ResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hResource)799 ResourceReadAfterWriteHazard(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
820 void APIENTRY
ResourceUpdateSubResourceUP(D3D10DDI_HDEVICE hDevice,D3D10DDI_HRESOURCE hDstResource,UINT DstSubResource,__in_opt const D3D10_DDI_BOX * pDstBox,__in const void * pSysMemUP,UINT RowPitch,UINT DepthPitch)821 ResourceUpdateSubResourceUP(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