xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_pipe_vertex.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "pipe/p_defines.h"
9 #include "util/u_bitmask.h"
10 #include "util/format/u_format.h"
11 #include "util/u_helpers.h"
12 #include "util/u_inlines.h"
13 #include "util/u_math.h"
14 #include "util/u_memory.h"
15 #include "util/u_transfer.h"
16 
17 #include "svga_context.h"
18 #include "svga_cmd.h"
19 #include "svga_format.h"
20 #include "svga_resource_buffer.h"
21 #include "svga_screen.h"
22 
23 
24 static void
svga_set_vertex_buffers(struct pipe_context * pipe,unsigned count,const struct pipe_vertex_buffer * buffers)25 svga_set_vertex_buffers(struct pipe_context *pipe,
26                         unsigned count,
27                         const struct pipe_vertex_buffer *buffers)
28 {
29    struct svga_context *svga = svga_context(pipe);
30 
31    util_set_vertex_buffers_count(svga->curr.vb,
32                                  &svga->curr.num_vertex_buffers,
33                                  buffers, count, true);
34 
35    svga->dirty |= SVGA_NEW_VBUFFER;
36 }
37 
38 
39 /**
40  * Does the given vertex attrib format need range adjustment in the VS?
41  * Range adjustment scales and biases values from [0,1] to [-1,1].
42  * This lets us avoid the swtnl path.
43  */
44 static bool
attrib_needs_range_adjustment(enum pipe_format format)45 attrib_needs_range_adjustment(enum pipe_format format)
46 {
47    switch (format) {
48    case PIPE_FORMAT_R8G8B8_SNORM:
49       return true;
50    default:
51       return false;
52    }
53 }
54 
55 
56 /**
57  * Given a gallium vertex element format, return the corresponding
58  * SVGA3dDeclType.
59  */
60 static SVGA3dDeclType
translate_vertex_format_to_decltype(enum pipe_format format)61 translate_vertex_format_to_decltype(enum pipe_format format)
62 {
63    switch (format) {
64    case PIPE_FORMAT_R32_FLOAT:            return SVGA3D_DECLTYPE_FLOAT1;
65    case PIPE_FORMAT_R32G32_FLOAT:         return SVGA3D_DECLTYPE_FLOAT2;
66    case PIPE_FORMAT_R32G32B32_FLOAT:      return SVGA3D_DECLTYPE_FLOAT3;
67    case PIPE_FORMAT_R32G32B32A32_FLOAT:   return SVGA3D_DECLTYPE_FLOAT4;
68    case PIPE_FORMAT_B8G8R8A8_UNORM:       return SVGA3D_DECLTYPE_D3DCOLOR;
69    case PIPE_FORMAT_R8G8B8A8_USCALED:     return SVGA3D_DECLTYPE_UBYTE4;
70    case PIPE_FORMAT_R16G16_SSCALED:       return SVGA3D_DECLTYPE_SHORT2;
71    case PIPE_FORMAT_R16G16B16A16_SSCALED: return SVGA3D_DECLTYPE_SHORT4;
72    case PIPE_FORMAT_R8G8B8A8_UNORM:       return SVGA3D_DECLTYPE_UBYTE4N;
73    case PIPE_FORMAT_R16G16_SNORM:         return SVGA3D_DECLTYPE_SHORT2N;
74    case PIPE_FORMAT_R16G16B16A16_SNORM:   return SVGA3D_DECLTYPE_SHORT4N;
75    case PIPE_FORMAT_R16G16_UNORM:         return SVGA3D_DECLTYPE_USHORT2N;
76    case PIPE_FORMAT_R16G16B16A16_UNORM:   return SVGA3D_DECLTYPE_USHORT4N;
77    case PIPE_FORMAT_R10G10B10X2_USCALED:  return SVGA3D_DECLTYPE_UDEC3;
78    case PIPE_FORMAT_R10G10B10X2_SNORM:    return SVGA3D_DECLTYPE_DEC3N;
79    case PIPE_FORMAT_R16G16_FLOAT:         return SVGA3D_DECLTYPE_FLOAT16_2;
80    case PIPE_FORMAT_R16G16B16A16_FLOAT:   return SVGA3D_DECLTYPE_FLOAT16_4;
81 
82    /* See attrib_needs_adjustment() and attrib_needs_w_to_1() above */
83    case PIPE_FORMAT_R8G8B8_SNORM:         return SVGA3D_DECLTYPE_UBYTE4N;
84 
85    /* See attrib_needs_w_to_1() above */
86    case PIPE_FORMAT_R16G16B16_SNORM:      return SVGA3D_DECLTYPE_SHORT4N;
87    case PIPE_FORMAT_R16G16B16_UNORM:      return SVGA3D_DECLTYPE_USHORT4N;
88    case PIPE_FORMAT_R8G8B8_UNORM:         return SVGA3D_DECLTYPE_UBYTE4N;
89 
90    default:
91       /* There are many formats without hardware support.  This case
92        * will be hit regularly, meaning we'll need swvfetch.
93        */
94       return SVGA3D_DECLTYPE_MAX;
95    }
96 }
97 
98 
99 static void
define_input_element_object(struct svga_context * svga,struct svga_velems_state * velems)100 define_input_element_object(struct svga_context *svga,
101                             struct svga_velems_state *velems)
102 {
103    SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS];
104    unsigned i;
105 
106    assert(velems->count <= PIPE_MAX_ATTRIBS);
107    assert(svga_have_vgpu10(svga));
108 
109    for (i = 0; i < velems->count; i++) {
110       const struct pipe_vertex_element *elem = velems->velem + i;
111       SVGA3dSurfaceFormat svga_format;
112       unsigned vf_flags;
113 
114       svga_translate_vertex_format_vgpu10(elem->src_format,
115                                           &svga_format, &vf_flags);
116 
117       velems->decl_type[i] =
118          translate_vertex_format_to_decltype(elem->src_format);
119       elements[i].inputSlot = elem->vertex_buffer_index;
120       elements[i].alignedByteOffset = elem->src_offset;
121       elements[i].format = svga_format;
122 
123       if (elem->instance_divisor) {
124          elements[i].inputSlotClass = SVGA3D_INPUT_PER_INSTANCE_DATA;
125          elements[i].instanceDataStepRate = elem->instance_divisor;
126       }
127       else {
128          elements[i].inputSlotClass = SVGA3D_INPUT_PER_VERTEX_DATA;
129          elements[i].instanceDataStepRate = 0;
130       }
131       elements[i].inputRegister = i;
132 
133       if (elements[i].format == SVGA3D_FORMAT_INVALID) {
134          velems->need_swvfetch = true;
135       }
136 
137       if (util_format_is_pure_integer(elem->src_format)) {
138          velems->attrib_is_pure_int |= (1 << i);
139       }
140 
141       if (vf_flags & VF_W_TO_1) {
142          velems->adjust_attrib_w_1 |= (1 << i);
143       }
144 
145       if (vf_flags & VF_U_TO_F_CAST) {
146          velems->adjust_attrib_utof |= (1 << i);
147       }
148       else if (vf_flags & VF_I_TO_F_CAST) {
149          velems->adjust_attrib_itof |= (1 << i);
150       }
151 
152       if (vf_flags & VF_BGRA) {
153          velems->attrib_is_bgra |= (1 << i);
154       }
155 
156       if (vf_flags & VF_PUINT_TO_SNORM) {
157          velems->attrib_puint_to_snorm |= (1 << i);
158       }
159       else if (vf_flags & VF_PUINT_TO_USCALED) {
160          velems->attrib_puint_to_uscaled |= (1 << i);
161       }
162       else if (vf_flags & VF_PUINT_TO_SSCALED) {
163          velems->attrib_puint_to_sscaled |= (1 << i);
164       }
165    }
166 
167    velems->id = util_bitmask_add(svga->input_element_object_id_bm);
168 
169    SVGA_RETRY(svga, SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
170                                                       velems->id, elements));
171 }
172 
173 
174 /**
175  * Translate the vertex element types to SVGA3dDeclType and check
176  * for VS-based vertex attribute adjustments.
177  */
178 static void
translate_vertex_decls(struct svga_context * svga,struct svga_velems_state * velems)179 translate_vertex_decls(struct svga_context *svga,
180                        struct svga_velems_state *velems)
181 {
182    unsigned i;
183 
184    assert(!svga_have_vgpu10(svga));
185 
186    for (i = 0; i < velems->count; i++) {
187       const enum pipe_format f = velems->velem[i].src_format;
188       SVGA3dSurfaceFormat svga_format;
189       unsigned vf_flags;
190 
191       svga_translate_vertex_format_vgpu10(f, &svga_format, &vf_flags);
192 
193       velems->decl_type[i] = translate_vertex_format_to_decltype(f);
194       if (velems->decl_type[i] == SVGA3D_DECLTYPE_MAX) {
195          /* Unsupported format - use software fetch */
196          velems->need_swvfetch = true;
197       }
198 
199       /* Check for VS-based adjustments */
200       if (attrib_needs_range_adjustment(f)) {
201          velems->adjust_attrib_range |= (1 << i);
202       }
203 
204       if (vf_flags & VF_W_TO_1) {
205          velems->adjust_attrib_w_1 |= (1 << i);
206       }
207    }
208 }
209 
210 
211 static void *
svga_create_vertex_elements_state(struct pipe_context * pipe,unsigned count,const struct pipe_vertex_element * attribs)212 svga_create_vertex_elements_state(struct pipe_context *pipe,
213                                   unsigned count,
214                                   const struct pipe_vertex_element *attribs)
215 {
216    struct svga_context *svga = svga_context(pipe);
217    struct svga_velems_state *velems;
218 
219    assert(count <= PIPE_MAX_ATTRIBS);
220    velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
221    if (velems) {
222       velems->count = count;
223       memcpy(velems->velem, attribs, sizeof(*attribs) * count);
224 
225       velems->need_swvfetch = false;
226       velems->adjust_attrib_range = 0x0;
227       velems->attrib_is_pure_int = 0x0;
228       velems->adjust_attrib_w_1 = 0x0;
229       velems->adjust_attrib_itof = 0x0;
230       velems->adjust_attrib_utof = 0x0;
231       velems->attrib_is_bgra = 0x0;
232       velems->attrib_puint_to_snorm = 0x0;
233       velems->attrib_puint_to_uscaled = 0x0;
234       velems->attrib_puint_to_sscaled = 0x0;
235 
236       if (svga_have_vgpu10(svga)) {
237          define_input_element_object(svga, velems);
238       }
239       else {
240          translate_vertex_decls(svga, velems);
241       }
242       for (unsigned i = 0; i < count; i++)
243          velems->strides[attribs[i].vertex_buffer_index] = attribs[i].src_stride;
244    }
245 
246    svga->hud.num_vertexelement_objects++;
247    SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
248                         SVGA_STATS_COUNT_VERTEXELEMENT);
249 
250    return velems;
251 }
252 
253 
254 static void
svga_bind_vertex_elements_state(struct pipe_context * pipe,void * state)255 svga_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
256 {
257    struct svga_context *svga = svga_context(pipe);
258    struct svga_velems_state *velems = (struct svga_velems_state *) state;
259 
260    svga->curr.velems = velems;
261    svga->dirty |= SVGA_NEW_VELEMENT;
262 }
263 
264 
265 static void
svga_delete_vertex_elements_state(struct pipe_context * pipe,void * state)266 svga_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
267 {
268    struct svga_context *svga = svga_context(pipe);
269    struct svga_velems_state *velems = (struct svga_velems_state *) state;
270 
271    if (svga_have_vgpu10(svga)) {
272       svga_hwtnl_flush_retry(svga);
273 
274       SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
275                                                           velems->id));
276 
277       if (velems->id == svga->state.hw_draw.layout_id)
278          svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;
279 
280       util_bitmask_clear(svga->input_element_object_id_bm, velems->id);
281       velems->id = SVGA3D_INVALID_ID;
282    }
283 
284    FREE(velems);
285    svga->hud.num_vertexelement_objects--;
286 }
287 
288 
289 void
svga_cleanup_vertex_state(struct svga_context * svga)290 svga_cleanup_vertex_state(struct svga_context *svga)
291 {
292    unsigned i;
293 
294    for (i = 0 ; i < svga->curr.num_vertex_buffers; i++)
295       pipe_vertex_buffer_unreference(&svga->curr.vb[i]);
296 
297    pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
298 
299    for (i = 0; i < svga->state.hw_draw.num_vbuffers; i++)
300       pipe_resource_reference(&svga->state.hw_draw.vbuffers[i], NULL);
301 }
302 
303 
304 void
svga_init_vertex_functions(struct svga_context * svga)305 svga_init_vertex_functions(struct svga_context *svga)
306 {
307    svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
308    svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
309    svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
310    svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
311 }
312