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