~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/svga/svga_pipe_vertex.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************
2
 
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person
5
 
 * obtaining a copy of this software and associated documentation
6
 
 * files (the "Software"), to deal in the Software without
7
 
 * restriction, including without limitation the rights to use, copy,
8
 
 * modify, merge, publish, distribute, sublicense, and/or sell copies
9
 
 * of the Software, and to permit persons to whom the Software is
10
 
 * furnished to do so, subject to the following conditions:
11
 
 *
12
 
 * The above copyright notice and this permission notice shall be
13
 
 * included in all copies or substantial portions of the Software.
14
 
 *
15
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
 
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
 
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 
 * SOFTWARE.
23
 
 *
24
 
 **********************************************************/
25
 
 
26
 
#include "pipe/p_defines.h"
27
 
#include "util/u_bitmask.h"
28
 
#include "util/format/u_format.h"
29
 
#include "util/u_helpers.h"
30
 
#include "util/u_inlines.h"
31
 
#include "util/u_math.h"
32
 
#include "util/u_memory.h"
33
 
#include "util/u_transfer.h"
34
 
#include "tgsi/tgsi_parse.h"
35
 
 
36
 
#include "svga_context.h"
37
 
#include "svga_cmd.h"
38
 
#include "svga_format.h"
39
 
#include "svga_resource_buffer.h"
40
 
#include "svga_screen.h"
41
 
 
42
 
 
43
 
static void
44
 
svga_set_vertex_buffers(struct pipe_context *pipe,
45
 
                        unsigned start_slot, unsigned count,
46
 
                        unsigned unbind_num_trailing_slots,
47
 
                        bool take_ownership,
48
 
                        const struct pipe_vertex_buffer *buffers)
49
 
{
50
 
   struct svga_context *svga = svga_context(pipe);
51
 
 
52
 
   util_set_vertex_buffers_count(svga->curr.vb,
53
 
                                 &svga->curr.num_vertex_buffers,
54
 
                                 buffers, start_slot, count,
55
 
                                 unbind_num_trailing_slots,
56
 
                                 take_ownership);
57
 
 
58
 
   svga->dirty |= SVGA_NEW_VBUFFER;
59
 
}
60
 
 
61
 
 
62
 
/**
63
 
 * Does the given vertex attrib format need range adjustment in the VS?
64
 
 * Range adjustment scales and biases values from [0,1] to [-1,1].
65
 
 * This lets us avoid the swtnl path.
66
 
 */
67
 
static boolean
68
 
attrib_needs_range_adjustment(enum pipe_format format)
69
 
{
70
 
   switch (format) {
71
 
   case PIPE_FORMAT_R8G8B8_SNORM:
72
 
      return TRUE;
73
 
   default:
74
 
      return FALSE;
75
 
   }
76
 
}
77
 
 
78
 
 
79
 
/**
80
 
 * Given a gallium vertex element format, return the corresponding
81
 
 * SVGA3dDeclType.
82
 
 */
83
 
static SVGA3dDeclType
84
 
translate_vertex_format_to_decltype(enum pipe_format format)
85
 
{
86
 
   switch (format) {
87
 
   case PIPE_FORMAT_R32_FLOAT:            return SVGA3D_DECLTYPE_FLOAT1;
88
 
   case PIPE_FORMAT_R32G32_FLOAT:         return SVGA3D_DECLTYPE_FLOAT2;
89
 
   case PIPE_FORMAT_R32G32B32_FLOAT:      return SVGA3D_DECLTYPE_FLOAT3;
90
 
   case PIPE_FORMAT_R32G32B32A32_FLOAT:   return SVGA3D_DECLTYPE_FLOAT4;
91
 
   case PIPE_FORMAT_B8G8R8A8_UNORM:       return SVGA3D_DECLTYPE_D3DCOLOR;
92
 
   case PIPE_FORMAT_R8G8B8A8_USCALED:     return SVGA3D_DECLTYPE_UBYTE4;
93
 
   case PIPE_FORMAT_R16G16_SSCALED:       return SVGA3D_DECLTYPE_SHORT2;
94
 
   case PIPE_FORMAT_R16G16B16A16_SSCALED: return SVGA3D_DECLTYPE_SHORT4;
95
 
   case PIPE_FORMAT_R8G8B8A8_UNORM:       return SVGA3D_DECLTYPE_UBYTE4N;
96
 
   case PIPE_FORMAT_R16G16_SNORM:         return SVGA3D_DECLTYPE_SHORT2N;
97
 
   case PIPE_FORMAT_R16G16B16A16_SNORM:   return SVGA3D_DECLTYPE_SHORT4N;
98
 
   case PIPE_FORMAT_R16G16_UNORM:         return SVGA3D_DECLTYPE_USHORT2N;
99
 
   case PIPE_FORMAT_R16G16B16A16_UNORM:   return SVGA3D_DECLTYPE_USHORT4N;
100
 
   case PIPE_FORMAT_R10G10B10X2_USCALED:  return SVGA3D_DECLTYPE_UDEC3;
101
 
   case PIPE_FORMAT_R10G10B10X2_SNORM:    return SVGA3D_DECLTYPE_DEC3N;
102
 
   case PIPE_FORMAT_R16G16_FLOAT:         return SVGA3D_DECLTYPE_FLOAT16_2;
103
 
   case PIPE_FORMAT_R16G16B16A16_FLOAT:   return SVGA3D_DECLTYPE_FLOAT16_4;
104
 
 
105
 
   /* See attrib_needs_adjustment() and attrib_needs_w_to_1() above */
106
 
   case PIPE_FORMAT_R8G8B8_SNORM:         return SVGA3D_DECLTYPE_UBYTE4N;
107
 
 
108
 
   /* See attrib_needs_w_to_1() above */
109
 
   case PIPE_FORMAT_R16G16B16_SNORM:      return SVGA3D_DECLTYPE_SHORT4N;
110
 
   case PIPE_FORMAT_R16G16B16_UNORM:      return SVGA3D_DECLTYPE_USHORT4N;
111
 
   case PIPE_FORMAT_R8G8B8_UNORM:         return SVGA3D_DECLTYPE_UBYTE4N;
112
 
 
113
 
   default:
114
 
      /* There are many formats without hardware support.  This case
115
 
       * will be hit regularly, meaning we'll need swvfetch.
116
 
       */
117
 
      return SVGA3D_DECLTYPE_MAX;
118
 
   }
119
 
}
120
 
 
121
 
 
122
 
