17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2012-2021 VMware, Inc. 47ec681f3Smrg * All Rights Reserved. 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the 87ec681f3Smrg * "Software"), to deal in the Software without restriction, including 97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 127ec681f3Smrg * the following conditions: 137ec681f3Smrg * 147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 177ec681f3Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 187ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 197ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 207ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 217ec681f3Smrg * 227ec681f3Smrg * The above copyright notice and this permission notice (including the 237ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 247ec681f3Smrg * of the Software. 257ec681f3Smrg * 267ec681f3Smrg **************************************************************************/ 277ec681f3Smrg 287ec681f3Smrg/* 297ec681f3Smrg * Resource.cpp -- 307ec681f3Smrg * Functions that manipulate GPU resources. 317ec681f3Smrg */ 327ec681f3Smrg 337ec681f3Smrg 347ec681f3Smrg#include "Resource.h" 357ec681f3Smrg#include "Format.h" 367ec681f3Smrg#include "State.h" 377ec681f3Smrg#include "Query.h" 387ec681f3Smrg 397ec681f3Smrg#include "Debug.h" 407ec681f3Smrg 417ec681f3Smrg#include "util/u_math.h" 427ec681f3Smrg#include "util/u_rect.h" 437ec681f3Smrg#include "util/u_surface.h" 447ec681f3Smrg 457ec681f3Smrg 467ec681f3Smrg/* 477ec681f3Smrg * ---------------------------------------------------------------------- 487ec681f3Smrg * 497ec681f3Smrg * CalcPrivateResourceSize -- 507ec681f3Smrg * 517ec681f3Smrg * The CalcPrivateResourceSize function determines the size of 527ec681f3Smrg * the user-mode display driver's private region of memory 537ec681f3Smrg * (that is, the size of internal driver structures, not the 547ec681f3Smrg * size of the resource video memory). 557ec681f3Smrg * 567ec681f3Smrg * ---------------------------------------------------------------------- 577ec681f3Smrg */ 587ec681f3Smrg 597ec681f3SmrgSIZE_T APIENTRY 607ec681f3SmrgCalcPrivateResourceSize(D3D10DDI_HDEVICE hDevice, // IN 617ec681f3Smrg __in const D3D10DDIARG_CREATERESOURCE *pCreateResource) // IN 627ec681f3Smrg{ 637ec681f3Smrg LOG_ENTRYPOINT(); 647ec681f3Smrg return sizeof(Resource); 657ec681f3Smrg} 667ec681f3Smrg 677ec681f3Smrg 687ec681f3Smrgstatic unsigned 697ec681f3Smrgtranslate_resource_usage( unsigned usage ) 707ec681f3Smrg{ 717ec681f3Smrg unsigned resource_usage = 0; 727ec681f3Smrg 737ec681f3Smrg switch (usage) { 747ec681f3Smrg case D3D10_DDI_USAGE_DEFAULT: 757ec681f3Smrg resource_usage = PIPE_USAGE_DEFAULT; 767ec681f3Smrg break; 777ec681f3Smrg case D3D10_DDI_USAGE_IMMUTABLE: 787ec681f3Smrg resource_usage = PIPE_USAGE_IMMUTABLE; 797ec681f3Smrg break; 807ec681f3Smrg case D3D10_DDI_USAGE_DYNAMIC: 817ec681f3Smrg resource_usage = PIPE_USAGE_DYNAMIC; 827ec681f3Smrg break; 837ec681f3Smrg case D3D10_DDI_USAGE_STAGING: 847ec681f3Smrg resource_usage = PIPE_USAGE_STAGING; 857ec681f3Smrg break; 867ec681f3Smrg default: 877ec681f3Smrg assert(0); 887ec681f3Smrg break; 897ec681f3Smrg } 907ec681f3Smrg 917ec681f3Smrg return resource_usage; 927ec681f3Smrg} 937ec681f3Smrg 947ec681f3Smrg 957ec681f3Smrgstatic unsigned 967ec681f3Smrgtranslate_resource_flags(UINT flags) 977ec681f3Smrg{ 987ec681f3Smrg unsigned bind = 0; 997ec681f3Smrg 1007ec681f3Smrg if (flags & D3D10_DDI_BIND_VERTEX_BUFFER) 1017ec681f3Smrg bind |= PIPE_BIND_VERTEX_BUFFER; 1027ec681f3Smrg 1037ec681f3Smrg if (flags & D3D10_DDI_BIND_INDEX_BUFFER) 1047ec681f3Smrg bind |= PIPE_BIND_INDEX_BUFFER; 1057ec681f3Smrg 1067ec681f3Smrg if (flags & D3D10_DDI_BIND_CONSTANT_BUFFER) 1077ec681f3Smrg bind |= PIPE_BIND_CONSTANT_BUFFER; 1087ec681f3Smrg 1097ec681f3Smrg if (flags & D3D10_DDI_BIND_SHADER_RESOURCE) 1107ec681f3Smrg bind |= PIPE_BIND_SAMPLER_VIEW; 1117ec681f3Smrg 1127ec681f3Smrg if (flags & D3D10_DDI_BIND_RENDER_TARGET) 1137ec681f3Smrg bind |= PIPE_BIND_RENDER_TARGET; 1147ec681f3Smrg 1157ec681f3Smrg if (flags & D3D10_DDI_BIND_DEPTH_STENCIL) 1167ec681f3Smrg bind |= PIPE_BIND_DEPTH_STENCIL; 1177ec681f3Smrg 1187ec681f3Smrg if (flags & D3D10_DDI_BIND_STREAM_OUTPUT) 1197ec681f3Smrg bind |= PIPE_BIND_STREAM_OUTPUT; 1207ec681f3Smrg 1217ec681f3Smrg return bind; 1227ec681f3Smrg} 1237ec681f3Smrg 1247ec681f3Smrg 1257ec681f3Smrgstatic enum pipe_texture_target 1267ec681f3Smrgtranslate_texture_target( D3D10DDIRESOURCE_TYPE ResourceDimension, 1277ec681f3Smrg UINT ArraySize) 1287ec681f3Smrg{ 1297ec681f3Smrg assert(ArraySize >= 1); 1307ec681f3Smrg switch(ResourceDimension) { 1317ec681f3Smrg case D3D10DDIRESOURCE_BUFFER: 1327ec681f3Smrg assert(ArraySize == 1); 1337ec681f3Smrg return PIPE_BUFFER; 1347ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE1D: 1357ec681f3Smrg return ArraySize > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D; 1367ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE2D: 1377ec681f3Smrg return ArraySize > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D; 1387ec681f3Smrg case D3D10DDIRESOURCE_TEXTURE3D: 1397ec681f3Smrg assert(ArraySize == 1); 1407ec681f3Smrg return PIPE_TEXTURE_3D; 1417ec681f3Smrg case D3D10DDIRESOURCE_TEXTURECUBE: 1427ec681f3Smrg assert(ArraySize % 6 == 0); 1437ec681f3Smrg return ArraySize > 6 ? PIPE_TEXTURE_CUBE_ARRAY : PIPE_TEXTURE_CUBE; 1447ec681f3Smrg default: 1457ec681f3Smrg assert(0); 1467ec681f3Smrg return PIPE_TEXTURE_1D; 1477ec681f3Smrg } 1487ec681f3Smrg} 1497ec681f3Smrg 1507ec681f3Smrg 1517ec681f3Smrgstatic void 1527ec681f3SmrgsubResourceBox(struct pipe_resource *resource, // IN 1537ec681f3Smrg UINT SubResource, // IN 1547ec681f3Smrg unsigned *pLevel, // OUT 1557ec681f3Smrg struct pipe_box *pBox) // OUT 1567ec681f3Smrg{ 1577ec681f3Smrg UINT MipLevels = resource->last_level + 1; 1587ec681f3Smrg unsigned layer; 1597ec681f3Smrg unsigned width; 1607ec681f3Smrg unsigned height; 1617ec681f3Smrg unsigned depth; 1627ec681f3Smrg 1637ec681f3Smrg *pLevel = SubResource % MipLevels; 1647ec681f3Smrg layer = SubResource / MipLevels; 1657ec681f3Smrg 1667ec681f3Smrg width = u_minify(resource->width0, *pLevel); 1677ec681f3Smrg height = u_minify(resource->height0, *pLevel); 1687ec681f3Smrg depth = u_minify(resource->depth0, *pLevel); 1697ec681f3Smrg 1707ec681f3Smrg pBox->x = 0; 1717ec681f3Smrg pBox->y = 0; 1727ec681f3Smrg pBox->z = 0 + layer; 1737ec681f3Smrg pBox->width = width; 1747ec681f3Smrg pBox->height = height; 1757ec681f3Smrg pBox->depth = depth; 1767ec681f3Smrg} 1777ec681f3Smrg 1787ec681f3Smrg 1797ec681f3Smrg/* 1807ec681f3Smrg * ---------------------------------------------------------------------- 1817ec681f3Smrg * 1827ec681f3Smrg * CreateResource -- 1837ec681f3Smrg * 1847ec681f3Smrg * The CreateResource function creates a resource. 1857ec681f3Smrg * 1867ec681f3Smrg * ---------------------------------------------------------------------- 1877ec681f3Smrg */ 1887ec681f3Smrg 1897ec681f3Smrgvoid APIENTRY 1907ec681f3SmrgCreateResource(D3D10DDI_HDEVICE hDevice, // IN 1917ec681f3Smrg __in const D3D10DDIARG_CREATERESOURCE *pCreateResource, // IN 1927ec681f3Smrg D3D10DDI_HRESOURCE hResource, // IN 1937ec681f3Smrg D3D10DDI_HRTRESOURCE hRTResource) // IN 1947ec681f3Smrg{ 1957ec681f3Smrg LOG_ENTRYPOINT(); 1967ec681f3Smrg 1977ec681f3Smrg if ((pCreateResource->MiscFlags & D3D10_DDI_RESOURCE_MISC_SHARED) || 1987ec681f3Smrg (pCreateResource->pPrimaryDesc && 1997ec681f3Smrg pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) { 2007ec681f3Smrg 2017ec681f3Smrg DebugPrintf("%s(%dx%dx%d hResource=%p)\n", 2027ec681f3Smrg __FUNCTION__, 2037ec681f3Smrg pCreateResource->pMipInfoList[0].TexelWidth, 2047ec681f3Smrg pCreateResource->pMipInfoList[0].TexelHeight, 2057ec681f3Smrg pCreateResource->pMipInfoList[0].TexelDepth, 2067ec681f3Smrg hResource.pDrvPrivate); 2077ec681f3Smrg DebugPrintf(" ResourceDimension = %u\n", 2087ec681f3Smrg pCreateResource->ResourceDimension); 2097ec681f3Smrg DebugPrintf(" Usage = %u\n", 2107ec681f3Smrg pCreateResource->Usage); 2117ec681f3Smrg DebugPrintf(" BindFlags = 0x%x\n", 2127ec681f3Smrg pCreateResource->BindFlags); 2137ec681f3Smrg DebugPrintf(" MapFlags = 0x%x\n", 2147ec681f3Smrg pCreateResource->MapFlags); 2157ec681f3Smrg DebugPrintf(" MiscFlags = 0x%x\n", 2167ec681f3Smrg pCreateResource->MiscFlags); 2177ec681f3Smrg DebugPrintf(" Format = %s\n", 2187ec681f3Smrg FormatToName(pCreateResource->Format)); 2197ec681f3Smrg DebugPrintf(" SampleDesc.Count = %u\n", pCreateResource->SampleDesc.Count); 2207ec681f3Smrg DebugPrintf(" SampleDesc.Quality = %u\n", pCreateResource->SampleDesc.Quality); 2217ec681f3Smrg DebugPrintf(" MipLevels = %u\n", pCreateResource->MipLevels); 2227ec681f3Smrg DebugPrintf(" ArraySize = %u\n", pCreateResource->ArraySize); 2237ec681f3Smrg DebugPrintf(" pPrimaryDesc = %p\n", pCreateResource->pPrimaryDesc); 2247ec681f3Smrg if (pCreateResource->pPrimaryDesc) { 2257ec681f3Smrg DebugPrintf(" Flags = 0x%x\n", 2267ec681f3Smrg pCreateResource->pPrimaryDesc->Flags); 2277ec681f3Smrg DebugPrintf(" VidPnSourceId = %u\n", pCreateResource->pPrimaryDesc->VidPnSourceId); 2287ec681f3Smrg DebugPrintf(" ModeDesc.Width = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Width); 2297ec681f3Smrg DebugPrintf(" ModeDesc.Height = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.Height); 2307ec681f3Smrg DebugPrintf(" ModeDesc.Format = %u)\n", 2317ec681f3Smrg pCreateResource->pPrimaryDesc->ModeDesc.Format); 2327ec681f3Smrg DebugPrintf(" ModeDesc.RefreshRate.Numerator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Numerator); 2337ec681f3Smrg DebugPrintf(" ModeDesc.RefreshRate.Denominator = %u\n", pCreateResource->pPrimaryDesc->ModeDesc.RefreshRate.Denominator); 2347ec681f3Smrg DebugPrintf(" ModeDesc.ScanlineOrdering = %u\n", 2357ec681f3Smrg pCreateResource->pPrimaryDesc->ModeDesc.ScanlineOrdering); 2367ec681f3Smrg DebugPrintf(" ModeDesc.Rotation = %u\n", 2377ec681f3Smrg pCreateResource->pPrimaryDesc->ModeDesc.Rotation); 2387ec681f3Smrg DebugPrintf(" ModeDesc.Scaling = %u\n", 2397ec681f3Smrg pCreateResource->pPrimaryDesc->ModeDesc.Scaling); 2407ec681f3Smrg DebugPrintf(" DriverFlags = 0x%x\n", 2417ec681f3Smrg pCreateResource->pPrimaryDesc->DriverFlags); 2427ec681f3Smrg } 2437ec681f3Smrg 2447ec681f3Smrg } 2457ec681f3Smrg 2467ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 2477ec681f3Smrg struct pipe_screen *screen = pipe->screen; 2487ec681f3Smrg 2497ec681f3Smrg Resource *pResource = CastResource(hResource); 2507ec681f3Smrg 2517ec681f3Smrg memset(pResource, 0, sizeof *pResource); 2527ec681f3Smrg 2537ec681f3Smrg#if 0 2547ec681f3Smrg if (pCreateResource->pPrimaryDesc) { 2557ec681f3Smrg pCreateResource->pPrimaryDesc->DriverFlags = DXGI_DDI_PRIMARY_DRIVER_FLAG_NO_SCANOUT; 2567ec681f3Smrg if (!(pCreateResource->pPrimaryDesc->DriverFlags & DXGI_DDI_PRIMARY_OPTIONAL)) { 2577ec681f3Smrg // http://msdn.microsoft.com/en-us/library/windows/hardware/ff568846.aspx 2587ec681f3Smrg SetError(hDevice, DXGI_DDI_ERR_UNSUPPORTED); 2597ec681f3Smrg return; 2607ec681f3Smrg } 2617ec681f3Smrg } 2627ec681f3Smrg#endif 2637ec681f3Smrg 2647ec681f3Smrg pResource->Format = pCreateResource->Format; 2657ec681f3Smrg pResource->MipLevels = pCreateResource->MipLevels; 2667ec681f3Smrg 2677ec681f3Smrg struct pipe_resource templat; 2687ec681f3Smrg 2697ec681f3Smrg memset(&templat, 0, sizeof templat); 2707ec681f3Smrg 2717ec681f3Smrg templat.target = translate_texture_target( pCreateResource->ResourceDimension, 2727ec681f3Smrg pCreateResource->ArraySize ); 2737ec681f3Smrg 2747ec681f3Smrg if (pCreateResource->Format == DXGI_FORMAT_UNKNOWN) { 2757ec681f3Smrg assert(pCreateResource->ResourceDimension == D3D10DDIRESOURCE_BUFFER); 2767ec681f3Smrg templat.format = PIPE_FORMAT_R8_UINT; 2777ec681f3Smrg } else { 2787ec681f3Smrg BOOL bindDepthStencil = !!(pCreateResource->BindFlags & D3D10_DDI_BIND_DEPTH_STENCIL); 2797ec681f3Smrg templat.format = FormatTranslate(pCreateResource->Format, bindDepthStencil); 2807ec681f3Smrg } 2817ec681f3Smrg 2827ec681f3Smrg templat.width0 = pCreateResource->pMipInfoList[0].TexelWidth; 2837ec681f3Smrg templat.height0 = pCreateResource->pMipInfoList[0].TexelHeight; 2847ec681f3Smrg templat.depth0 = pCreateResource->pMipInfoList[0].TexelDepth; 2857ec681f3Smrg templat.array_size = pCreateResource->ArraySize; 2867ec681f3Smrg templat.last_level = pCreateResource->MipLevels - 1; 2877ec681f3Smrg templat.nr_samples = pCreateResource->SampleDesc.Count; 2887ec681f3Smrg templat.nr_storage_samples = pCreateResource->SampleDesc.Count; 2897ec681f3Smrg templat.bind = translate_resource_flags(pCreateResource->BindFlags); 2907ec681f3Smrg templat.usage = translate_resource_usage(pCreateResource->Usage); 2917ec681f3Smrg 2927ec681f3Smrg if (templat.target != PIPE_BUFFER) { 2937ec681f3Smrg if (!screen->is_format_supported(screen, 2947ec681f3Smrg templat.format, 2957ec681f3Smrg templat.target, 2967ec681f3Smrg templat.nr_samples, 2977ec681f3Smrg templat.nr_storage_samples, 2987ec681f3Smrg templat.bind)) { 2997ec681f3Smrg debug_printf("%s: unsupported format %s\n", 3007ec681f3Smrg __FUNCTION__, util_format_name(templat.format)); 3017ec681f3Smrg SetError(hDevice, E_OUTOFMEMORY); 3027ec681f3Smrg return; 3037ec681f3Smrg } 3047ec681f3Smrg } 3057ec681f3Smrg 3067ec681f3Smrg pResource->resource = screen->resource_create(screen, &templat); 3077ec681f3Smrg if (!pResource) { 3087ec681f3Smrg DebugPrintf("%s: failed to create resource\n", __FUNCTION__); 3097ec681f3Smrg SetError(hDevice, E_OUTOFMEMORY); 3107ec681f3Smrg return; 3117ec681f3Smrg } 3127ec681f3Smrg 3137ec681f3Smrg pResource->NumSubResources = pCreateResource->MipLevels * pCreateResource->ArraySize; 3147ec681f3Smrg pResource->transfers = (struct pipe_transfer **)calloc(pResource->NumSubResources, 3157ec681f3Smrg sizeof *pResource->transfers); 3167ec681f3Smrg 3177ec681f3Smrg if (pCreateResource->pInitialDataUP) { 3187ec681f3Smrg for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 3197ec681f3Smrg const D3D10_DDIARG_SUBRESOURCE_UP* pInitialDataUP = 3207ec681f3Smrg &pCreateResource->pInitialDataUP[SubResource]; 3217ec681f3Smrg 3227ec681f3Smrg unsigned level; 3237ec681f3Smrg struct pipe_box box; 3247ec681f3Smrg subResourceBox(pResource->resource, SubResource, &level, &box); 3257ec681f3Smrg 3267ec681f3Smrg struct pipe_transfer *transfer; 3277ec681f3Smrg void *map; 3287ec681f3Smrg map = pipe->transfer_map(pipe, 3297ec681f3Smrg pResource->resource, 3307ec681f3Smrg level, 3317ec681f3Smrg PIPE_MAP_WRITE | 3327ec681f3Smrg PIPE_MAP_UNSYNCHRONIZED, 3337ec681f3Smrg &box, 3347ec681f3Smrg &transfer); 3357ec681f3Smrg assert(map); 3367ec681f3Smrg if (map) { 3377ec681f3Smrg for (int z = 0; z < box.depth; ++z) { 3387ec681f3Smrg ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 3397ec681f3Smrg const ubyte *src = (const ubyte*)pInitialDataUP->pSysMem + z*pInitialDataUP->SysMemSlicePitch; 3407ec681f3Smrg util_copy_rect(dst, 3417ec681f3Smrg templat.format, 3427ec681f3Smrg transfer->stride, 3437ec681f3Smrg 0, 0, box.width, box.height, 3447ec681f3Smrg src, 3457ec681f3Smrg pInitialDataUP->SysMemPitch, 3467ec681f3Smrg 0, 0); 3477ec681f3Smrg } 3487ec681f3Smrg pipe_transfer_unmap(pipe, transfer); 3497ec681f3Smrg } 3507ec681f3Smrg } 3517ec681f3Smrg } 3527ec681f3Smrg} 3537ec681f3Smrg 3547ec681f3Smrg 3557ec681f3Smrg/* 3567ec681f3Smrg * ---------------------------------------------------------------------- 3577ec681f3Smrg * 3587ec681f3Smrg * CalcPrivateOpenedResourceSize -- 3597ec681f3Smrg * 3607ec681f3Smrg * The CalcPrivateOpenedResourceSize function determines the size 3617ec681f3Smrg * of the user-mode display driver's private shared region of memory 3627ec681f3Smrg * (that is, the size of internal driver structures, not the size 3637ec681f3Smrg * of the resource video memory) for an opened resource. 3647ec681f3Smrg * 3657ec681f3Smrg * ---------------------------------------------------------------------- 3667ec681f3Smrg */ 3677ec681f3Smrg 3687ec681f3SmrgSIZE_T APIENTRY 3697ec681f3SmrgCalcPrivateOpenedResourceSize(D3D10DDI_HDEVICE hDevice, // IN 3707ec681f3Smrg __in const D3D10DDIARG_OPENRESOURCE *pOpenResource) // IN 3717ec681f3Smrg{ 3727ec681f3Smrg return sizeof(Resource); 3737ec681f3Smrg} 3747ec681f3Smrg 3757ec681f3Smrg 3767ec681f3Smrg/* 3777ec681f3Smrg * ---------------------------------------------------------------------- 3787ec681f3Smrg * 3797ec681f3Smrg * OpenResource -- 3807ec681f3Smrg * 3817ec681f3Smrg * The OpenResource function opens a shared resource. 3827ec681f3Smrg * 3837ec681f3Smrg * ---------------------------------------------------------------------- 3847ec681f3Smrg */ 3857ec681f3Smrg 3867ec681f3Smrgvoid APIENTRY 3877ec681f3SmrgOpenResource(D3D10DDI_HDEVICE hDevice, // IN 3887ec681f3Smrg __in const D3D10DDIARG_OPENRESOURCE *pOpenResource, // IN 3897ec681f3Smrg D3D10DDI_HRESOURCE hResource, // IN 3907ec681f3Smrg D3D10DDI_HRTRESOURCE hRTResource) // IN 3917ec681f3Smrg{ 3927ec681f3Smrg LOG_UNSUPPORTED_ENTRYPOINT(); 3937ec681f3Smrg SetError(hDevice, E_OUTOFMEMORY); 3947ec681f3Smrg} 3957ec681f3Smrg 3967ec681f3Smrg 3977ec681f3Smrg/* 3987ec681f3Smrg * ---------------------------------------------------------------------- 3997ec681f3Smrg * 4007ec681f3Smrg * DestroyResource -- 4017ec681f3Smrg * 4027ec681f3Smrg * The DestroyResource function destroys the specified resource 4037ec681f3Smrg * object. The resource object can be destoyed only if it is not 4047ec681f3Smrg * currently bound to a display device, and if all views that 4057ec681f3Smrg * refer to the resource are also destroyed. 4067ec681f3Smrg * 4077ec681f3Smrg * ---------------------------------------------------------------------- 4087ec681f3Smrg */ 4097ec681f3Smrg 4107ec681f3Smrg 4117ec681f3Smrgvoid APIENTRY 4127ec681f3SmrgDestroyResource(D3D10DDI_HDEVICE hDevice, // IN 4137ec681f3Smrg D3D10DDI_HRESOURCE hResource) // IN 4147ec681f3Smrg{ 4157ec681f3Smrg LOG_ENTRYPOINT(); 4167ec681f3Smrg 4177ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 4187ec681f3Smrg Resource *pResource = CastResource(hResource); 4197ec681f3Smrg 4207ec681f3Smrg if (pResource->so_target) { 4217ec681f3Smrg pipe_so_target_reference(&pResource->so_target, NULL); 4227ec681f3Smrg } 4237ec681f3Smrg 4247ec681f3Smrg for (UINT SubResource = 0; SubResource < pResource->NumSubResources; ++SubResource) { 4257ec681f3Smrg if (pResource->transfers[SubResource]) { 4267ec681f3Smrg pipe_transfer_unmap(pipe, pResource->transfers[SubResource]); 4277ec681f3Smrg pResource->transfers[SubResource] = NULL; 4287ec681f3Smrg } 4297ec681f3Smrg } 4307ec681f3Smrg free(pResource->transfers); 4317ec681f3Smrg 4327ec681f3Smrg pipe_resource_reference(&pResource->resource, NULL); 4337ec681f3Smrg} 4347ec681f3Smrg 4357ec681f3Smrg 4367ec681f3Smrg/* 4377ec681f3Smrg * ---------------------------------------------------------------------- 4387ec681f3Smrg * 4397ec681f3Smrg * ResourceMap -- 4407ec681f3Smrg * 4417ec681f3Smrg * The ResourceMap function maps a subresource of a resource. 4427ec681f3Smrg * 4437ec681f3Smrg * ---------------------------------------------------------------------- 4447ec681f3Smrg */ 4457ec681f3Smrg 4467ec681f3Smrgvoid APIENTRY 4477ec681f3SmrgResourceMap(D3D10DDI_HDEVICE hDevice, // IN 4487ec681f3Smrg D3D10DDI_HRESOURCE hResource, // IN 4497ec681f3Smrg UINT SubResource, // IN 4507ec681f3Smrg D3D10_DDI_MAP DDIMap, // IN 4517ec681f3Smrg UINT Flags, // IN 4527ec681f3Smrg __out D3D10DDI_MAPPED_SUBRESOURCE *pMappedSubResource) // OUT 4537ec681f3Smrg{ 4547ec681f3Smrg LOG_ENTRYPOINT(); 4557ec681f3Smrg 4567ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 4577ec681f3Smrg Resource *pResource = CastResource(hResource); 4587ec681f3Smrg struct pipe_resource *resource = pResource->resource; 4597ec681f3Smrg 4607ec681f3Smrg unsigned usage; 4617ec681f3Smrg switch (DDIMap) { 4627ec681f3Smrg case D3D10_DDI_MAP_READ: 4637ec681f3Smrg usage = PIPE_MAP_READ; 4647ec681f3Smrg break; 4657ec681f3Smrg case D3D10_DDI_MAP_READWRITE: 4667ec681f3Smrg usage = PIPE_MAP_READ | PIPE_MAP_WRITE; 4677ec681f3Smrg break; 4687ec681f3Smrg case D3D10_DDI_MAP_WRITE: 4697ec681f3Smrg usage = PIPE_MAP_WRITE; 4707ec681f3Smrg break; 4717ec681f3Smrg case D3D10_DDI_MAP_WRITE_DISCARD: 4727ec681f3Smrg usage = PIPE_MAP_WRITE; 4737ec681f3Smrg if (resource->last_level == 0 && resource->array_size == 1) { 4747ec681f3Smrg usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; 4757ec681f3Smrg } else { 4767ec681f3Smrg usage |= PIPE_MAP_DISCARD_RANGE; 4777ec681f3Smrg } 4787ec681f3Smrg break; 4797ec681f3Smrg case D3D10_DDI_MAP_WRITE_NOOVERWRITE: 4807ec681f3Smrg usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED; 4817ec681f3Smrg break; 4827ec681f3Smrg default: 4837ec681f3Smrg assert(0); 4847ec681f3Smrg return; 4857ec681f3Smrg } 4867ec681f3Smrg 4877ec681f3Smrg assert(SubResource < pResource->NumSubResources); 4887ec681f3Smrg 4897ec681f3Smrg unsigned level; 4907ec681f3Smrg struct pipe_box box; 4917ec681f3Smrg subResourceBox(resource, SubResource, &level, &box); 4927ec681f3Smrg 4937ec681f3Smrg assert(!pResource->transfers[SubResource]); 4947ec681f3Smrg 4957ec681f3Smrg void *map; 4967ec681f3Smrg map = pipe->transfer_map(pipe, 4977ec681f3Smrg resource, 4987ec681f3Smrg level, 4997ec681f3Smrg usage, 5007ec681f3Smrg &box, 5017ec681f3Smrg &pResource->transfers[SubResource]); 5027ec681f3Smrg if (!map) { 5037ec681f3Smrg DebugPrintf("%s: failed to map resource\n", __FUNCTION__); 5047ec681f3Smrg SetError(hDevice, E_FAIL); 5057ec681f3Smrg return; 5067ec681f3Smrg } 5077ec681f3Smrg 5087ec681f3Smrg pMappedSubResource->pData = map; 5097ec681f3Smrg pMappedSubResource->RowPitch = pResource->transfers[SubResource]->stride; 5107ec681f3Smrg pMappedSubResource->DepthPitch = pResource->transfers[SubResource]->layer_stride; 5117ec681f3Smrg} 5127ec681f3Smrg 5137ec681f3Smrg 5147ec681f3Smrg/* 5157ec681f3Smrg * ---------------------------------------------------------------------- 5167ec681f3Smrg * 5177ec681f3Smrg * ResourceUnmap -- 5187ec681f3Smrg * 5197ec681f3Smrg * The ResourceUnmap function unmaps a subresource of a resource. 5207ec681f3Smrg * 5217ec681f3Smrg * ---------------------------------------------------------------------- 5227ec681f3Smrg */ 5237ec681f3Smrg 5247ec681f3Smrgvoid APIENTRY 5257ec681f3SmrgResourceUnmap(D3D10DDI_HDEVICE hDevice, // IN 5267ec681f3Smrg D3D10DDI_HRESOURCE hResource, // IN 5277ec681f3Smrg UINT SubResource) // IN 5287ec681f3Smrg{ 5297ec681f3Smrg LOG_ENTRYPOINT(); 5307ec681f3Smrg 5317ec681f3Smrg struct pipe_context *pipe = CastPipeContext(hDevice); 5327ec681f3Smrg Resource *pResource = CastResource(hResource); 5337ec681f3Smrg 5347ec681f3Smrg assert(SubResource < pResource->NumSubResources); 5357ec681f3Smrg 5367ec681f3Smrg if (pResource->transfers[SubResource]) { 5377ec681f3Smrg pipe_transfer_unmap(pipe, pResource->transfers[SubResource]); 5387ec681f3Smrg pResource->transfers[SubResource] = NULL; 5397ec681f3Smrg } 5407ec681f3Smrg} 5417ec681f3Smrg 5427ec681f3Smrg 5437ec681f3Smrg/* 5447ec681f3Smrg *---------------------------------------------------------------------- 5457ec681f3Smrg * 5467ec681f3Smrg * areResourcesCompatible -- 5477ec681f3Smrg * 5487ec681f3Smrg * Check whether two resources can be safely passed to 5497ec681f3Smrg * pipe_context::resource_copy_region method. 5507ec681f3Smrg * 5517ec681f3Smrg * Results: 5527ec681f3Smrg * As above. 5537ec681f3Smrg * 5547ec681f3Smrg * Side effects: 5557ec681f3Smrg * None. 5567ec681f3Smrg * 5577ec681f3Smrg *---------------------------------------------------------------------- 5587ec681f3Smrg */ 5597ec681f3Smrg 5607ec681f3Smrgstatic bool 5617ec681f3SmrgareResourcesCompatible(const struct pipe_resource *src_resource, // IN 5627ec681f3Smrg const struct pipe_resource *dst_resource) // IN 5637ec681f3Smrg{ 5647ec681f3Smrg if (src_resource->format == dst_resource->format) { 5657ec681f3Smrg /* 5667ec681f3Smrg * Trivial. 5677ec681f3Smrg */ 5687ec681f3Smrg 5697ec681f3Smrg return TRUE; 5707ec681f3Smrg } else if (src_resource->target == PIPE_BUFFER && 5717ec681f3Smrg dst_resource->target == PIPE_BUFFER) { 5727ec681f3Smrg /* 5737ec681f3Smrg * Buffer resources are merely a collection of bytes. 5747ec681f3Smrg */ 5757ec681f3Smrg 5767ec681f3Smrg return TRUE; 5777ec681f3Smrg } else { 5787ec681f3Smrg /* 5797ec681f3Smrg * Check whether the formats are supported by 5807ec681f3Smrg * the resource_copy_region method. 5817ec681f3Smrg */ 5827ec681f3Smrg 5837ec681f3Smrg const struct util_format_description *src_format_desc; 5847ec681f3Smrg const struct util_format_description *dst_format_desc; 5857ec681f3Smrg 5867ec681f3Smrg src_format_desc = util_format_description(src_resource->format); 5877ec681f3Smrg dst_format_desc = util_format_description(dst_resource->format); 5887ec681f3Smrg 5897ec681f3Smrg assert(src_format_desc->block.width == dst_format_desc->block.width); 5907ec681f3Smrg assert(src_format_desc->block.height == dst_format_desc->block.height); 5917ec681f3Smrg assert(src_format_desc->block.bits == dst_format_desc->block.bits); 5927ec681f3Smrg 5937ec681f3Smrg return util_is_format_compatible(src_format_desc, dst_format_desc); 5947ec681f3Smrg } 5957ec681f3Smrg} 5967ec681f3Smrg 5977ec681f3Smrg 5987ec681f3Smrg/* 5997ec681f3Smrg * ---------------------------------------------------------------------- 6007ec681f3Smrg * 6017ec681f3Smrg * ResourceCopy -- 6027ec681f3Smrg * 6037ec681f3Smrg * The ResourceCopy function copies an entire source 6047ec681f3Smrg * resource to a destination resource. 6057ec681f3Smrg * 6067ec681f3Smrg * ---------------------------------------------------------------------- 6077ec681f3Smrg */ 6087ec681f3Smrg 6097ec681f3Smrgvoid APIENTRY 6107ec681f3SmrgResourceCopy(D3D10DDI_HDEVICE hDevice, // IN 6117ec681f3Smrg D3D10DDI_HRESOURCE hDstResource, // IN 6127ec681f3Smrg D3D10DDI_HRESOURCE hSrcResource) // IN 6137ec681f3Smrg{ 6147ec681f3Smrg LOG_ENTRYPOINT(); 6157ec681f3Smrg 6167ec681f3Smrg Device *pDevice = CastDevice(hDevice); 6177ec681f3Smrg if (!CheckPredicate(pDevice)) { 6187ec681f3Smrg return; 6197ec681f3Smrg } 6207ec681f3Smrg 6217ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 6227ec681f3Smrg Resource *pDstResource = CastResource(hDstResource); 6237ec681f3Smrg Resource *pSrcResource = CastResource(hSrcResource); 6247ec681f3Smrg struct pipe_resource *dst_resource = pDstResource->resource; 6257ec681f3Smrg struct pipe_resource *src_resource = pSrcResource->resource; 6267ec681f3Smrg bool compatible; 6277ec681f3Smrg 6287ec681f3Smrg assert(dst_resource->target == src_resource->target); 6297ec681f3Smrg assert(dst_resource->width0 == src_resource->width0); 6307ec681f3Smrg assert(dst_resource->height0 == src_resource->height0); 6317ec681f3Smrg assert(dst_resource->depth0 == src_resource->depth0); 6327ec681f3Smrg assert(dst_resource->last_level == src_resource->last_level); 6337ec681f3Smrg assert(dst_resource->array_size == src_resource->array_size); 6347ec681f3Smrg 6357ec681f3Smrg compatible = areResourcesCompatible(src_resource, dst_resource); 6367ec681f3Smrg 6377ec681f3Smrg /* could also use one 3d copy for arrays */ 6387ec681f3Smrg for (unsigned layer = 0; layer < dst_resource->array_size; ++layer) { 6397ec681f3Smrg for (unsigned level = 0; level <= dst_resource->last_level; ++level) { 6407ec681f3Smrg struct pipe_box box; 6417ec681f3Smrg box.x = 0; 6427ec681f3Smrg box.y = 0; 6437ec681f3Smrg box.z = 0 + layer; 6447ec681f3Smrg box.width = u_minify(dst_resource->width0, level); 6457ec681f3Smrg box.height = u_minify(dst_resource->height0, level); 6467ec681f3Smrg box.depth = u_minify(dst_resource->depth0, level); 6477ec681f3Smrg 6487ec681f3Smrg if (compatible) { 6497ec681f3Smrg pipe->resource_copy_region(pipe, 6507ec681f3Smrg dst_resource, level, 6517ec681f3Smrg 0, 0, layer, 6527ec681f3Smrg src_resource, level, 6537ec681f3Smrg &box); 6547ec681f3Smrg } else { 6557ec681f3Smrg util_resource_copy_region(pipe, 6567ec681f3Smrg dst_resource, level, 6577ec681f3Smrg 0, 0, layer, 6587ec681f3Smrg src_resource, level, 6597ec681f3Smrg &box); 6607ec681f3Smrg } 6617ec681f3Smrg } 6627ec681f3Smrg } 6637ec681f3Smrg} 6647ec681f3Smrg 6657ec681f3Smrg 6667ec681f3Smrg/* 6677ec681f3Smrg * ---------------------------------------------------------------------- 6687ec681f3Smrg * 6697ec681f3Smrg * ResourceCopyRegion -- 6707ec681f3Smrg * 6717ec681f3Smrg * The ResourceCopyRegion function copies a source subresource 6727ec681f3Smrg * region to a location on a destination subresource. 6737ec681f3Smrg * 6747ec681f3Smrg * ---------------------------------------------------------------------- 6757ec681f3Smrg */ 6767ec681f3Smrg 6777ec681f3Smrgvoid APIENTRY 6787ec681f3SmrgResourceCopyRegion(D3D10DDI_HDEVICE hDevice, // IN 6797ec681f3Smrg D3D10DDI_HRESOURCE hDstResource, // IN 6807ec681f3Smrg UINT DstSubResource, // IN 6817ec681f3Smrg UINT DstX, // IN 6827ec681f3Smrg UINT DstY, // IN 6837ec681f3Smrg UINT DstZ, // IN 6847ec681f3Smrg D3D10DDI_HRESOURCE hSrcResource, // IN 6857ec681f3Smrg UINT SrcSubResource, // IN 6867ec681f3Smrg __in_opt const D3D10_DDI_BOX *pSrcBox) // IN (optional) 6877ec681f3Smrg{ 6887ec681f3Smrg LOG_ENTRYPOINT(); 6897ec681f3Smrg 6907ec681f3Smrg Device *pDevice = CastDevice(hDevice); 6917ec681f3Smrg if (!CheckPredicate(pDevice)) { 6927ec681f3Smrg return; 6937ec681f3Smrg } 6947ec681f3Smrg 6957ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 6967ec681f3Smrg Resource *pDstResource = CastResource(hDstResource); 6977ec681f3Smrg Resource *pSrcResource = CastResource(hSrcResource); 6987ec681f3Smrg struct pipe_resource *dst_resource = pDstResource->resource; 6997ec681f3Smrg struct pipe_resource *src_resource = pSrcResource->resource; 7007ec681f3Smrg 7017ec681f3Smrg unsigned dst_level = DstSubResource % (dst_resource->last_level + 1); 7027ec681f3Smrg unsigned dst_layer = DstSubResource / (dst_resource->last_level + 1); 7037ec681f3Smrg unsigned src_level = SrcSubResource % (src_resource->last_level + 1); 7047ec681f3Smrg unsigned src_layer = SrcSubResource / (src_resource->last_level + 1); 7057ec681f3Smrg 7067ec681f3Smrg struct pipe_box src_box; 7077ec681f3Smrg if (pSrcBox) { 7087ec681f3Smrg src_box.x = pSrcBox->left; 7097ec681f3Smrg src_box.y = pSrcBox->top; 7107ec681f3Smrg src_box.z = pSrcBox->front + src_layer; 7117ec681f3Smrg src_box.width = pSrcBox->right - pSrcBox->left; 7127ec681f3Smrg src_box.height = pSrcBox->bottom - pSrcBox->top; 7137ec681f3Smrg src_box.depth = pSrcBox->back - pSrcBox->front; 7147ec681f3Smrg } else { 7157ec681f3Smrg src_box.x = 0; 7167ec681f3Smrg src_box.y = 0; 7177ec681f3Smrg src_box.z = 0 + src_layer; 7187ec681f3Smrg src_box.width = u_minify(src_resource->width0, src_level); 7197ec681f3Smrg src_box.height = u_minify(src_resource->height0, src_level); 7207ec681f3Smrg src_box.depth = u_minify(src_resource->depth0, src_level); 7217ec681f3Smrg } 7227ec681f3Smrg 7237ec681f3Smrg if (areResourcesCompatible(src_resource, dst_resource)) { 7247ec681f3Smrg pipe->resource_copy_region(pipe, 7257ec681f3Smrg dst_resource, dst_level, 7267ec681f3Smrg DstX, DstY, DstZ + dst_layer, 7277ec681f3Smrg src_resource, src_level, 7287ec681f3Smrg &src_box); 7297ec681f3Smrg } else { 7307ec681f3Smrg util_resource_copy_region(pipe, 7317ec681f3Smrg dst_resource, dst_level, 7327ec681f3Smrg DstX, DstY, DstZ + dst_layer, 7337ec681f3Smrg src_resource, src_level, 7347ec681f3Smrg &src_box); 7357ec681f3Smrg } 7367ec681f3Smrg} 7377ec681f3Smrg 7387ec681f3Smrg 7397ec681f3Smrg/* 7407ec681f3Smrg * ---------------------------------------------------------------------- 7417ec681f3Smrg * 7427ec681f3Smrg * ResourceResolveSubResource -- 7437ec681f3Smrg * 7447ec681f3Smrg * The ResourceResolveSubResource function resolves 7457ec681f3Smrg * multiple samples to one pixel. 7467ec681f3Smrg * 7477ec681f3Smrg * ---------------------------------------------------------------------- 7487ec681f3Smrg */ 7497ec681f3Smrg 7507ec681f3Smrgvoid APIENTRY 7517ec681f3SmrgResourceResolveSubResource(D3D10DDI_HDEVICE hDevice, // IN 7527ec681f3Smrg D3D10DDI_HRESOURCE hDstResource, // IN 7537ec681f3Smrg UINT DstSubResource, // IN 7547ec681f3Smrg D3D10DDI_HRESOURCE hSrcResource, // IN 7557ec681f3Smrg UINT SrcSubResource, // IN 7567ec681f3Smrg DXGI_FORMAT ResolveFormat) // IN 7577ec681f3Smrg{ 7587ec681f3Smrg LOG_UNSUPPORTED_ENTRYPOINT(); 7597ec681f3Smrg} 7607ec681f3Smrg 7617ec681f3Smrg 7627ec681f3Smrg/* 7637ec681f3Smrg * ---------------------------------------------------------------------- 7647ec681f3Smrg * 7657ec681f3Smrg * ResourceIsStagingBusy -- 7667ec681f3Smrg * 7677ec681f3Smrg * The ResourceIsStagingBusy function determines whether a 7687ec681f3Smrg * resource is currently being used by the graphics pipeline. 7697ec681f3Smrg * 7707ec681f3Smrg * ---------------------------------------------------------------------- 7717ec681f3Smrg */ 7727ec681f3Smrg 7737ec681f3SmrgBOOL APIENTRY 7747ec681f3SmrgResourceIsStagingBusy(D3D10DDI_HDEVICE hDevice, // IN 7757ec681f3Smrg D3D10DDI_HRESOURCE hResource) // IN 7767ec681f3Smrg{ 7777ec681f3Smrg LOG_ENTRYPOINT(); 7787ec681f3Smrg 7797ec681f3Smrg /* ignore */ 7807ec681f3Smrg 7817ec681f3Smrg return FALSE; 7827ec681f3Smrg} 7837ec681f3Smrg 7847ec681f3Smrg 7857ec681f3Smrg/* 7867ec681f3Smrg * ---------------------------------------------------------------------- 7877ec681f3Smrg * 7887ec681f3Smrg * ResourceReadAfterWriteHazard -- 7897ec681f3Smrg * 7907ec681f3Smrg * The ResourceReadAfterWriteHazard function informs the user-mode 7917ec681f3Smrg * display driver that the specified resource was used as an output 7927ec681f3Smrg * from the graphics processing unit (GPU) and that the resource 7937ec681f3Smrg * will be used as an input to the GPU. 7947ec681f3Smrg * 7957ec681f3Smrg * ---------------------------------------------------------------------- 7967ec681f3Smrg */ 7977ec681f3Smrg 7987ec681f3Smrgvoid APIENTRY 7997ec681f3SmrgResourceReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN 8007ec681f3Smrg D3D10DDI_HRESOURCE hResource) // IN 8017ec681f3Smrg{ 8027ec681f3Smrg LOG_ENTRYPOINT(); 8037ec681f3Smrg 8047ec681f3Smrg /* Not actually necessary */ 8057ec681f3Smrg} 8067ec681f3Smrg 8077ec681f3Smrg 8087ec681f3Smrg/* 8097ec681f3Smrg * ---------------------------------------------------------------------- 8107ec681f3Smrg * 8117ec681f3Smrg * ResourceUpdateSubResourceUP -- 8127ec681f3Smrg * 8137ec681f3Smrg * The ResourceUpdateSubresourceUP function updates a 8147ec681f3Smrg * destination subresource region from a source 8157ec681f3Smrg * system memory region. 8167ec681f3Smrg * 8177ec681f3Smrg * ---------------------------------------------------------------------- 8187ec681f3Smrg */ 8197ec681f3Smrg 8207ec681f3Smrgvoid APIENTRY 8217ec681f3SmrgResourceUpdateSubResourceUP(D3D10DDI_HDEVICE hDevice, // IN 8227ec681f3Smrg D3D10DDI_HRESOURCE hDstResource, // IN 8237ec681f3Smrg UINT DstSubResource, // IN 8247ec681f3Smrg __in_opt const D3D10_DDI_BOX *pDstBox, // IN 8257ec681f3Smrg __in const void *pSysMemUP, // IN 8267ec681f3Smrg UINT RowPitch, // IN 8277ec681f3Smrg UINT DepthPitch) // IN 8287ec681f3Smrg{ 8297ec681f3Smrg LOG_ENTRYPOINT(); 8307ec681f3Smrg 8317ec681f3Smrg Device *pDevice = CastDevice(hDevice); 8327ec681f3Smrg if (!CheckPredicate(pDevice)) { 8337ec681f3Smrg return; 8347ec681f3Smrg } 8357ec681f3Smrg 8367ec681f3Smrg struct pipe_context *pipe = pDevice->pipe; 8377ec681f3Smrg struct pipe_resource *dst_resource = CastPipeResource(hDstResource); 8387ec681f3Smrg 8397ec681f3Smrg unsigned level; 8407ec681f3Smrg struct pipe_box box; 8417ec681f3Smrg 8427ec681f3Smrg if (pDstBox) { 8437ec681f3Smrg UINT DstMipLevels = dst_resource->last_level + 1; 8447ec681f3Smrg level = DstSubResource % DstMipLevels; 8457ec681f3Smrg unsigned dst_layer = DstSubResource / DstMipLevels; 8467ec681f3Smrg box.x = pDstBox->left; 8477ec681f3Smrg box.y = pDstBox->top; 8487ec681f3Smrg box.z = pDstBox->front + dst_layer; 8497ec681f3Smrg box.width = pDstBox->right - pDstBox->left; 8507ec681f3Smrg box.height = pDstBox->bottom - pDstBox->top; 8517ec681f3Smrg box.depth = pDstBox->back - pDstBox->front; 8527ec681f3Smrg } else { 8537ec681f3Smrg subResourceBox(dst_resource, DstSubResource, &level, &box); 8547ec681f3Smrg } 8557ec681f3Smrg 8567ec681f3Smrg struct pipe_transfer *transfer; 8577ec681f3Smrg void *map; 8587ec681f3Smrg map = pipe->transfer_map(pipe, 8597ec681f3Smrg dst_resource, 8607ec681f3Smrg level, 8617ec681f3Smrg PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE, 8627ec681f3Smrg &box, 8637ec681f3Smrg &transfer); 8647ec681f3Smrg assert(map); 8657ec681f3Smrg if (map) { 8667ec681f3Smrg for (int z = 0; z < box.depth; ++z) { 8677ec681f3Smrg ubyte *dst = (ubyte*)map + z*transfer->layer_stride; 8687ec681f3Smrg const ubyte *src = (const ubyte*)pSysMemUP + z*DepthPitch; 8697ec681f3Smrg util_copy_rect(dst, 8707ec681f3Smrg dst_resource->format, 8717ec681f3Smrg transfer->stride, 8727ec681f3Smrg 0, 0, box.width, box.height, 8737ec681f3Smrg src, 8747ec681f3Smrg RowPitch, 8757ec681f3Smrg 0, 0); 8767ec681f3Smrg } 8777ec681f3Smrg pipe_transfer_unmap(pipe, transfer); 8787ec681f3Smrg } 8797ec681f3Smrg} 8807ec681f3Smrg 881