1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include "device9.h" 24bf215546Sopenharmony_ci#include "volume9.h" 25bf215546Sopenharmony_ci#include "basetexture9.h" /* for marking dirty */ 26bf215546Sopenharmony_ci#include "volumetexture9.h" 27bf215546Sopenharmony_ci#include "nine_helpers.h" 28bf215546Sopenharmony_ci#include "nine_pipe.h" 29bf215546Sopenharmony_ci#include "nine_dump.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/format/u_format.h" 32bf215546Sopenharmony_ci#include "util/u_surface.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#define DBG_CHANNEL DBG_VOLUME 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic HRESULT 38bf215546Sopenharmony_ciNineVolume9_AllocateData( struct NineVolume9 *This ) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci unsigned size = This->layer_stride * This->desc.Depth; 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n", 43bf215546Sopenharmony_ci This->base.container, This, This->level, size); 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci This->data = (uint8_t *)align_calloc(size, 32); 46bf215546Sopenharmony_ci if (!This->data) 47bf215546Sopenharmony_ci return E_OUTOFMEMORY; 48bf215546Sopenharmony_ci return D3D_OK; 49bf215546Sopenharmony_ci} 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_cistatic HRESULT 52bf215546Sopenharmony_ciNineVolume9_ctor( struct NineVolume9 *This, 53bf215546Sopenharmony_ci struct NineUnknownParams *pParams, 54bf215546Sopenharmony_ci struct NineUnknown *pContainer, 55bf215546Sopenharmony_ci struct pipe_resource *pResource, 56bf215546Sopenharmony_ci unsigned Level, 57bf215546Sopenharmony_ci D3DVOLUME_DESC *pDesc ) 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci HRESULT hr; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci assert(pContainer); /* stand-alone volumes can't be created */ 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci DBG("This=%p pContainer=%p pDevice=%p pResource=%p Level=%u pDesc=%p\n", 64bf215546Sopenharmony_ci This, pContainer, pParams->device, pResource, Level, pDesc); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci /* Mark this as a special surface held by another internal resource. */ 67bf215546Sopenharmony_ci pParams->container = pContainer; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || 70bf215546Sopenharmony_ci (pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci assert(pResource || pDesc->Pool != D3DPOOL_DEFAULT); 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci hr = NineUnknown_ctor(&This->base, pParams); 75bf215546Sopenharmony_ci if (FAILED(hr)) 76bf215546Sopenharmony_ci return hr; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci pipe_resource_reference(&This->resource, pResource); 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci This->transfer = NULL; 81bf215546Sopenharmony_ci This->lock_count = 0; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci This->level = Level; 84bf215546Sopenharmony_ci This->level_actual = Level; 85bf215546Sopenharmony_ci This->desc = *pDesc; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci This->info.screen = pParams->device->screen; 88bf215546Sopenharmony_ci This->info.target = PIPE_TEXTURE_3D; 89bf215546Sopenharmony_ci This->info.width0 = pDesc->Width; 90bf215546Sopenharmony_ci This->info.height0 = pDesc->Height; 91bf215546Sopenharmony_ci This->info.depth0 = pDesc->Depth; 92bf215546Sopenharmony_ci This->info.last_level = 0; 93bf215546Sopenharmony_ci This->info.array_size = 1; 94bf215546Sopenharmony_ci This->info.nr_samples = 0; 95bf215546Sopenharmony_ci This->info.nr_storage_samples = 0; 96bf215546Sopenharmony_ci This->info.usage = PIPE_USAGE_DEFAULT; 97bf215546Sopenharmony_ci This->info.bind = PIPE_BIND_SAMPLER_VIEW; 98bf215546Sopenharmony_ci This->info.flags = 0; 99bf215546Sopenharmony_ci This->info.format = d3d9_to_pipe_format_checked(This->info.screen, 100bf215546Sopenharmony_ci pDesc->Format, 101bf215546Sopenharmony_ci This->info.target, 102bf215546Sopenharmony_ci This->info.nr_samples, 103bf215546Sopenharmony_ci This->info.bind, FALSE, 104bf215546Sopenharmony_ci pDesc->Pool == D3DPOOL_SCRATCH); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci if (This->info.format == PIPE_FORMAT_NONE) 107bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci This->stride = util_format_get_stride(This->info.format, pDesc->Width); 110bf215546Sopenharmony_ci This->stride = align(This->stride, 4); 111bf215546Sopenharmony_ci This->layer_stride = util_format_get_2d_size(This->info.format, 112bf215546Sopenharmony_ci This->stride, pDesc->Height); 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci /* Get true format */ 115bf215546Sopenharmony_ci This->format_internal = d3d9_to_pipe_format_checked(This->info.screen, 116bf215546Sopenharmony_ci pDesc->Format, 117bf215546Sopenharmony_ci This->info.target, 118bf215546Sopenharmony_ci This->info.nr_samples, 119bf215546Sopenharmony_ci This->info.bind, FALSE, 120bf215546Sopenharmony_ci TRUE); 121bf215546Sopenharmony_ci if (This->info.format != This->format_internal || 122bf215546Sopenharmony_ci /* See surface9.c */ 123bf215546Sopenharmony_ci (pParams->device->workarounds.dynamic_texture_workaround && 124bf215546Sopenharmony_ci pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) { 125bf215546Sopenharmony_ci This->stride_internal = nine_format_get_stride(This->format_internal, 126bf215546Sopenharmony_ci pDesc->Width); 127bf215546Sopenharmony_ci This->layer_stride_internal = util_format_get_2d_size(This->format_internal, 128bf215546Sopenharmony_ci This->stride_internal, 129bf215546Sopenharmony_ci pDesc->Height); 130bf215546Sopenharmony_ci This->data_internal = align_calloc(This->layer_stride_internal * 131bf215546Sopenharmony_ci This->desc.Depth, 32); 132bf215546Sopenharmony_ci if (!This->data_internal) 133bf215546Sopenharmony_ci return E_OUTOFMEMORY; 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci if (!This->resource) { 137bf215546Sopenharmony_ci hr = NineVolume9_AllocateData(This); 138bf215546Sopenharmony_ci if (FAILED(hr)) 139bf215546Sopenharmony_ci return hr; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci return D3D_OK; 142bf215546Sopenharmony_ci} 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_cistatic void 145bf215546Sopenharmony_ciNineVolume9_dtor( struct NineVolume9 *This ) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci DBG("This=%p\n", This); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (This->transfer) { 150bf215546Sopenharmony_ci struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device); 151bf215546Sopenharmony_ci pipe->texture_unmap(pipe, This->transfer); 152bf215546Sopenharmony_ci This->transfer = NULL; 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci /* Note: Following condition cannot happen currently, since we 156bf215546Sopenharmony_ci * refcount the volume in the functions increasing 157bf215546Sopenharmony_ci * pending_uploads_counter. */ 158bf215546Sopenharmony_ci if (p_atomic_read(&This->pending_uploads_counter)) 159bf215546Sopenharmony_ci nine_csmt_process(This->base.device); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci if (This->data) 162bf215546Sopenharmony_ci align_free(This->data); 163bf215546Sopenharmony_ci if (This->data_internal) 164bf215546Sopenharmony_ci align_free(This->data_internal); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci pipe_resource_reference(&This->resource, NULL); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci NineUnknown_dtor(&This->base); 169bf215546Sopenharmony_ci} 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ciHRESULT NINE_WINAPI 172bf215546Sopenharmony_ciNineVolume9_GetContainer( struct NineVolume9 *This, 173bf215546Sopenharmony_ci REFIID riid, 174bf215546Sopenharmony_ci void **ppContainer ) 175bf215546Sopenharmony_ci{ 176bf215546Sopenharmony_ci char guid_str[64]; 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci DBG("This=%p riid=%p id=%s ppContainer=%p\n", 179bf215546Sopenharmony_ci This, riid, riid ? GUID_sprintf(guid_str, riid) : "", ppContainer); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci (void)guid_str; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci if (!NineUnknown(This)->container) 184bf215546Sopenharmony_ci return E_NOINTERFACE; 185bf215546Sopenharmony_ci return NineUnknown_QueryInterface(NineUnknown(This)->container, riid, ppContainer); 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cistatic inline void 189bf215546Sopenharmony_ciNineVolume9_MarkContainerDirty( struct NineVolume9 *This ) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci struct NineBaseTexture9 *tex; 192bf215546Sopenharmony_ci#if defined(DEBUG) || !defined(NDEBUG) 193bf215546Sopenharmony_ci /* This is always contained by a NineVolumeTexture9. */ 194bf215546Sopenharmony_ci GUID id = IID_IDirect3DVolumeTexture9; 195bf215546Sopenharmony_ci REFIID ref = &id; 196bf215546Sopenharmony_ci assert(NineUnknown_QueryInterface(This->base.container, ref, (void **)&tex) 197bf215546Sopenharmony_ci == S_OK); 198bf215546Sopenharmony_ci assert(NineUnknown_Release(NineUnknown(tex)) != 0); 199bf215546Sopenharmony_ci#endif 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci tex = NineBaseTexture9(This->base.container); 202bf215546Sopenharmony_ci assert(tex); 203bf215546Sopenharmony_ci if (This->desc.Pool == D3DPOOL_MANAGED) 204bf215546Sopenharmony_ci tex->managed.dirty = TRUE; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci BASETEX_REGISTER_UPDATE(tex); 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ciHRESULT NINE_WINAPI 210bf215546Sopenharmony_ciNineVolume9_GetDesc( struct NineVolume9 *This, 211bf215546Sopenharmony_ci D3DVOLUME_DESC *pDesc ) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci user_assert(pDesc != NULL, E_POINTER); 214bf215546Sopenharmony_ci *pDesc = This->desc; 215bf215546Sopenharmony_ci return D3D_OK; 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ciinline void 219bf215546Sopenharmony_ciNineVolume9_AddDirtyRegion( struct NineVolume9 *This, 220bf215546Sopenharmony_ci const struct pipe_box *box ) 221bf215546Sopenharmony_ci{ 222bf215546Sopenharmony_ci D3DBOX dirty_region; 223bf215546Sopenharmony_ci struct NineVolumeTexture9 *tex = NineVolumeTexture9(This->base.container); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci if (!box) { 226bf215546Sopenharmony_ci NineVolumeTexture9_AddDirtyBox(tex, NULL); 227bf215546Sopenharmony_ci } else { 228bf215546Sopenharmony_ci dirty_region.Left = box->x << This->level_actual; 229bf215546Sopenharmony_ci dirty_region.Top = box->y << This->level_actual; 230bf215546Sopenharmony_ci dirty_region.Front = box->z << This->level_actual; 231bf215546Sopenharmony_ci dirty_region.Right = dirty_region.Left + (box->width << This->level_actual); 232bf215546Sopenharmony_ci dirty_region.Bottom = dirty_region.Top + (box->height << This->level_actual); 233bf215546Sopenharmony_ci dirty_region.Back = dirty_region.Front + (box->depth << This->level_actual); 234bf215546Sopenharmony_ci NineVolumeTexture9_AddDirtyBox(tex, &dirty_region); 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci} 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_cistatic inline unsigned 239bf215546Sopenharmony_ciNineVolume9_GetSystemMemOffset(enum pipe_format format, unsigned stride, 240bf215546Sopenharmony_ci unsigned layer_stride, 241bf215546Sopenharmony_ci int x, int y, int z) 242bf215546Sopenharmony_ci{ 243bf215546Sopenharmony_ci unsigned x_offset = util_format_get_stride(format, x); 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci y = util_format_get_nblocksy(format, y); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci return z * layer_stride + y * stride + x_offset; 248bf215546Sopenharmony_ci} 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ciHRESULT NINE_WINAPI 251bf215546Sopenharmony_ciNineVolume9_LockBox( struct NineVolume9 *This, 252bf215546Sopenharmony_ci D3DLOCKED_BOX *pLockedVolume, 253bf215546Sopenharmony_ci const D3DBOX *pBox, 254bf215546Sopenharmony_ci DWORD Flags ) 255bf215546Sopenharmony_ci{ 256bf215546Sopenharmony_ci struct pipe_context *pipe; 257bf215546Sopenharmony_ci struct pipe_resource *resource = This->resource; 258bf215546Sopenharmony_ci struct pipe_box box; 259bf215546Sopenharmony_ci unsigned usage; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci DBG("This=%p(%p) pLockedVolume=%p pBox=%p[%u..%u,%u..%u,%u..%u] Flags=%s\n", 262bf215546Sopenharmony_ci This, This->base.container, pLockedVolume, pBox, 263bf215546Sopenharmony_ci pBox ? pBox->Left : 0, pBox ? pBox->Right : 0, 264bf215546Sopenharmony_ci pBox ? pBox->Top : 0, pBox ? pBox->Bottom : 0, 265bf215546Sopenharmony_ci pBox ? pBox->Front : 0, pBox ? pBox->Back : 0, 266bf215546Sopenharmony_ci nine_D3DLOCK_to_str(Flags)); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci /* check if it's already locked */ 269bf215546Sopenharmony_ci user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* set pBits to NULL after lock_count check */ 272bf215546Sopenharmony_ci user_assert(pLockedVolume, E_POINTER); 273bf215546Sopenharmony_ci pLockedVolume->pBits = NULL; 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci user_assert(This->desc.Pool != D3DPOOL_DEFAULT || 276bf215546Sopenharmony_ci (This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), 279bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci if (pBox && compressed_format (This->desc.Format)) { /* For volume all pools are checked */ 282bf215546Sopenharmony_ci const unsigned w = util_format_get_blockwidth(This->info.format); 283bf215546Sopenharmony_ci const unsigned h = util_format_get_blockheight(This->info.format); 284bf215546Sopenharmony_ci user_assert((pBox->Left == 0 && pBox->Right == This->desc.Width && 285bf215546Sopenharmony_ci pBox->Top == 0 && pBox->Bottom == This->desc.Height) || 286bf215546Sopenharmony_ci (!(pBox->Left % w) && !(pBox->Right % w) && 287bf215546Sopenharmony_ci !(pBox->Top % h) && !(pBox->Bottom % h)), 288bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 289bf215546Sopenharmony_ci } 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci if (Flags & D3DLOCK_DISCARD) { 292bf215546Sopenharmony_ci usage = PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE; 293bf215546Sopenharmony_ci } else { 294bf215546Sopenharmony_ci usage = (Flags & D3DLOCK_READONLY) ? 295bf215546Sopenharmony_ci PIPE_MAP_READ : PIPE_MAP_READ_WRITE; 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci if (Flags & D3DLOCK_DONOTWAIT) 298bf215546Sopenharmony_ci usage |= PIPE_MAP_DONTBLOCK; 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci if (pBox) { 301bf215546Sopenharmony_ci user_assert(pBox->Right > pBox->Left, D3DERR_INVALIDCALL); 302bf215546Sopenharmony_ci user_assert(pBox->Bottom > pBox->Top, D3DERR_INVALIDCALL); 303bf215546Sopenharmony_ci user_assert(pBox->Back > pBox->Front, D3DERR_INVALIDCALL); 304bf215546Sopenharmony_ci user_assert(pBox->Right <= This->desc.Width, D3DERR_INVALIDCALL); 305bf215546Sopenharmony_ci user_assert(pBox->Bottom <= This->desc.Height, D3DERR_INVALIDCALL); 306bf215546Sopenharmony_ci user_assert(pBox->Back <= This->desc.Depth, D3DERR_INVALIDCALL); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci d3dbox_to_pipe_box(&box, pBox); 309bf215546Sopenharmony_ci if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { 310bf215546Sopenharmony_ci DBG("Locked volume intersection empty.\n"); 311bf215546Sopenharmony_ci return D3DERR_INVALIDCALL; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } else { 314bf215546Sopenharmony_ci u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, 315bf215546Sopenharmony_ci &box); 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci if (p_atomic_read(&This->pending_uploads_counter)) 319bf215546Sopenharmony_ci nine_csmt_process(This->base.device); 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci if (This->data_internal || This->data) { 322bf215546Sopenharmony_ci enum pipe_format format = This->info.format; 323bf215546Sopenharmony_ci unsigned stride = This->stride; 324bf215546Sopenharmony_ci unsigned layer_stride = This->layer_stride; 325bf215546Sopenharmony_ci uint8_t *data = This->data; 326bf215546Sopenharmony_ci if (This->data_internal) { 327bf215546Sopenharmony_ci format = This->format_internal; 328bf215546Sopenharmony_ci stride = This->stride_internal; 329bf215546Sopenharmony_ci layer_stride = This->layer_stride_internal; 330bf215546Sopenharmony_ci data = This->data_internal; 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci pLockedVolume->RowPitch = stride; 333bf215546Sopenharmony_ci pLockedVolume->SlicePitch = layer_stride; 334bf215546Sopenharmony_ci pLockedVolume->pBits = data + 335bf215546Sopenharmony_ci NineVolume9_GetSystemMemOffset(format, stride, 336bf215546Sopenharmony_ci layer_stride, 337bf215546Sopenharmony_ci box.x, box.y, box.z); 338bf215546Sopenharmony_ci } else { 339bf215546Sopenharmony_ci bool no_refs = !p_atomic_read(&This->base.bind) && 340bf215546Sopenharmony_ci !p_atomic_read(&This->base.container->bind); 341bf215546Sopenharmony_ci if (no_refs) 342bf215546Sopenharmony_ci pipe = nine_context_get_pipe_acquire(This->base.device); 343bf215546Sopenharmony_ci else 344bf215546Sopenharmony_ci pipe = NineDevice9_GetPipe(This->base.device); 345bf215546Sopenharmony_ci pLockedVolume->pBits = 346bf215546Sopenharmony_ci pipe->texture_map(pipe, resource, This->level, usage, 347bf215546Sopenharmony_ci &box, &This->transfer); 348bf215546Sopenharmony_ci if (no_refs) 349bf215546Sopenharmony_ci nine_context_get_pipe_release(This->base.device); 350bf215546Sopenharmony_ci if (!This->transfer) { 351bf215546Sopenharmony_ci if (Flags & D3DLOCK_DONOTWAIT) 352bf215546Sopenharmony_ci return D3DERR_WASSTILLDRAWING; 353bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci pLockedVolume->RowPitch = This->transfer->stride; 356bf215546Sopenharmony_ci pLockedVolume->SlicePitch = This->transfer->layer_stride; 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { 360bf215546Sopenharmony_ci NineVolume9_MarkContainerDirty(This); 361bf215546Sopenharmony_ci NineVolume9_AddDirtyRegion(This, &box); 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci ++This->lock_count; 365bf215546Sopenharmony_ci return D3D_OK; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ciHRESULT NINE_WINAPI 369bf215546Sopenharmony_ciNineVolume9_UnlockBox( struct NineVolume9 *This ) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci struct pipe_context *pipe; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci DBG("This=%p lock_count=%u\n", This, This->lock_count); 374bf215546Sopenharmony_ci user_assert(This->lock_count, D3DERR_INVALIDCALL); 375bf215546Sopenharmony_ci if (This->transfer) { 376bf215546Sopenharmony_ci pipe = nine_context_get_pipe_acquire(This->base.device); 377bf215546Sopenharmony_ci pipe->texture_unmap(pipe, This->transfer); 378bf215546Sopenharmony_ci This->transfer = NULL; 379bf215546Sopenharmony_ci nine_context_get_pipe_release(This->base.device); 380bf215546Sopenharmony_ci } 381bf215546Sopenharmony_ci --This->lock_count; 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci if (This->data_internal) { 384bf215546Sopenharmony_ci struct pipe_box box; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, 387bf215546Sopenharmony_ci &box); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci if (This->data) { 391bf215546Sopenharmony_ci (void) util_format_translate_3d(This->info.format, 392bf215546Sopenharmony_ci This->data, This->stride, 393bf215546Sopenharmony_ci This->layer_stride, 394bf215546Sopenharmony_ci 0, 0, 0, 395bf215546Sopenharmony_ci This->format_internal, 396bf215546Sopenharmony_ci This->data_internal, 397bf215546Sopenharmony_ci This->stride_internal, 398bf215546Sopenharmony_ci This->layer_stride_internal, 399bf215546Sopenharmony_ci 0, 0, 0, 400bf215546Sopenharmony_ci This->desc.Width, This->desc.Height, 401bf215546Sopenharmony_ci This->desc.Depth); 402bf215546Sopenharmony_ci } else { 403bf215546Sopenharmony_ci nine_context_box_upload(This->base.device, 404bf215546Sopenharmony_ci &This->pending_uploads_counter, 405bf215546Sopenharmony_ci (struct NineUnknown *)This, 406bf215546Sopenharmony_ci This->resource, 407bf215546Sopenharmony_ci This->level, 408bf215546Sopenharmony_ci &box, 409bf215546Sopenharmony_ci This->format_internal, 410bf215546Sopenharmony_ci This->data_internal, 411bf215546Sopenharmony_ci This->stride_internal, 412bf215546Sopenharmony_ci This->layer_stride_internal, 413bf215546Sopenharmony_ci &box); 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci } 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci return D3D_OK; 418bf215546Sopenharmony_ci} 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci/* When this function is called, we have already checked 421bf215546Sopenharmony_ci * The copy regions fit the volumes */ 422bf215546Sopenharmony_civoid 423bf215546Sopenharmony_ciNineVolume9_CopyMemToDefault( struct NineVolume9 *This, 424bf215546Sopenharmony_ci struct NineVolume9 *From, 425bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 426bf215546Sopenharmony_ci struct pipe_box *pSrcBox ) 427bf215546Sopenharmony_ci{ 428bf215546Sopenharmony_ci struct pipe_resource *r_dst = This->resource; 429bf215546Sopenharmony_ci struct pipe_box src_box; 430bf215546Sopenharmony_ci struct pipe_box dst_box; 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci DBG("This=%p From=%p dstx=%u dsty=%u dstz=%u pSrcBox=%p\n", 433bf215546Sopenharmony_ci This, From, dstx, dsty, dstz, pSrcBox); 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci assert(This->desc.Pool == D3DPOOL_DEFAULT && 436bf215546Sopenharmony_ci From->desc.Pool == D3DPOOL_SYSTEMMEM); 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci dst_box.x = dstx; 439bf215546Sopenharmony_ci dst_box.y = dsty; 440bf215546Sopenharmony_ci dst_box.z = dstz; 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci if (pSrcBox) { 443bf215546Sopenharmony_ci src_box = *pSrcBox; 444bf215546Sopenharmony_ci } else { 445bf215546Sopenharmony_ci src_box.x = 0; 446bf215546Sopenharmony_ci src_box.y = 0; 447bf215546Sopenharmony_ci src_box.z = 0; 448bf215546Sopenharmony_ci src_box.width = From->desc.Width; 449bf215546Sopenharmony_ci src_box.height = From->desc.Height; 450bf215546Sopenharmony_ci src_box.depth = From->desc.Depth; 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci dst_box.width = src_box.width; 454bf215546Sopenharmony_ci dst_box.height = src_box.height; 455bf215546Sopenharmony_ci dst_box.depth = src_box.depth; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci nine_context_box_upload(This->base.device, 458bf215546Sopenharmony_ci &From->pending_uploads_counter, 459bf215546Sopenharmony_ci (struct NineUnknown *)From, 460bf215546Sopenharmony_ci r_dst, 461bf215546Sopenharmony_ci This->level, 462bf215546Sopenharmony_ci &dst_box, 463bf215546Sopenharmony_ci From->info.format, 464bf215546Sopenharmony_ci From->data, From->stride, 465bf215546Sopenharmony_ci From->layer_stride, 466bf215546Sopenharmony_ci &src_box); 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci if (This->data_internal) 469bf215546Sopenharmony_ci (void) util_format_translate_3d(This->format_internal, 470bf215546Sopenharmony_ci This->data_internal, 471bf215546Sopenharmony_ci This->stride_internal, 472bf215546Sopenharmony_ci This->layer_stride_internal, 473bf215546Sopenharmony_ci dstx, dsty, dstz, 474bf215546Sopenharmony_ci From->info.format, 475bf215546Sopenharmony_ci From->data, From->stride, 476bf215546Sopenharmony_ci From->layer_stride, 477bf215546Sopenharmony_ci src_box.x, src_box.y, 478bf215546Sopenharmony_ci src_box.z, 479bf215546Sopenharmony_ci src_box.width, 480bf215546Sopenharmony_ci src_box.height, 481bf215546Sopenharmony_ci src_box.depth); 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci NineVolume9_MarkContainerDirty(This); 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci return; 486bf215546Sopenharmony_ci} 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ciHRESULT 489bf215546Sopenharmony_ciNineVolume9_UploadSelf( struct NineVolume9 *This, 490bf215546Sopenharmony_ci const struct pipe_box *damaged ) 491bf215546Sopenharmony_ci{ 492bf215546Sopenharmony_ci struct pipe_resource *res = This->resource; 493bf215546Sopenharmony_ci struct pipe_box box; 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci DBG("This=%p damaged=%p data=%p res=%p\n", This, damaged, 496bf215546Sopenharmony_ci This->data, res); 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci assert(This->desc.Pool == D3DPOOL_MANAGED); 499bf215546Sopenharmony_ci assert(res); 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci if (damaged) { 502bf215546Sopenharmony_ci box = *damaged; 503bf215546Sopenharmony_ci } else { 504bf215546Sopenharmony_ci box.x = 0; 505bf215546Sopenharmony_ci box.y = 0; 506bf215546Sopenharmony_ci box.z = 0; 507bf215546Sopenharmony_ci box.width = This->desc.Width; 508bf215546Sopenharmony_ci box.height = This->desc.Height; 509bf215546Sopenharmony_ci box.depth = This->desc.Depth; 510bf215546Sopenharmony_ci } 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci nine_context_box_upload(This->base.device, 513bf215546Sopenharmony_ci &This->pending_uploads_counter, 514bf215546Sopenharmony_ci (struct NineUnknown *)This, 515bf215546Sopenharmony_ci res, 516bf215546Sopenharmony_ci This->level, 517bf215546Sopenharmony_ci &box, 518bf215546Sopenharmony_ci res->format, 519bf215546Sopenharmony_ci This->data, This->stride, 520bf215546Sopenharmony_ci This->layer_stride, 521bf215546Sopenharmony_ci &box); 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci return D3D_OK; 524bf215546Sopenharmony_ci} 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ciIDirect3DVolume9Vtbl NineVolume9_vtable = { 528bf215546Sopenharmony_ci (void *)NineUnknown_QueryInterface, 529bf215546Sopenharmony_ci (void *)NineUnknown_AddRef, 530bf215546Sopenharmony_ci (void *)NineUnknown_Release, 531bf215546Sopenharmony_ci (void *)NineUnknown_GetDevice, /* actually part of Volume9 iface */ 532bf215546Sopenharmony_ci (void *)NineUnknown_SetPrivateData, 533bf215546Sopenharmony_ci (void *)NineUnknown_GetPrivateData, 534bf215546Sopenharmony_ci (void *)NineUnknown_FreePrivateData, 535bf215546Sopenharmony_ci (void *)NineVolume9_GetContainer, 536bf215546Sopenharmony_ci (void *)NineVolume9_GetDesc, 537bf215546Sopenharmony_ci (void *)NineVolume9_LockBox, 538bf215546Sopenharmony_ci (void *)NineVolume9_UnlockBox 539bf215546Sopenharmony_ci}; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_cistatic const GUID *NineVolume9_IIDs[] = { 542bf215546Sopenharmony_ci &IID_IDirect3DVolume9, 543bf215546Sopenharmony_ci &IID_IUnknown, 544bf215546Sopenharmony_ci NULL 545bf215546Sopenharmony_ci}; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ciHRESULT 548bf215546Sopenharmony_ciNineVolume9_new( struct NineDevice9 *pDevice, 549bf215546Sopenharmony_ci struct NineUnknown *pContainer, 550bf215546Sopenharmony_ci struct pipe_resource *pResource, 551bf215546Sopenharmony_ci unsigned Level, 552bf215546Sopenharmony_ci D3DVOLUME_DESC *pDesc, 553bf215546Sopenharmony_ci struct NineVolume9 **ppOut ) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci NINE_DEVICE_CHILD_NEW(Volume9, ppOut, pDevice, /* args */ 556bf215546Sopenharmony_ci pContainer, pResource, Level, pDesc); 557bf215546Sopenharmony_ci} 558