static void
123
 
define_input_element_object(struct svga_context *svga,
124
 
                            struct svga_velems_state *velems)
125
 
{
126
 
   SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS];
127
 
   unsigned i;
128
 
 
129
 
   assert(velems->count <= PIPE_MAX_ATTRIBS);
130
 
   assert(svga_have_vgpu10(svga));
131
 
 
132
 
   for (i = 0; i < velems->count; i++) {
133
 
      const struct pipe_vertex_element *elem = velems->velem + i;
134
 
      SVGA3dSurfaceFormat svga_format;
135
 
      unsigned vf_flags;
136
 
 
137
 
      svga_translate_vertex_format_vgpu10(elem->src_format,
138
 
                                          &svga_format, &vf_flags);
139
 
 
140
 
      velems->decl_type[i] =
141
 
         translate_vertex_format_to_decltype(elem->src_format);
142
 
      elements[i].inputSlot = elem->vertex_buffer_index;
143
 
      elements[i].alignedByteOffset = elem->src_offset;
144
 
      elements[i].format = svga_format;
145
 
 
146
 
      if (elem->instance_divisor) {
147
 
         elements[i].inputSlotClass = SVGA3D_INPUT_PER_INSTANCE_DATA;
148
 
         elements[i].instanceDataStepRate = elem->instance_divisor;
149
 
      }
150
 
      else {
151
 
         elements[i].inputSlotClass = SVGA3D_INPUT_PER_VERTEX_DATA;
152
 
         elements[i].instanceDataStepRate = 0;
153
 
      }
154
 
      elements[i].inputRegister = i;
155
 
 
156
 
      if (elements[i].format == SVGA3D_FORMAT_INVALID) {
157
 
         velems->need_swvfetch = TRUE;
158
 
      }
159
 
 
160
 
      if (util_format_is_pure_integer(elem->src_format)) {
161
 
         velems->attrib_is_pure_int |= (1 << i);
162
 
      }
163
 
 
164
 
      if (vf_flags & VF_W_TO_1) {
165
 
         velems->adjust_attrib_w_1 |= (1 << i);
166
 
      }
167
 
 
168
 
      if (vf_flags & VF_U_TO_F_CAST) {
169
 
         velems->adjust_attrib_utof |= (1 << i);
170
 
      }
171
 
      else if (vf_flags & VF_I_TO_F_CAST) {
172
 
         velems->adjust_attrib_itof |= (1 << i);
173
 
      }
174
 
 
175
 
      if (vf_flags & VF_BGRA) {
176
 
         velems->attrib_is_bgra |= (1 << i);
177
 
      }
178
 
 
179
 
      if (vf_flags & VF_PUINT_TO_SNORM) {
180
 
         velems->attrib_puint_to_snorm |= (1 << i);
181
 
      }
182
 
      else if (vf_flags & VF_PUINT_TO_USCALED) {
183
 
         velems->attrib_puint_to_uscaled |= (1 << i);
184
 
      }
185
 
      else if (vf_flags & VF_PUINT_TO_SSCALED) {
186
 
         velems->attrib_puint_to_sscaled |= (1 << i);
187
 
      }
188
 
   }
189
 
 
190
 
   velems->id = util_bitmask_add(svga->input_element_object_id_bm);
191
 
 
192
 
   SVGA_RETRY(svga, SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
193
 
                                                      velems->id, elements));
194
 
}
195
 
 
196
 
 
197
 
/**
198
 
 * Translate the vertex element types to SVGA3dDeclType and check
199
 
 * for VS-based vertex attribute adjustments.
200
 
 */
201
 
static void
202
 
translate_vertex_decls(struct svga_context *svga,
203
 
                       struct svga_velems_state *velems)
