xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/nine/pixelshader9.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 "nine_helpers.h"
7*61046927SAndroid Build Coastguard Worker #include "nine_shader.h"
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "pixelshader9.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "device9.h"
12*61046927SAndroid Build Coastguard Worker #include "pipe/p_context.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker #define DBG_CHANNEL DBG_PIXELSHADER
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker HRESULT
NinePixelShader9_ctor(struct NinePixelShader9 * This,struct NineUnknownParams * pParams,const DWORD * pFunction,void * cso)17*61046927SAndroid Build Coastguard Worker NinePixelShader9_ctor( struct NinePixelShader9 *This,
18*61046927SAndroid Build Coastguard Worker                        struct NineUnknownParams *pParams,
19*61046927SAndroid Build Coastguard Worker                        const DWORD *pFunction, void *cso )
20*61046927SAndroid Build Coastguard Worker {
21*61046927SAndroid Build Coastguard Worker     struct NineDevice9 *device;
22*61046927SAndroid Build Coastguard Worker     struct nine_shader_info info;
23*61046927SAndroid Build Coastguard Worker     struct pipe_context *pipe;
24*61046927SAndroid Build Coastguard Worker     HRESULT hr;
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker     DBG("This=%p pParams=%p pFunction=%p cso=%p\n", This, pParams, pFunction, cso);
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker     hr = NineUnknown_ctor(&This->base, pParams);
29*61046927SAndroid Build Coastguard Worker     if (FAILED(hr))
30*61046927SAndroid Build Coastguard Worker         return hr;
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker     if (cso) {
33*61046927SAndroid Build Coastguard Worker         This->ff_cso = cso;
34*61046927SAndroid Build Coastguard Worker         return D3D_OK;
35*61046927SAndroid Build Coastguard Worker     }
36*61046927SAndroid Build Coastguard Worker     device = This->base.device;
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker     info.type = PIPE_SHADER_FRAGMENT;
39*61046927SAndroid Build Coastguard Worker     info.byte_code = pFunction;
40*61046927SAndroid Build Coastguard Worker     info.const_i_base = NINE_CONST_I_BASE(NINE_MAX_CONST_F_PS3) / 16;
41*61046927SAndroid Build Coastguard Worker     info.const_b_base = NINE_CONST_B_BASE(NINE_MAX_CONST_F_PS3) / 16;
42*61046927SAndroid Build Coastguard Worker     info.sampler_mask_shadow = 0x0;
43*61046927SAndroid Build Coastguard Worker     info.fetch4 = 0x0;
44*61046927SAndroid Build Coastguard Worker     info.force_color_in_centroid = 0;
45*61046927SAndroid Build Coastguard Worker     info.sampler_ps1xtypes = 0x0;
46*61046927SAndroid Build Coastguard Worker     info.fog_enable = 0;
47*61046927SAndroid Build Coastguard Worker     info.projected = 0;
48*61046927SAndroid Build Coastguard Worker     info.alpha_test_emulation = 0;
49*61046927SAndroid Build Coastguard Worker     info.color_flatshade = 0;
50*61046927SAndroid Build Coastguard Worker     info.add_constants_defs.c_combination = NULL;
51*61046927SAndroid Build Coastguard Worker     info.add_constants_defs.int_const_added = NULL;
52*61046927SAndroid Build Coastguard Worker     info.add_constants_defs.bool_const_added = NULL;
53*61046927SAndroid Build Coastguard Worker     info.process_vertices = false;
54*61046927SAndroid Build Coastguard Worker     info.swvp_on = false;
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker     pipe = nine_context_get_pipe_acquire(device);
57*61046927SAndroid Build Coastguard Worker     hr = nine_translate_shader(device, &info, pipe);
58*61046927SAndroid Build Coastguard Worker     nine_context_get_pipe_release(device);
59*61046927SAndroid Build Coastguard Worker     if (FAILED(hr))
60*61046927SAndroid Build Coastguard Worker         return hr;
61*61046927SAndroid Build Coastguard Worker     This->byte_code.version = info.version;
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker     This->byte_code.tokens = mem_dup(pFunction, info.byte_size);
64*61046927SAndroid Build Coastguard Worker     if (!This->byte_code.tokens)
65*61046927SAndroid Build Coastguard Worker         return E_OUTOFMEMORY;
66*61046927SAndroid Build Coastguard Worker     This->byte_code.size = info.byte_size;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker     This->variant.cso = info.cso;
69*61046927SAndroid Build Coastguard Worker     This->variant.const_ranges = info.const_ranges;
70*61046927SAndroid Build Coastguard Worker     This->variant.const_used_size = info.const_used_size;
71*61046927SAndroid Build Coastguard Worker     This->last_cso = info.cso;
72*61046927SAndroid Build Coastguard Worker     This->last_const_ranges = info.const_ranges;
73*61046927SAndroid Build Coastguard Worker     This->last_const_used_size = info.const_used_size;
74*61046927SAndroid Build Coastguard Worker     This->last_key = 0;
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker     This->sampler_mask = info.sampler_mask;
77*61046927SAndroid Build Coastguard Worker     This->rt_mask = info.rt_mask;
78*61046927SAndroid Build Coastguard Worker     This->bumpenvmat_needed = info.bumpenvmat_needed;
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker     memcpy(This->int_slots_used, info.int_slots_used, sizeof(This->int_slots_used));
81*61046927SAndroid Build Coastguard Worker     memcpy(This->bool_slots_used, info.bool_slots_used, sizeof(This->bool_slots_used));
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker     This->const_int_slots = info.const_int_slots;
84*61046927SAndroid Build Coastguard Worker     This->const_bool_slots = info.const_bool_slots;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker     This->c_combinations = NULL;
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker     /* no constant relative addressing for ps */
89*61046927SAndroid Build Coastguard Worker     assert(info.lconstf.data == NULL);
90*61046927SAndroid Build Coastguard Worker     assert(info.lconstf.ranges == NULL);
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker     return D3D_OK;
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker void
NinePixelShader9_dtor(struct NinePixelShader9 * This)96*61046927SAndroid Build Coastguard Worker NinePixelShader9_dtor( struct NinePixelShader9 *This )
97*61046927SAndroid Build Coastguard Worker {
98*61046927SAndroid Build Coastguard Worker     DBG("This=%p\n", This);
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker     if (This->base.device) {
101*61046927SAndroid Build Coastguard Worker         struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device);
102*61046927SAndroid Build Coastguard Worker         struct nine_shader_variant *var = &This->variant;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker         do {
105*61046927SAndroid Build Coastguard Worker             if (var->cso) {
106*61046927SAndroid Build Coastguard Worker                 if (This->base.device->context.cso_shader.ps == var->cso) {
107*61046927SAndroid Build Coastguard Worker                     /* unbind because it is illegal to delete something bound */
108*61046927SAndroid Build Coastguard Worker                     pipe->bind_fs_state(pipe, NULL);
109*61046927SAndroid Build Coastguard Worker                     /* This will rebind cso_shader.ps in case somehow actually
110*61046927SAndroid Build Coastguard Worker                      * an identical shader with same cso is bound */
111*61046927SAndroid Build Coastguard Worker                     This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
112*61046927SAndroid Build Coastguard Worker                 }
113*61046927SAndroid Build Coastguard Worker                 pipe->delete_fs_state(pipe, var->cso);
114*61046927SAndroid Build Coastguard Worker                 FREE(var->const_ranges);
115*61046927SAndroid Build Coastguard Worker             }
116*61046927SAndroid Build Coastguard Worker             var = var->next;
117*61046927SAndroid Build Coastguard Worker         } while (var);
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker         if (This->ff_cso) {
120*61046927SAndroid Build Coastguard Worker             if (This->ff_cso == This->base.device->context.cso_shader.ps) {
121*61046927SAndroid Build Coastguard Worker                 pipe->bind_fs_state(pipe, NULL);
122*61046927SAndroid Build Coastguard Worker                 This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
123*61046927SAndroid Build Coastguard Worker             }
124*61046927SAndroid Build Coastguard Worker             pipe->delete_fs_state(pipe, This->ff_cso);
125*61046927SAndroid Build Coastguard Worker         }
126*61046927SAndroid Build Coastguard Worker     }
127*61046927SAndroid Build Coastguard Worker     nine_shader_variants_free(&This->variant);
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker     nine_shader_constant_combination_free(This->c_combinations);
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker     FREE((void *)This->byte_code.tokens); /* const_cast */
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker     NineUnknown_dtor(&This->base);
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker HRESULT NINE_WINAPI
NinePixelShader9_GetFunction(struct NinePixelShader9 * This,void * pData,UINT * pSizeOfData)137*61046927SAndroid Build Coastguard Worker NinePixelShader9_GetFunction( struct NinePixelShader9 *This,
138*61046927SAndroid Build Coastguard Worker                               void *pData,
139*61046927SAndroid Build Coastguard Worker                               UINT *pSizeOfData )
140*61046927SAndroid Build Coastguard Worker {
141*61046927SAndroid Build Coastguard Worker     DBG("This=%p pData=%p pSizeOfData=%p\n", This, pData, pSizeOfData);
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker     user_assert(pSizeOfData, D3DERR_INVALIDCALL);
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker     if (!pData) {
146*61046927SAndroid Build Coastguard Worker         *pSizeOfData = This->byte_code.size;
147*61046927SAndroid Build Coastguard Worker         return D3D_OK;
148*61046927SAndroid Build Coastguard Worker     }
149*61046927SAndroid Build Coastguard Worker     user_assert(*pSizeOfData >= This->byte_code.size, D3DERR_INVALIDCALL);
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker     memcpy(pData, This->byte_code.tokens, This->byte_code.size);
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker     return D3D_OK;
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker void *
NinePixelShader9_GetVariant(struct NinePixelShader9 * This,unsigned ** const_ranges,unsigned * const_used_size)157*61046927SAndroid Build Coastguard Worker NinePixelShader9_GetVariant( struct NinePixelShader9 *This,
158*61046927SAndroid Build Coastguard Worker                              unsigned **const_ranges,
159*61046927SAndroid Build Coastguard Worker                              unsigned *const_used_size )
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker     /* GetVariant is called from nine_context, thus we can
162*61046927SAndroid Build Coastguard Worker      * get pipe directly */
163*61046927SAndroid Build Coastguard Worker     struct pipe_context *pipe = This->base.device->context.pipe;
164*61046927SAndroid Build Coastguard Worker     void *cso;
165*61046927SAndroid Build Coastguard Worker     uint64_t key;
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker     key = This->next_key;
168*61046927SAndroid Build Coastguard Worker     if (key == This->last_key) {
169*61046927SAndroid Build Coastguard Worker         *const_ranges = This->last_const_ranges;
170*61046927SAndroid Build Coastguard Worker         *const_used_size = This->last_const_used_size;
171*61046927SAndroid Build Coastguard Worker         return This->last_cso;
172*61046927SAndroid Build Coastguard Worker     }
173*61046927SAndroid Build Coastguard Worker 
174*61046927SAndroid Build Coastguard Worker     cso = nine_shader_variant_get(&This->variant, const_ranges, const_used_size, key);
175*61046927SAndroid Build Coastguard Worker     if (!cso) {
176*61046927SAndroid Build Coastguard Worker         struct NineDevice9 *device = This->base.device;
177*61046927SAndroid Build Coastguard Worker         struct nine_shader_info info;
178*61046927SAndroid Build Coastguard Worker         HRESULT hr;
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker         info.type = PIPE_SHADER_FRAGMENT;
181*61046927SAndroid Build Coastguard Worker         info.const_i_base = NINE_CONST_I_BASE(NINE_MAX_CONST_F_PS3) / 16;
182*61046927SAndroid Build Coastguard Worker         info.const_b_base = NINE_CONST_B_BASE(NINE_MAX_CONST_F_PS3) / 16;
183*61046927SAndroid Build Coastguard Worker         info.byte_code = This->byte_code.tokens;
184*61046927SAndroid Build Coastguard Worker         info.sampler_mask_shadow = key & 0xffff;
185*61046927SAndroid Build Coastguard Worker         /* intended overlap with sampler_mask_shadow */
186*61046927SAndroid Build Coastguard Worker         if (unlikely(This->byte_code.version < 0x20)) {
187*61046927SAndroid Build Coastguard Worker             if (This->byte_code.version < 0x14) {
188*61046927SAndroid Build Coastguard Worker                 info.sampler_ps1xtypes = (key >> 4) & 0xff;
189*61046927SAndroid Build Coastguard Worker                 info.projected = (key >> 12) & 0xff;
190*61046927SAndroid Build Coastguard Worker             } else {
191*61046927SAndroid Build Coastguard Worker                 info.sampler_ps1xtypes = (key >> 6) & 0xfff;
192*61046927SAndroid Build Coastguard Worker                 info.projected = 0;
193*61046927SAndroid Build Coastguard Worker             }
194*61046927SAndroid Build Coastguard Worker         } else {
195*61046927SAndroid Build Coastguard Worker             info.sampler_ps1xtypes = 0;
196*61046927SAndroid Build Coastguard Worker             info.projected = 0;
197*61046927SAndroid Build Coastguard Worker         }
198*61046927SAndroid Build Coastguard Worker         info.fog_enable = device->context.rs[D3DRS_FOGENABLE];
199*61046927SAndroid Build Coastguard Worker         info.fog_mode = device->context.rs[D3DRS_FOGTABLEMODE];
200*61046927SAndroid Build Coastguard Worker         info.zfog = device->context.zfog;
201*61046927SAndroid Build Coastguard Worker         info.add_constants_defs.c_combination =
202*61046927SAndroid Build Coastguard Worker             nine_shader_constant_combination_get(This->c_combinations, (key >> 24) & 0xff);
203*61046927SAndroid Build Coastguard Worker         info.add_constants_defs.int_const_added = &This->int_slots_used;
204*61046927SAndroid Build Coastguard Worker         info.add_constants_defs.bool_const_added = &This->bool_slots_used;
205*61046927SAndroid Build Coastguard Worker         info.fetch4 = (key >> 32) & 0xffff;
206*61046927SAndroid Build Coastguard Worker         info.force_color_in_centroid = (key >> 48) & 1;
207*61046927SAndroid Build Coastguard Worker         info.alpha_test_emulation = (key >> 49) & 0x7;
208*61046927SAndroid Build Coastguard Worker         info.color_flatshade = (key >> 52) & 1;
209*61046927SAndroid Build Coastguard Worker         info.force_color_in_centroid &= !info.color_flatshade; /* centroid doesn't make sense with flatshade */
210*61046927SAndroid Build Coastguard Worker         info.process_vertices = false;
211*61046927SAndroid Build Coastguard Worker         info.swvp_on = false;
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker         hr = nine_translate_shader(This->base.device, &info, pipe);
214*61046927SAndroid Build Coastguard Worker         if (FAILED(hr))
215*61046927SAndroid Build Coastguard Worker             return NULL;
216*61046927SAndroid Build Coastguard Worker         nine_shader_variant_add(&This->variant, key, info.cso,
217*61046927SAndroid Build Coastguard Worker                                 info.const_ranges, info.const_used_size);
218*61046927SAndroid Build Coastguard Worker         cso = info.cso;
219*61046927SAndroid Build Coastguard Worker         *const_ranges = info.const_ranges;
220*61046927SAndroid Build Coastguard Worker         *const_used_size = info.const_used_size;
221*61046927SAndroid Build Coastguard Worker     }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker     This->last_key = key;
224*61046927SAndroid Build Coastguard Worker     This->last_cso = cso;
225*61046927SAndroid Build Coastguard Worker     This->last_const_ranges = *const_ranges;
226*61046927SAndroid Build Coastguard Worker     This->last_const_used_size = *const_used_size;
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker     return cso;
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker IDirect3DPixelShader9Vtbl NinePixelShader9_vtable = {
232*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_QueryInterface,
233*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_AddRef,
234*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_Release,
235*61046927SAndroid Build Coastguard Worker     (void *)NineUnknown_GetDevice,
236*61046927SAndroid Build Coastguard Worker     (void *)NinePixelShader9_GetFunction
237*61046927SAndroid Build Coastguard Worker };
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker static const GUID *NinePixelShader9_IIDs[] = {
240*61046927SAndroid Build Coastguard Worker     &IID_IDirect3DPixelShader9,
241*61046927SAndroid Build Coastguard Worker     &IID_IUnknown,
242*61046927SAndroid Build Coastguard Worker     NULL
243*61046927SAndroid Build Coastguard Worker };
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker HRESULT
NinePixelShader9_new(struct NineDevice9 * pDevice,struct NinePixelShader9 ** ppOut,const DWORD * pFunction,void * cso)246*61046927SAndroid Build Coastguard Worker NinePixelShader9_new( struct NineDevice9 *pDevice,
247*61046927SAndroid Build Coastguard Worker                       struct NinePixelShader9 **ppOut,
248*61046927SAndroid Build Coastguard Worker                       const DWORD *pFunction, void *cso )
249*61046927SAndroid Build Coastguard Worker {
250*61046927SAndroid Build Coastguard Worker     if (cso) { /* ff shader. Needs to start with bind count */
251*61046927SAndroid Build Coastguard Worker         NINE_DEVICE_CHILD_BIND_NEW(PixelShader9, ppOut, pDevice, pFunction, cso);
252*61046927SAndroid Build Coastguard Worker     } else {
253*61046927SAndroid Build Coastguard Worker         NINE_DEVICE_CHILD_NEW(PixelShader9, ppOut, pDevice, pFunction, cso);
254*61046927SAndroid Build Coastguard Worker     }
255*61046927SAndroid Build Coastguard Worker }
256