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