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