• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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