xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/nine/texture9.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 "c99_alloca.h"
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "device9.h"
9*61046927SAndroid Build Coastguard Worker #include "surface9.h"
10*61046927SAndroid Build Coastguard Worker #include "texture9.h"
11*61046927SAndroid Build Coastguard Worker #include "nine_helpers.h"
12*61046927SAndroid Build Coastguard Worker #include "nine_memory_helper.h"
13*61046927SAndroid Build Coastguard Worker #include "nine_pipe.h"
14*61046927SAndroid Build Coastguard Worker #include "nine_dump.h"
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker #include "pipe/p_state.h"
17*61046927SAndroid Build Coastguard Worker #include "pipe/p_context.h"
18*61046927SAndroid Build Coastguard Worker #include "pipe/p_screen.h"
19*61046927SAndroid Build Coastguard Worker #include "util/u_inlines.h"
20*61046927SAndroid Build Coastguard Worker #include "util/u_resource.h"
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker #define DBG_CHANNEL DBG_TEXTURE
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker static HRESULT
NineTexture9_ctor(struct NineTexture9 * This,struct NineUnknownParams * pParams,UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,HANDLE * pSharedHandle)25*61046927SAndroid Build Coastguard Worker NineTexture9_ctor( struct NineTexture9 *This,
26*61046927SAndroid Build Coastguard Worker                    struct NineUnknownParams *pParams,
27*61046927SAndroid Build Coastguard Worker                    UINT Width, UINT Height, UINT Levels,
28*61046927SAndroid Build Coastguard Worker                    DWORD Usage,
29*61046927SAndroid Build Coastguard Worker                    D3DFORMAT Format,
30*61046927SAndroid Build Coastguard Worker                    D3DPOOL Pool,
31*61046927SAndroid Build Coastguard Worker                    HANDLE *pSharedHandle )
32*61046927SAndroid Build Coastguard Worker {
33*61046927SAndroid Build Coastguard Worker     struct pipe_screen *screen = pParams->device->screen;
34*61046927SAndroid Build Coastguard Worker     struct pipe_resource *info = &This->base.base.info;
35*61046927SAndroid Build Coastguard Worker     enum pipe_format pf;
36*61046927SAndroid Build Coastguard Worker     unsigned *level_offsets = NULL;
37*61046927SAndroid Build Coastguard Worker     unsigned l;
38*61046927SAndroid Build Coastguard Worker     D3DSURFACE_DESC sfdesc;
39*61046927SAndroid Build Coastguard Worker     HRESULT hr;
40*61046927SAndroid Build Coastguard Worker     struct nine_allocation *user_buffer = NULL, *user_buffer_for_level;
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker     This->base.base.base.device = pParams->device; /* Early fill this field in case of failure */
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker     DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
45*61046927SAndroid Build Coastguard Worker         "pSharedHandle=%p\n", This, Width, Height, Levels,
46*61046927SAndroid Build Coastguard Worker         nine_D3DUSAGE_to_str(Usage),
47*61046927SAndroid Build Coastguard Worker         d3dformat_to_string(Format), nine_D3DPOOL_to_str(Pool), pSharedHandle);
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker     user_assert(Width && Height, D3DERR_INVALIDCALL);
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker     /* pSharedHandle: can be non-null for ex only.
52*61046927SAndroid Build Coastguard Worker      * D3DPOOL_SYSTEMMEM: Levels must be 1
53*61046927SAndroid Build Coastguard Worker      * D3DPOOL_DEFAULT: no restriction for Levels
54*61046927SAndroid Build Coastguard Worker      * Other Pools are forbidden. */
55*61046927SAndroid Build Coastguard Worker     user_assert(!pSharedHandle || pParams->device->ex, D3DERR_INVALIDCALL);
56*61046927SAndroid Build Coastguard Worker     user_assert(!pSharedHandle ||
57*61046927SAndroid Build Coastguard Worker                 (Pool == D3DPOOL_SYSTEMMEM && Levels == 1) ||
58*61046927SAndroid Build Coastguard Worker                 Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker     user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
61*61046927SAndroid Build Coastguard Worker                 (Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_SCRATCH && Levels <= 1),
62*61046927SAndroid Build Coastguard Worker                 D3DERR_INVALIDCALL);
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker     /* TODO: implement pSharedHandle for D3DPOOL_DEFAULT (cross process
65*61046927SAndroid Build Coastguard Worker      * buffer sharing).
66*61046927SAndroid Build Coastguard Worker      *
67*61046927SAndroid Build Coastguard Worker      * Gem names may have fit but they're depreciated and won't work on render-nodes.
68*61046927SAndroid Build Coastguard Worker      * One solution is to use shm buffers. We would use a /dev/shm file, fill the first
69*61046927SAndroid Build Coastguard Worker      * values to tell it is a nine buffer, the size, which function created it, etc,
70*61046927SAndroid Build Coastguard Worker      * and then it would contain the data. The handle would be a number, corresponding to
71*61046927SAndroid Build Coastguard Worker      * the file to read (/dev/shm/nine-share-4 for example would be 4).
72*61046927SAndroid Build Coastguard Worker      *
73*61046927SAndroid Build Coastguard Worker      * Wine just ignores the argument, which works only if the app creates the handle
74*61046927SAndroid Build Coastguard Worker      * and won't use it. Instead of failing, we support that situation by putting an
75*61046927SAndroid Build Coastguard Worker      * invalid handle, that we would fail to import. Please note that we don't advertise
76*61046927SAndroid Build Coastguard Worker      * the flag indicating the support for that feature, but apps seem to not care.
77*61046927SAndroid Build Coastguard Worker      */
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker     if (pSharedHandle && Pool == D3DPOOL_DEFAULT) {
80*61046927SAndroid Build Coastguard Worker         if (!*pSharedHandle) {
81*61046927SAndroid Build Coastguard Worker             DBG("Creating Texture with invalid handle. Importing will fail\n.");
82*61046927SAndroid Build Coastguard Worker             *pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */
83*61046927SAndroid Build Coastguard Worker             pSharedHandle = NULL;
84*61046927SAndroid Build Coastguard Worker         } else {
85*61046927SAndroid Build Coastguard Worker             ERR("Application tries to use cross-process sharing feature. Nine "
86*61046927SAndroid Build Coastguard Worker                 "doesn't support it");
87*61046927SAndroid Build Coastguard Worker             return D3DERR_INVALIDCALL;
88*61046927SAndroid Build Coastguard Worker         }
89*61046927SAndroid Build Coastguard Worker     }
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker     if (Usage & D3DUSAGE_AUTOGENMIPMAP)
92*61046927SAndroid Build Coastguard Worker         Levels = 0;
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker     pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0,
95*61046927SAndroid Build Coastguard Worker                                      PIPE_BIND_SAMPLER_VIEW, false,
96*61046927SAndroid Build Coastguard Worker                                      Pool == D3DPOOL_SCRATCH);
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker     if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE)
99*61046927SAndroid Build Coastguard Worker         return D3DERR_INVALIDCALL;
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker     if (compressed_format(Format)) {
102*61046927SAndroid Build Coastguard Worker         const unsigned w = util_format_get_blockwidth(pf);
103*61046927SAndroid Build Coastguard Worker         const unsigned h = util_format_get_blockheight(pf);
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker         user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
106*61046927SAndroid Build Coastguard Worker     }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker     info->screen = screen;
109*61046927SAndroid Build Coastguard Worker     info->target = PIPE_TEXTURE_2D;
110*61046927SAndroid Build Coastguard Worker     info->format = pf;
111*61046927SAndroid Build Coastguard Worker     info->width0 = Width;
112*61046927SAndroid Build Coastguard Worker     info->height0 = Height;
113*61046927SAndroid Build Coastguard Worker     info->depth0 = 1;
114*61046927SAndroid Build Coastguard Worker     if (Levels)
115*61046927SAndroid Build Coastguard Worker         info->last_level = Levels - 1;
116*61046927SAndroid Build Coastguard Worker     else
117*61046927SAndroid Build Coastguard Worker         info->last_level = util_logbase2(MAX2(Width, Height));
118*61046927SAndroid Build Coastguard Worker     info->array_size = 1;
119*61046927SAndroid Build Coastguard Worker     info->nr_samples = 0;
120*61046927SAndroid Build Coastguard Worker     info->nr_storage_samples = 0;
121*61046927SAndroid Build Coastguard Worker     info->bind = PIPE_BIND_SAMPLER_VIEW;
122*61046927SAndroid Build Coastguard Worker     info->usage = PIPE_USAGE_DEFAULT;
123*61046927SAndroid Build Coastguard Worker     info->flags = 0;
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker     if (Usage & D3DUSAGE_RENDERTARGET)
126*61046927SAndroid Build Coastguard Worker         info->bind |= PIPE_BIND_RENDER_TARGET;
127*61046927SAndroid Build Coastguard Worker     if (Usage & D3DUSAGE_DEPTHSTENCIL)
128*61046927SAndroid Build Coastguard Worker         info->bind |= PIPE_BIND_DEPTH_STENCIL;
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker     if (Usage & D3DUSAGE_DYNAMIC) {
131*61046927SAndroid Build Coastguard Worker         info->usage = PIPE_USAGE_DYNAMIC;
132*61046927SAndroid Build Coastguard Worker     }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker     if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
135*61046927SAndroid Build Coastguard Worker         DBG("Application asked for Software Vertex Processing, "
136*61046927SAndroid Build Coastguard Worker             "but this is unimplemented\n");
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker     hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
139*61046927SAndroid Build Coastguard Worker     if (FAILED(hr))
140*61046927SAndroid Build Coastguard Worker         return hr;
141*61046927SAndroid Build Coastguard Worker     This->base.pstype = (Height == 1) ? 1 : 0;
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker     if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
144*61046927SAndroid Build Coastguard Worker         user_buffer = nine_wrap_external_pointer(pParams->device->allocator, (void *)*pSharedHandle);
145*61046927SAndroid Build Coastguard Worker         level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
146*61046927SAndroid Build Coastguard Worker         (void) nine_format_get_size_and_offsets(pf, level_offsets,
147*61046927SAndroid Build Coastguard Worker                                                 Width, Height,
148*61046927SAndroid Build Coastguard Worker                                                 This->base.level_count-1);
149*61046927SAndroid Build Coastguard Worker     } else if (Pool != D3DPOOL_DEFAULT) {
150*61046927SAndroid Build Coastguard Worker         level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
151*61046927SAndroid Build Coastguard Worker         user_buffer = nine_allocate(pParams->device->allocator,
152*61046927SAndroid Build Coastguard Worker             nine_format_get_size_and_offsets(pf, level_offsets,
153*61046927SAndroid Build Coastguard Worker                                              Width, Height,
154*61046927SAndroid Build Coastguard Worker                                              This->base.level_count-1));
155*61046927SAndroid Build Coastguard Worker         This->managed_buffer = user_buffer;
156*61046927SAndroid Build Coastguard Worker         if (!This->managed_buffer)
157*61046927SAndroid Build Coastguard Worker             return E_OUTOFMEMORY;
158*61046927SAndroid Build Coastguard Worker     }
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker     This->surfaces = CALLOC(This->base.level_count, sizeof(*This->surfaces));
161*61046927SAndroid Build Coastguard Worker     if (!This->surfaces)
162*61046927SAndroid Build Coastguard Worker         return E_OUTOFMEMORY;
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker     /* Create all the surfaces right away.
165*61046927SAndroid Build Coastguard Worker      * They manage backing storage, and transfers (LockRect) are deferred
166*61046927SAndroid Build Coastguard Worker      * to them.
167*61046927SAndroid Build Coastguard Worker      */
168*61046927SAndroid Build Coastguard Worker     sfdesc.Format = Format;
169*61046927SAndroid Build Coastguard Worker     sfdesc.Type = D3DRTYPE_SURFACE;
170*61046927SAndroid Build Coastguard Worker     sfdesc.Usage = Usage;
171*61046927SAndroid Build Coastguard Worker     sfdesc.Pool = Pool;
172*61046927SAndroid Build Coastguard Worker     sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE;
173*61046927SAndroid Build Coastguard Worker     sfdesc.MultiSampleQuality = 0;
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker     for (l = 0; l < This->base.level_count; ++l) {
176*61046927SAndroid Build Coastguard Worker         sfdesc.Width = u_minify(Width, l);
177*61046927SAndroid Build Coastguard Worker         sfdesc.Height = u_minify(Height, l);
178*61046927SAndroid Build Coastguard Worker         /* Some apps expect the memory to be allocated in
179*61046927SAndroid Build Coastguard Worker          * continuous blocks */
180*61046927SAndroid Build Coastguard Worker         user_buffer_for_level = user_buffer ?
181*61046927SAndroid Build Coastguard Worker             nine_suballocate(pParams->device->allocator, user_buffer, level_offsets[l]) : NULL;
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker         hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
184*61046927SAndroid Build Coastguard Worker                               This->base.base.resource, user_buffer_for_level,
185*61046927SAndroid Build Coastguard Worker                               D3DRTYPE_TEXTURE, l, 0,
186*61046927SAndroid Build Coastguard Worker                               &sfdesc, &This->surfaces[l]);
187*61046927SAndroid Build Coastguard Worker         if (FAILED(hr))
188*61046927SAndroid Build Coastguard Worker             return hr;
189*61046927SAndroid Build Coastguard Worker     }
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker     /* Textures start initially dirty */
192*61046927SAndroid Build Coastguard Worker     This->dirty_rect.width = Width;
193*61046927SAndroid Build Coastguard Worker     This->dirty_rect.height = Height;
194*61046927SAndroid Build Coastguard Worker     This->dirty_rect.depth = 1; /* width == 0 means empty, depth stays 1 */
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker     if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */
197*61046927SAndroid Build Coastguard Worker         *pSharedHandle = This->surfaces[0]->data;
198*61046927SAndroid Build Coastguard Worker     }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker     return D3D_OK;
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker static void
NineTexture9_dtor(struct NineTexture9 * This)204*61046927SAndroid Build Coastguard Worker NineTexture9_dtor( struct NineTexture9 *This )
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker     bool is_worker = nine_context_is_worker(This->base.base.base.device);
207*61046927SAndroid Build Coastguard Worker     unsigned l;
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker     DBG("This=%p\n", This);
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker     if (This->surfaces) {
212*61046927SAndroid Build Coastguard Worker         /* The surfaces should have 0 references and be unbound now. */
213*61046927SAndroid Build Coastguard Worker         for (l = 0; l < This->base.level_count; ++l)
214*61046927SAndroid Build Coastguard Worker             if (This->surfaces[l])
215*61046927SAndroid Build Coastguard Worker                 NineUnknown_Destroy(&This->surfaces[l]->base.base);
216*61046927SAndroid Build Coastguard Worker         FREE(This->surfaces);
217*61046927SAndroid Build Coastguard Worker     }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker     if (This->managed_buffer) {
220*61046927SAndroid Build Coastguard Worker         if (is_worker)
221*61046927SAndroid Build Coastguard Worker             nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer);
222*61046927SAndroid Build Coastguard Worker         else
223*61046927SAndroid Build Coastguard Worker             nine_free(This->base.base.base.device->allocator, This->managed_buffer);
224*61046927SAndroid Build Coastguard Worker     }
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker     NineBaseTexture9_dtor(&This->base);
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NineTexture9_GetLevelDesc(struct NineTexture9 * This,UINT Level,D3DSURFACE_DESC * pDesc)230*61046927SAndroid Build Coastguard Worker NineTexture9_GetLevelDesc( struct NineTexture9 *This,
231*61046927SAndroid Build Coastguard Worker                            UINT Level,
232*61046927SAndroid Build Coastguard Worker                            D3DSURFACE_DESC *pDesc )
233*61046927SAndroid Build Coastguard Worker {
234*61046927SAndroid Build Coastguard Worker     DBG("This=%p Level=%d pDesc=%p\n", This, Level, pDesc);
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker     user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
237*61046927SAndroid Build Coastguard Worker     user_assert(pDesc, D3DERR_INVALIDCALL);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker     *pDesc = This->surfaces[Level]->desc;
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker     return D3D_OK;
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NineTexture9_GetSurfaceLevel(struct NineTexture9 * This,UINT Level,IDirect3DSurface9 ** ppSurfaceLevel)245*61046927SAndroid Build Coastguard Worker NineTexture9_GetSurfaceLevel( struct NineTexture9 *This,
246*61046927SAndroid Build Coastguard Worker                               UINT Level,
247*61046927SAndroid Build Coastguard Worker                               IDirect3DSurface9 **ppSurfaceLevel )
248*61046927SAndroid Build Coastguard Worker {
249*61046927SAndroid Build Coastguard Worker     DBG("This=%p Level=%d ppSurfaceLevel=%p\n", This, Level, ppSurfaceLevel);
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker     user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
252*61046927SAndroid Build Coastguard Worker     user_assert(ppSurfaceLevel, D3DERR_INVALIDCALL);
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker     NineUnknown_AddRef(NineUnknown(This->surfaces[Level]));
255*61046927SAndroid Build Coastguard Worker     *ppSurfaceLevel = (IDirect3DSurface9 *)This->surfaces[Level];
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker     return D3D_OK;
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NineTexture9_LockRect(struct NineTexture9 * This,UINT Level,D3DLOCKED_RECT * pLockedRect,const RECT * pRect,DWORD Flags)261*61046927SAndroid Build Coastguard Worker NineTexture9_LockRect( struct NineTexture9 *This,
262*61046927SAndroid Build Coastguard Worker                        UINT Level,
263*61046927SAndroid Build Coastguard Worker                        D3DLOCKED_RECT *pLockedRect,
264*61046927SAndroid Build Coastguard Worker                        const RECT *pRect,
265*61046927SAndroid Build Coastguard Worker                        DWORD Flags )
266*61046927SAndroid Build Coastguard Worker {
267*61046927SAndroid Build Coastguard Worker     DBG("This=%p Level=%u pLockedRect=%p pRect=%p Flags=%d\n",
268*61046927SAndroid Build Coastguard Worker         This, Level, pLockedRect, pRect, Flags);
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker     user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker     return NineSurface9_LockRect(This->surfaces[Level], pLockedRect,
273*61046927SAndroid Build Coastguard Worker                                  pRect, Flags);
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NineTexture9_UnlockRect(struct NineTexture9 * This,UINT Level)277*61046927SAndroid Build Coastguard Worker NineTexture9_UnlockRect( struct NineTexture9 *This,
278*61046927SAndroid Build Coastguard Worker                          UINT Level )
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker     DBG("This=%p Level=%u\n", This, Level);
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker     user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker     return NineSurface9_UnlockRect(This->surfaces[Level]);
285*61046927SAndroid Build Coastguard Worker }
286*61046927SAndroid Build Coastguard Worker 
287*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NineTexture9_AddDirtyRect(struct NineTexture9 * This,const RECT * pDirtyRect)288*61046927SAndroid Build Coastguard Worker NineTexture9_AddDirtyRect( struct NineTexture9 *This,
289*61046927SAndroid Build Coastguard Worker                            const RECT *pDirtyRect )
290*61046927SAndroid Build Coastguard Worker {
291*61046927SAndroid Build Coastguard Worker     DBG("This=%p pDirtyRect=%p[(%u,%u)-(%u,%u)]\n", This, pDirtyRect,
292*61046927SAndroid Build Coastguard Worker         pDirtyRect ? pDirtyRect->left : 0, pDirtyRect ? pDirtyRect->top : 0,
293*61046927SAndroid Build Coastguard Worker         pDirtyRect ? pDirtyRect->right : 0, pDirtyRect ? pDirtyRect->bottom : 0);
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker     /* Tracking dirty regions on DEFAULT resources is pointless,
296*61046927SAndroid Build Coastguard Worker      * because we always write to the final storage. Just marked it dirty in
297*61046927SAndroid Build Coastguard Worker      * case we need to generate mip maps.
298*61046927SAndroid Build Coastguard Worker      */
299*61046927SAndroid Build Coastguard Worker     if (This->base.base.pool == D3DPOOL_DEFAULT) {
300*61046927SAndroid Build Coastguard Worker         if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) {
301*61046927SAndroid Build Coastguard Worker             This->base.dirty_mip = true;
302*61046927SAndroid Build Coastguard Worker             BASETEX_REGISTER_UPDATE(&This->base);
303*61046927SAndroid Build Coastguard Worker         }
304*61046927SAndroid Build Coastguard Worker         return D3D_OK;
305*61046927SAndroid Build Coastguard Worker     }
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker     if (This->base.base.pool == D3DPOOL_MANAGED) {
308*61046927SAndroid Build Coastguard Worker         This->base.managed.dirty = true;
309*61046927SAndroid Build Coastguard Worker         BASETEX_REGISTER_UPDATE(&This->base);
310*61046927SAndroid Build Coastguard Worker     }
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker     if (!pDirtyRect) {
313*61046927SAndroid Build Coastguard Worker         u_box_origin_2d(This->base.base.info.width0,
314*61046927SAndroid Build Coastguard Worker                         This->base.base.info.height0, &This->dirty_rect);
315*61046927SAndroid Build Coastguard Worker     } else {
316*61046927SAndroid Build Coastguard Worker         if (This->dirty_rect.width == 0) {
317*61046927SAndroid Build Coastguard Worker             rect_to_pipe_box_clamp(&This->dirty_rect, pDirtyRect);
318*61046927SAndroid Build Coastguard Worker         } else {
319*61046927SAndroid Build Coastguard Worker             struct pipe_box box;
320*61046927SAndroid Build Coastguard Worker             rect_to_pipe_box_clamp(&box, pDirtyRect);
321*61046927SAndroid Build Coastguard Worker             u_box_union_2d(&This->dirty_rect, &This->dirty_rect, &box);
322*61046927SAndroid Build Coastguard Worker         }
323*61046927SAndroid Build Coastguard Worker         (void) u_box_clip_2d(&This->dirty_rect, &This->dirty_rect,
324*61046927SAndroid Build Coastguard Worker                              This->base.base.info.width0,
325*61046927SAndroid Build Coastguard Worker                              This->base.base.info.height0);
326*61046927SAndroid Build Coastguard Worker     }
327*61046927SAndroid Build Coastguard Worker     return D3D_OK;
328*61046927SAndroid Build Coastguard Worker }
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker IDirect3DTexture9Vtbl NineTexture9_vtable = {
331*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_QueryInterface,
332*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_AddRef,
333*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_Release,
334*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */
335*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_SetPrivateData,
336*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_GetPrivateData,
337*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_FreePrivateData,
338*61046927SAndroid Build Coastguard Worker     (void *)NineResource9_SetPriority,
339*61046927SAndroid Build Coastguard Worker     (void *)NineResource9_GetPriority,
340*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_PreLoad,
341*61046927SAndroid Build Coastguard Worker     (void *)NineResource9_GetType,
342*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_SetLOD,
343*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_GetLOD,
344*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_GetLevelCount,
345*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_SetAutoGenFilterType,
346*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_GetAutoGenFilterType,
347*61046927SAndroid Build Coastguard Worker     (void *)NineBaseTexture9_GenerateMipSubLevels,
348*61046927SAndroid Build Coastguard Worker     (void *)NineTexture9_GetLevelDesc,
349*61046927SAndroid Build Coastguard Worker     (void *)NineTexture9_GetSurfaceLevel,
350*61046927SAndroid Build Coastguard Worker     (void *)NineTexture9_LockRect,
351*61046927SAndroid Build Coastguard Worker     (void *)NineTexture9_UnlockRect,
352*61046927SAndroid Build Coastguard Worker     (void *)NineTexture9_AddDirtyRect
353*61046927SAndroid Build Coastguard Worker };
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker static const GUID *NineTexture9_IIDs[] = {
356*61046927SAndroid Build Coastguard Worker     &IID_IDirect3DTexture9,
357*61046927SAndroid Build Coastguard Worker     &IID_IDirect3DBaseTexture9,
358*61046927SAndroid Build Coastguard Worker     &IID_IDirect3DResource9,
359*61046927SAndroid Build Coastguard Worker     &IID_IUnknown,
360*61046927SAndroid Build Coastguard Worker     NULL
361*61046927SAndroid Build Coastguard Worker };
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker HRESULT
NineTexture9_new(struct NineDevice9 * pDevice,UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,struct NineTexture9 ** ppOut,HANDLE * pSharedHandle)364*61046927SAndroid Build Coastguard Worker NineTexture9_new( struct NineDevice9 *pDevice,
365*61046927SAndroid Build Coastguard Worker                   UINT Width, UINT Height, UINT Levels,
366*61046927SAndroid Build Coastguard Worker                   DWORD Usage,
367*61046927SAndroid Build Coastguard Worker                   D3DFORMAT Format,
368*61046927SAndroid Build Coastguard Worker                   D3DPOOL Pool,
369*61046927SAndroid Build Coastguard Worker                   struct NineTexture9 **ppOut,
370*61046927SAndroid Build Coastguard Worker                   HANDLE *pSharedHandle )
371*61046927SAndroid Build Coastguard Worker {
372*61046927SAndroid Build Coastguard Worker     NINE_DEVICE_CHILD_NEW(Texture9, ppOut, pDevice,
373*61046927SAndroid Build Coastguard Worker                           Width, Height, Levels,
374*61046927SAndroid Build Coastguard Worker                           Usage, Format, Pool, pSharedHandle);
375*61046927SAndroid Build Coastguard Worker }
376