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 "resource9.h"
7*61046927SAndroid Build Coastguard Worker #include "device9.h"
8*61046927SAndroid Build Coastguard Worker #include "nine_helpers.h"
9*61046927SAndroid Build Coastguard Worker #include "nine_defines.h"
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "util/u_inlines.h"
12*61046927SAndroid Build Coastguard Worker #include "util/u_resource.h"
13*61046927SAndroid Build Coastguard Worker
14*61046927SAndroid Build Coastguard Worker #include "pipe/p_screen.h"
15*61046927SAndroid Build Coastguard Worker
16*61046927SAndroid Build Coastguard Worker #define DBG_CHANNEL DBG_RESOURCE
17*61046927SAndroid Build Coastguard Worker
18*61046927SAndroid Build Coastguard Worker HRESULT
NineResource9_ctor(struct NineResource9 * This,struct NineUnknownParams * pParams,struct pipe_resource * initResource,BOOL Allocate,D3DRESOURCETYPE Type,D3DPOOL Pool,DWORD Usage)19*61046927SAndroid Build Coastguard Worker NineResource9_ctor( struct NineResource9 *This,
20*61046927SAndroid Build Coastguard Worker struct NineUnknownParams *pParams,
21*61046927SAndroid Build Coastguard Worker struct pipe_resource *initResource,
22*61046927SAndroid Build Coastguard Worker BOOL Allocate,
23*61046927SAndroid Build Coastguard Worker D3DRESOURCETYPE Type,
24*61046927SAndroid Build Coastguard Worker D3DPOOL Pool,
25*61046927SAndroid Build Coastguard Worker DWORD Usage)
26*61046927SAndroid Build Coastguard Worker {
27*61046927SAndroid Build Coastguard Worker struct pipe_screen *screen;
28*61046927SAndroid Build Coastguard Worker HRESULT hr;
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker DBG("This=%p pParams=%p initResource=%p Allocate=%d "
31*61046927SAndroid Build Coastguard Worker "Type=%d Pool=%d Usage=%d\n",
32*61046927SAndroid Build Coastguard Worker This, pParams, initResource, (int) Allocate,
33*61046927SAndroid Build Coastguard Worker Type, Pool, Usage);
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker hr = NineUnknown_ctor(&This->base, pParams);
36*61046927SAndroid Build Coastguard Worker if (FAILED(hr))
37*61046927SAndroid Build Coastguard Worker return hr;
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker This->info.screen = screen = This->base.device->screen;
40*61046927SAndroid Build Coastguard Worker if (initResource)
41*61046927SAndroid Build Coastguard Worker pipe_resource_reference(&This->resource, initResource);
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker if (Allocate) {
44*61046927SAndroid Build Coastguard Worker assert(!initResource);
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker /* On Windows it is possible allocation fails when
47*61046927SAndroid Build Coastguard Worker * IDirect3DDevice9::GetAvailableTextureMem() still reports
48*61046927SAndroid Build Coastguard Worker * enough free space.
49*61046927SAndroid Build Coastguard Worker *
50*61046927SAndroid Build Coastguard Worker * Some games allocate surfaces
51*61046927SAndroid Build Coastguard Worker * in a loop until they receive D3DERR_OUTOFVIDEOMEMORY to measure
52*61046927SAndroid Build Coastguard Worker * the available texture memory size.
53*61046927SAndroid Build Coastguard Worker *
54*61046927SAndroid Build Coastguard Worker * We are not using the drivers VRAM statistics because:
55*61046927SAndroid Build Coastguard Worker * * This would add overhead to each resource allocation.
56*61046927SAndroid Build Coastguard Worker * * Freeing memory is lazy and takes some time, but applications
57*61046927SAndroid Build Coastguard Worker * expects the memory counter to change immediately after allocating
58*61046927SAndroid Build Coastguard Worker * or freeing memory.
59*61046927SAndroid Build Coastguard Worker *
60*61046927SAndroid Build Coastguard Worker * Vertexbuffers and indexbuffers are not accounted !
61*61046927SAndroid Build Coastguard Worker */
62*61046927SAndroid Build Coastguard Worker if (This->info.target != PIPE_BUFFER) {
63*61046927SAndroid Build Coastguard Worker This->size = util_resource_size(&This->info);
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker p_atomic_add(&This->base.device->available_texture_mem, -This->size);
66*61046927SAndroid Build Coastguard Worker /* Before failing allocation, evict MANAGED memory */
67*61046927SAndroid Build Coastguard Worker if (This->base.device &&
68*61046927SAndroid Build Coastguard Worker p_atomic_read(&This->base.device->available_texture_mem) <=
69*61046927SAndroid Build Coastguard Worker This->base.device->available_texture_limit)
70*61046927SAndroid Build Coastguard Worker NineDevice9_EvictManagedResourcesInternal(This->base.device);
71*61046927SAndroid Build Coastguard Worker if (p_atomic_read(&This->base.device->available_texture_mem) <=
72*61046927SAndroid Build Coastguard Worker This->base.device->available_texture_limit) {
73*61046927SAndroid Build Coastguard Worker DBG("Memory allocation failure: software limit\n");
74*61046927SAndroid Build Coastguard Worker return D3DERR_OUTOFVIDEOMEMORY;
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker }
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker DBG("(%p) Creating pipe_resource.\n", This);
79*61046927SAndroid Build Coastguard Worker This->resource = nine_resource_create_with_retry(This->base.device, screen, &This->info);
80*61046927SAndroid Build Coastguard Worker if (!This->resource)
81*61046927SAndroid Build Coastguard Worker return D3DERR_OUTOFVIDEOMEMORY;
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker DBG("Current texture memory count: (%d/%d)KB\n",
85*61046927SAndroid Build Coastguard Worker (int)(This->base.device->available_texture_mem >> 10),
86*61046927SAndroid Build Coastguard Worker (int)(This->base.device->available_texture_limit >> 10));
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker This->type = Type;
89*61046927SAndroid Build Coastguard Worker This->pool = Pool;
90*61046927SAndroid Build Coastguard Worker This->usage = Usage;
91*61046927SAndroid Build Coastguard Worker This->priority = 0;
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker return D3D_OK;
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker void
NineResource9_dtor(struct NineResource9 * This)97*61046927SAndroid Build Coastguard Worker NineResource9_dtor( struct NineResource9 *This )
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker DBG("This=%p\n", This);
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker /* NOTE: We do have to use refcounting, the driver might
102*61046927SAndroid Build Coastguard Worker * still hold a reference. */
103*61046927SAndroid Build Coastguard Worker pipe_resource_reference(&This->resource, NULL);
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker /* NOTE: size is 0, unless something has actually been allocated */
106*61046927SAndroid Build Coastguard Worker if (This->base.device)
107*61046927SAndroid Build Coastguard Worker p_atomic_add(&This->base.device->available_texture_mem, This->size);
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker NineUnknown_dtor(&This->base);
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker struct pipe_resource *
NineResource9_GetResource(struct NineResource9 * This)113*61046927SAndroid Build Coastguard Worker NineResource9_GetResource( struct NineResource9 *This )
114*61046927SAndroid Build Coastguard Worker {
115*61046927SAndroid Build Coastguard Worker return This->resource;
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker D3DPOOL
NineResource9_GetPool(struct NineResource9 * This)119*61046927SAndroid Build Coastguard Worker NineResource9_GetPool( struct NineResource9 *This )
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker return This->pool;
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker DWORD NINE_WINAPI
NineResource9_SetPriority(struct NineResource9 * This,DWORD PriorityNew)125*61046927SAndroid Build Coastguard Worker NineResource9_SetPriority( struct NineResource9 *This,
126*61046927SAndroid Build Coastguard Worker DWORD PriorityNew )
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker DWORD prev;
129*61046927SAndroid Build Coastguard Worker DBG("This=%p, PriorityNew=%d\n", This, PriorityNew);
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
132*61046927SAndroid Build Coastguard Worker return 0;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker prev = This->priority;
135*61046927SAndroid Build Coastguard Worker This->priority = PriorityNew;
136*61046927SAndroid Build Coastguard Worker return prev;
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker DWORD NINE_WINAPI
NineResource9_GetPriority(struct NineResource9 * This)140*61046927SAndroid Build Coastguard Worker NineResource9_GetPriority( struct NineResource9 *This )
141*61046927SAndroid Build Coastguard Worker {
142*61046927SAndroid Build Coastguard Worker if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
143*61046927SAndroid Build Coastguard Worker return 0;
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker return This->priority;
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker /* NOTE: Don't forget to adjust locked vtable if you change this ! */
149*61046927SAndroid Build Coastguard Worker void NINE_WINAPI
NineResource9_PreLoad(struct NineResource9 * This)150*61046927SAndroid Build Coastguard Worker NineResource9_PreLoad( struct NineResource9 *This )
151*61046927SAndroid Build Coastguard Worker {
152*61046927SAndroid Build Coastguard Worker if (This->pool != D3DPOOL_MANAGED)
153*61046927SAndroid Build Coastguard Worker return;
154*61046927SAndroid Build Coastguard Worker /* We don't treat managed vertex or index buffers different from
155*61046927SAndroid Build Coastguard Worker * default ones (are managed vertex buffers even allowed ?), and
156*61046927SAndroid Build Coastguard Worker * the PreLoad for textures is overridden by superclass.
157*61046927SAndroid Build Coastguard Worker */
158*61046927SAndroid Build Coastguard Worker }
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker D3DRESOURCETYPE NINE_WINAPI
NineResource9_GetType(struct NineResource9 * This)161*61046927SAndroid Build Coastguard Worker NineResource9_GetType( struct NineResource9 *This )
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker return This->type;
164*61046927SAndroid Build Coastguard Worker }
165