204
 
{
205
 
   unsigned i;
206
 
 
207
 
   assert(!svga_have_vgpu10(svga));
208
 
 
209
 
   for (i = 0; i < velems->count; i++) {
210
 
      const enum pipe_format f = velems->velem[i].src_format;
211
 
      SVGA3dSurfaceFormat svga_format;
212
 
      unsigned vf_flags;
213
 
 
214
 
      svga_translate_vertex_format_vgpu10(f, &svga_format, &vf_flags);
215
 
 
216
 
      velems->decl_type[i] = translate_vertex_format_to_decltype(f);
217
 
      if (velems->decl_type[i] == SVGA3D_DECLTYPE_MAX) {
218
 
         /* Unsupported format - use software fetch */
219
 
         velems->need_swvfetch = TRUE;
220
 
      }
221
 
 
222
 
      /* Check for VS-based adjustments */
223
 
      if (attrib_needs_range_adjustment(f)) {
224
 
         velems->adjust_attrib_range |= (1 << i);
225
 
      }
226
 
 
227
 
      if (vf_flags & VF_W_TO_1) {
228
 
         velems->adjust_attrib_w_1 |= (1 << i);
229
 
      }
230
 
   }
231
 
}
232
 
 
233
 
 
234
 
static void *
235
 
svga_create_vertex_elements_state(struct pipe_context *pipe,
236
 
                                  unsigned count,
237
 
                                  const struct pipe_vertex_element *attribs)
238
 
{
239
 
   struct svga_context *svga = svga_context(pipe);
240
 
   struct svga_velems_state *velems;
241
 
 
242
 
   assert(count <= PIPE_MAX_ATTRIBS);
243
 
   velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
244
 
   if (velems) {
245
 
      velems->count = count;
246
 
      memcpy(velems->velem, attribs, sizeof(*attribs) * count);
247
 
 
248
 
      velems->need_swvfetch = FALSE;
249
 
      velems->adjust_attrib_range = 0x0;
250
 
      velems->attrib_is_pure_int = 0x0;
251
 
      velems->adjust_attrib_w_1 = 0x0;
252
 
      velems->adjust_attrib_itof = 0x0;
253
 
      velems->adjust_attrib_utof = 0x0;
254
 
      velems->attrib_is_bgra = 0x0;
255
 
      velems->attrib_puint_to_snorm = 0x0;
256
 
      velems->attrib_puint_to_uscaled = 0x0;
257
 
      velems->attrib_puint_to_sscaled = 0x0;
258
 
 
259
 
      if (svga_have_vgpu10(svga)) {
260
 
         define_input_element_object(svga, velems);
261
 
      }
262
 
      else {
263
 
         translate_vertex_decls(svga, velems);
264
 
      }
265
 
   }
266
 
 
267
 
   svga->hud.num_vertexelement_objects++;
268
 
   SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
269
 
                        SVGA_STATS_COUNT_VERTEXELEMENT);
270
 
 
271
 
   return velems;
272
 
}
273
 
 
274
 
 
275
 
static void
276
 
svga_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
277
 
{
278
 
   struct svga_context *svga = svga_context(pipe);
279
 
   struct svga_velems_state *velems = (struct svga_velems_state *) state;
280
 
 
281
 
   svga->curr.velems = velems;
282
 
   svga->dirty |= SVGA_NEW_VELEMENT;
283
 
}
284
 
 
285
 
 
286
 
static void
287
 
svga_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
288
 
{
289
 
   struct svga_context *svga = svga_context(pipe);
290
 
   struct svga_velems_state *velems = (struct svga_velems_state *) state;
291
 
 
292
 
   if (svga_have_vgpu10(svga)) {
293
 
      svga_hwtnl_flush_retry(svga);
294
 
 
295
 
      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
296
 
                                                          velems->id));
297
 
 
298
 
      if (velems->id == svga->state.hw_draw.layout_id)
299
 
         svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;
300
 
 
301
 
      util_bitmask_clear(svga->input_element_object_id_bm, velems->id);
302
 
      velems->id = SVGA3D_INVALID_ID;
303
 
   }
304
 
 
305
 
   FREE(velems);
306
 
   svga->hud.num_vertexelement_objects--;
307
 
}
308
 
 
309
 
 
310
 
void
311
 
svga_cleanup_vertex_state(struct svga_context *svga)
312
 
{
313
 
   unsigned i;
314
 
 
315
 
   for (i = 0 ; i < svga->curr.num_vertex_buffers; i++)
316
 
      pipe_vertex_buffer_unreference(&svga->curr.vb[i]);
317
 
 
318
 
   pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
319
 
 
320
 
   for (i = 0; i < svga->state.hw_draw.num_vbuffers; i++)
321
 
      pipe_resource_reference(&svga->state.hw_draw.vbuffers[i], NULL);
322
 
}
323
 
 
324
 
 
325
 
void
326
 
svga_init_vertex_functions(struct svga_context *svga)
327
 
{
328
 
   svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
329
 
   svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
330
 
   svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
331
 
   svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
332
 
}