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