xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_state_vdecl.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 "util/u_inlines.h"
9 #include "pipe/p_defines.h"
10 #include "util/u_math.h"
11 #include "util/u_upload_mgr.h"
12 
13 #include "svga_context.h"
14 #include "svga_state.h"
15 #include "svga_draw.h"
16 #include "svga_tgsi.h"
17 #include "svga_screen.h"
18 #include "svga_shader.h"
19 #include "svga_resource_buffer.h"
20 #include "svga_hw_reg.h"
21 
22 
23 
24 static enum pipe_error
emit_hw_vs_vdecl(struct svga_context * svga,uint64_t dirty)25 emit_hw_vs_vdecl(struct svga_context *svga, uint64_t dirty)
26 {
27    const struct pipe_vertex_element *ve = svga->curr.velems->velem;
28    SVGA3dVertexDecl decls[SVGA3D_INPUTREG_MAX];
29    unsigned buffer_indexes[SVGA3D_INPUTREG_MAX];
30    unsigned i;
31    unsigned neg_bias = 0;
32 
33    assert(svga->curr.velems->count >=
34           svga->curr.vs->base.info.num_inputs);
35 
36    /**
37     * We can't set the VDECL offset to something negative, so we
38     * must calculate a common negative additional index bias, and modify
39     * the VDECL offsets accordingly so they *all* end up positive.
40     *
41     * Note that the exact value of the negative index bias is not that
42     * important, since we compensate for it when we calculate the vertex
43     * buffer offset below. The important thing is that all vertex buffer
44     * offsets remain positive.
45     *
46     * Note that we use a negative bias variable in order to make the
47     * rounding maths more easy to follow, and to avoid int / unsigned
48     * confusion.
49     */
50 
51    for (i = 0; i < svga->curr.velems->count; i++) {
52       const struct pipe_vertex_buffer *vb =
53          &svga->curr.vb[ve[i].vertex_buffer_index];
54       struct svga_buffer *buffer;
55       unsigned int offset = vb->buffer_offset + ve[i].src_offset;
56       unsigned tmp_neg_bias = 0;
57 
58       if (!vb->buffer.resource)
59          continue;
60 
61       buffer = svga_buffer(vb->buffer.resource);
62       if (buffer->uploaded.start > offset) {
63          tmp_neg_bias = buffer->uploaded.start - offset;
64          if (ve[i].src_stride)
65             tmp_neg_bias = (tmp_neg_bias + ve[i].src_stride - 1) / ve[i].src_stride;
66          neg_bias = MAX2(neg_bias, tmp_neg_bias);
67       }
68    }
69 
70    for (i = 0; i < svga->curr.velems->count; i++) {
71       const struct pipe_vertex_buffer *vb =
72          &svga->curr.vb[ve[i].vertex_buffer_index];
73       unsigned usage, index;
74       struct svga_buffer *buffer;
75 
76       if (!vb->buffer.resource)
77          continue;
78 
79       buffer = svga_buffer(vb->buffer.resource);
80       svga_generate_vdecl_semantics( i, &usage, &index );
81 
82       /* SVGA_NEW_VELEMENT
83        */
84       decls[i].identity.type = svga->curr.velems->decl_type[i];
85       decls[i].identity.method = SVGA3D_DECLMETHOD_DEFAULT;
86       decls[i].identity.usage = usage;
87       decls[i].identity.usageIndex = index;
88       decls[i].array.stride = ve[i].src_stride;
89 
90       /* Compensate for partially uploaded vbo, and
91        * for the negative index bias.
92        */
93       decls[i].array.offset = (vb->buffer_offset
94                            + ve[i].src_offset
95 			   + neg_bias * ve[i].src_stride
96 			   - buffer->uploaded.start);
97 
98       assert(decls[i].array.offset >= 0);
99 
100       buffer_indexes[i] = ve[i].vertex_buffer_index;
101 
102       assert(!buffer->uploaded.buffer);
103    }
104 
105    svga_hwtnl_vertex_decls(svga->hwtnl,
106                            svga->curr.velems->count,
107                            decls,
108                            buffer_indexes,
109                            svga->curr.velems->id);
110 
111    svga_hwtnl_vertex_buffers(svga->hwtnl,
112                              svga->curr.num_vertex_buffers,
113                              svga->curr.vb);
114 
115    svga_hwtnl_set_index_bias( svga->hwtnl, -(int) neg_bias );
116    return PIPE_OK;
117 }
118 
119 
120 static enum pipe_error
emit_hw_vdecl(struct svga_context * svga,uint64_t dirty)121 emit_hw_vdecl(struct svga_context *svga, uint64_t dirty)
122 {
123    /* SVGA_NEW_NEED_SWTNL
124     */
125    if (svga->state.sw.need_swtnl)
126       return PIPE_OK; /* Do not emit during swtnl */
127 
128    return emit_hw_vs_vdecl( svga, dirty );
129 }
130 
131 
132 struct svga_tracked_state svga_hw_vdecl =
133 {
134    "hw vertex decl state (hwtnl version)",
135    ( SVGA_NEW_NEED_SWTNL |
136      SVGA_NEW_VELEMENT |
137      SVGA_NEW_VBUFFER |
138      SVGA_NEW_RAST |
139      SVGA_NEW_FS |
140      SVGA_NEW_VS ),
141    emit_hw_vdecl
142 };
143