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_compiler.h"
27 #include "util/u_inlines.h"
28 #include "pipe/p_defines.h"
29 #include "util/u_helpers.h"
30 #include "util/u_memory.h"
31 #include "util/u_math.h"
32
33 #include "svga_context.h"
34 #include "svga_draw.h"
35 #include "svga_draw_private.h"
36 #include "svga_debug.h"
37 #include "svga_screen.h"
38 #include "svga_resource.h"
39 #include "svga_resource_buffer.h"
40 #include "svga_resource_texture.h"
41 #include "svga_sampler_view.h"
42 #include "svga_shader.h"
43 #include "svga_surface.h"
44 #include "svga_winsys.h"
45 #include "svga_cmd.h"
46
47
48 struct svga_hwtnl *
svga_hwtnl_create(struct svga_context * svga)49 svga_hwtnl_create(struct svga_context *svga)
50 {
51 struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
52 if (!hwtnl)
53 goto fail;
54
55 hwtnl->svga = svga;
56
57 hwtnl->cmd.swc = svga->swc;
58
59 return hwtnl;
60
61 fail:
62 return NULL;
63 }
64
65
66 void
svga_hwtnl_destroy(struct svga_hwtnl * hwtnl)67 svga_hwtnl_destroy(struct svga_hwtnl *hwtnl)
68 {
69 unsigned i, j;
70
71 for (i = 0; i < PIPE_PRIM_MAX; i++) {
72 for (j = 0; j < IDX_CACHE_MAX; j++) {
73 pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
74 }
75 }
76
77 for (i = 0; i < hwtnl->cmd.vbuf_count; i++)
78 pipe_vertex_buffer_unreference(&hwtnl->cmd.vbufs[i]);
79
80 for (i = 0; i < hwtnl->cmd.prim_count; i++)
81 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
82
83 FREE(hwtnl);
84 }
85
86
87 void
svga_hwtnl_set_flatshade(struct svga_hwtnl * hwtnl,boolean flatshade,boolean flatshade_first)88 svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl,
89 boolean flatshade, boolean flatshade_first)
90 {
91 struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen);
92
93 /* User-specified PV */
94 hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
95
96 /* Device supported PV */
97 if (svgascreen->haveProvokingVertex) {
98 /* use the mode specified by the user */
99 hwtnl->hw_pv = hwtnl->api_pv;
100 }
101 else {
102 /* the device only support first provoking vertex */
103 hwtnl->hw_pv = PV_FIRST;
104 }
105 }
106
107
108 void
svga_hwtnl_set_fillmode(struct svga_hwtnl * hwtnl,unsigned mode)109 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
110 {
111 hwtnl->api_fillmode = mode;
112 }
113
114
115 void
svga_hwtnl_vertex_decls(struct svga_hwtnl * hwtnl,unsigned count,const SVGA3dVertexDecl * decls,const unsigned * buffer_indexes,SVGA3dElementLayoutId layout_id)116 svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl,
117 unsigned count,
118 const SVGA3dVertexDecl * decls,
119 const unsigned *buffer_indexes,
120 SVGA3dElementLayoutId layout_id)
121 {
122 assert(hwtnl->cmd.prim_count == 0);
123 hwtnl->cmd.vdecl_count = count;
124 hwtnl->cmd.vdecl_layout_id = layout_id;
125 memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls));
126 memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes,
127 count * sizeof(unsigned));
128 }
129
130
131 /**
132 * Specify vertex buffers for hardware drawing.
133 */
134 void
svga_hwtnl_vertex_buffers(struct svga_hwtnl * hwtnl,unsigned count,struct pipe_vertex_buffer * buffers)135 svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl,
136 unsigned count, struct pipe_vertex_buffer *buffers)
137 {
138 struct pipe_vertex_buffer *dst = hwtnl->cmd.vbufs;
139 const struct pipe_vertex_buffer *src = buffers;
140 unsigned i;
141
142 for (i = 0; i < count; i++) {
143 pipe_vertex_buffer_reference(&dst[i], &src[i]);
144 }
145
146 /* release old buffer references */
147 for ( ; i < hwtnl->cmd.vbuf_count; i++) {
148 pipe_vertex_buffer_unreference(&dst[i]);
149 /* don't bother zeroing stride/offset fields */
150 }
151
152 hwtnl->cmd.vbuf_count = count;
153 }
154
155
156 /**
157 * Determine whether the specified buffer is referred in the primitive queue,
158 * for which no commands have been written yet.
159 */
160 boolean
svga_hwtnl_is_buffer_referred(struct svga_hwtnl * hwtnl,struct pipe_resource * buffer)161 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
162 struct pipe_resource *buffer)
163 {
164 unsigned i;
165
166 if (svga_buffer_is_user_buffer(buffer)) {
167 return FALSE;
168 }
169
170 if (!hwtnl->cmd.prim_count) {
171 return FALSE;
172 }
173
174 for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) {
175 if (hwtnl->cmd.vbufs[i].buffer.resource == buffer) {
176 return TRUE;
177 }
178 }
179
180 for (i = 0; i < hwtnl->cmd.prim_count; ++i) {
181 if (hwtnl->cmd.prim_ib[i] == buffer) {
182 return TRUE;
183 }
184 }
185
186 return FALSE;
187 }
188
189
190 static enum pipe_error
draw_vgpu9(struct svga_hwtnl * hwtnl)191 draw_vgpu9(struct svga_hwtnl *hwtnl)
192 {
193 struct svga_winsys_context *swc = hwtnl->cmd.swc;
194 struct svga_context *svga = hwtnl->svga;
195 enum pipe_error ret;
196 struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
197 struct svga_winsys_surface *ib_handle[QSZ];
198 struct svga_winsys_surface *handle;
199 SVGA3dVertexDecl *vdecl;
200 SVGA3dPrimitiveRange *prim;
201 unsigned i;
202
203 /* Re-validate those sampler views with backing copy
204 * of texture whose original copy has been updated.
205 * This is done here at draw time because the texture binding might not
206 * have modified, hence validation is not triggered at state update time,
207 * and yet the texture might have been updated in another context, so
208 * we need to re-validate the sampler view in order to update the backing
209 * copy of the updated texture.
210 */
211 if (svga->state.hw_draw.num_backed_views) {
212 for (i = 0; i < svga->state.hw_draw.num_views; i++) {
213 struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
214 struct svga_texture *tex = svga_texture(view->texture);
215 struct svga_sampler_view *sv = view->v;
216 if (sv && tex && sv->handle != tex->handle && sv->age < tex->age)
217 svga_validate_sampler_view(svga, view->v);
218 }
219 }
220
221 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
222 unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
223 handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer.resource,
224 PIPE_BIND_VERTEX_BUFFER);
225 if (!handle)
226 return PIPE_ERROR_OUT_OF_MEMORY;
227
228 vb_handle[i] = handle;
229 }
230
231 for (i = 0; i < hwtnl->cmd.prim_count; i++) {
232 if (hwtnl->cmd.prim_ib[i]) {
233 handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i],
234 PIPE_BIND_INDEX_BUFFER);
235 if (!handle)
236 return PIPE_ERROR_OUT_OF_MEMORY;
237 }
238 else
239 handle = NULL;
240
241 ib_handle[i] = handle;
242 }
243
244 if (svga->rebind.flags.rendertargets) {
245 ret = svga_reemit_framebuffer_bindings(svga);
246 if (ret != PIPE_OK) {
247 return ret;
248 }
249 }
250
251 if (svga->rebind.flags.texture_samplers) {
252 ret = svga_reemit_tss_bindings(svga);
253 if (ret != PIPE_OK) {
254 return ret;
255 }
256 }
257
258 if (svga->rebind.flags.vs) {
259 ret = svga_reemit_vs_bindings(svga);
260 if (ret != PIPE_OK) {
261 return ret;
262 }
263 }
264
265 if (svga->rebind.flags.fs) {
266 ret = svga_reemit_fs_bindings(svga);
267 if (ret != PIPE_OK) {
268 return ret;
269 }
270 }
271
272 SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
273 svga->curr.framebuffer.cbufs[0] ?
274 svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
275 hwtnl->cmd.prim_count);
276
277 ret = SVGA3D_BeginDrawPrimitives(swc,
278 &vdecl,
279 hwtnl->cmd.vdecl_count,
280 &prim, hwtnl->cmd.prim_count);
281 if (ret != PIPE_OK)
282 return ret;
283
284 memcpy(vdecl,
285 hwtnl->cmd.vdecl,
286 hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
287
288 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
289 /* check for 4-byte alignment */
290 assert(vdecl[i].array.offset % 4 == 0);
291 assert(vdecl[i].array.stride % 4 == 0);
292
293 /* Given rangeHint is considered to be relative to indexBias, and
294 * indexBias varies per primitive, we cannot accurately supply an
295 * rangeHint when emitting more than one primitive per draw command.
296 */
297 if (hwtnl->cmd.prim_count == 1) {
298 vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
299 vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
300 }
301 else {
302 vdecl[i].rangeHint.first = 0;
303 vdecl[i].rangeHint.last = 0;
304 }
305
306 swc->surface_relocation(swc,
307 &vdecl[i].array.surfaceId,
308 NULL, vb_handle[i], SVGA_RELOC_READ);
309 }
310
311 memcpy(prim,
312 hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
313
314 for (i = 0; i < hwtnl->cmd.prim_count; i++) {
315 swc->surface_relocation(swc,
316 &prim[i].indexArray.surfaceId,
317 NULL, ib_handle[i], SVGA_RELOC_READ);
318 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
319 }
320
321 SVGA_FIFOCommitAll(swc);
322
323 hwtnl->cmd.prim_count = 0;
324
325 return PIPE_OK;
326 }
327
328
329 static SVGA3dSurfaceFormat
xlate_index_format(unsigned indexWidth)330 xlate_index_format(unsigned indexWidth)
331 {
332 if (indexWidth == 2) {
333 return SVGA3D_R16_UINT;
334 }
335 else if (indexWidth == 4) {
336 return SVGA3D_R32_UINT;
337 }
338 else {
339 assert(!"Bad indexWidth");
340 return SVGA3D_R32_UINT;
341 }
342 }
343
344
345 /**
346 * A helper function to validate sampler view resources to ensure any
347 * pending updates to buffers will be emitted before they are referenced
348 * at draw or dispatch time. It also rebinds the resources if needed.
349 */
350 enum pipe_error
svga_validate_sampler_resources(struct svga_context * svga,enum svga_pipe_type pipe_type)351 svga_validate_sampler_resources(struct svga_context *svga,
352 enum svga_pipe_type pipe_type)
353 {
354 enum pipe_shader_type shader, first_shader, last_shader;
355
356 assert(svga_have_vgpu10(svga));
357
358 if (pipe_type == SVGA_PIPE_GRAPHICS) {
359 first_shader = PIPE_SHADER_VERTEX;
360 last_shader = PIPE_SHADER_TESS_EVAL;
361 }
362 else {
363 assert(svga_have_gl43(svga));
364 first_shader = PIPE_SHADER_COMPUTE;
365 last_shader = PIPE_SHADER_COMPUTE;
366 }
367
368 for (shader = first_shader; shader <= last_shader; shader++) {
369 unsigned count = svga->curr.num_sampler_views[shader];
370 unsigned i;
371 struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
372 enum pipe_error ret;
373
374 /*
375 * Reference bound sampler resources to ensure pending updates are
376 * noticed by the device.
377 */
378 for (i = 0; i < count; i++) {
379 struct svga_pipe_sampler_view *sv =
380 svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
381
382 if (sv) {
383 if (sv->base.texture->target == PIPE_BUFFER) {
384 surfaces[i] = svga_buffer_handle(svga, sv->base.texture,
385 PIPE_BIND_SAMPLER_VIEW);
386 }
387 else {
388 surfaces[i] = svga_texture(sv->base.texture)->handle;
389 }
390 }
391 else {
392 surfaces[i] = NULL;
393 }
394 }
395
396 if (shader == PIPE_SHADER_FRAGMENT &&
397 svga->curr.rast->templ.poly_stipple_enable) {
398 const unsigned unit =
399 svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit;
400 struct svga_pipe_sampler_view *sv =
401 svga->polygon_stipple.sampler_view;
402
403 assert(sv);
404 surfaces[unit] = svga_texture(sv->base.texture)->handle;
405 count = MAX2(count, unit+1);
406 }
407
408 /* rebind the shader resources if needed */
409 if (svga->rebind.flags.texture_samplers) {
410 for (i = 0; i < count; i++) {
411 if (surfaces[i]) {
412 ret = svga->swc->resource_rebind(svga->swc,
413 surfaces[i],
414 NULL,
415 SVGA_RELOC_READ);
416 if (ret != PIPE_OK)
417 return ret;
418 }
419 }
420 }
421 }
422 svga->rebind.flags.texture_samplers = FALSE;
423
424 return PIPE_OK;
425 }
426
427
428 /**
429 * A helper function to validate constant buffers to ensure any
430 * pending updates to the buffers will be emitted before they are referenced
431 * at draw or dispatch time. It also rebinds the resources if needed.
432 */
433 enum pipe_error
svga_validate_constant_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)434 svga_validate_constant_buffers(struct svga_context *svga,
435 enum svga_pipe_type pipe_type)
436 {
437 enum pipe_shader_type shader, first_shader, last_shader;
438
439 assert(svga_have_vgpu10(svga));
440
441 if (pipe_type == SVGA_PIPE_GRAPHICS) {
442 first_shader = PIPE_SHADER_VERTEX;
443 last_shader = PIPE_SHADER_TESS_EVAL;
444 }
445 else {
446 assert(svga_have_gl43(svga));
447 first_shader = PIPE_SHADER_COMPUTE;
448 last_shader = PIPE_SHADER_COMPUTE;
449 }
450
451 for (shader = first_shader; shader <= last_shader; shader++) {
452
453 enum pipe_error ret;
454 struct svga_buffer *buffer;
455
456 /* Rebind the default constant buffer if needed */
457 if (svga->rebind.flags.constbufs) {
458 buffer = svga_buffer(svga->state.hw_draw.constbuf[shader][0]);
459 if (buffer) {
460 ret = svga->swc->resource_rebind(svga->swc,
461 buffer->handle,
462 NULL,
463 SVGA_RELOC_READ);
464 if (ret != PIPE_OK)
465 return ret;
466 }
467 }
468
469 struct svga_winsys_surface *handle;
470 unsigned enabled_constbufs;
471
472 /*
473 * Reference other bound constant buffers to ensure pending updates are
474 * noticed by the device.
475 */
476 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
477 while (enabled_constbufs) {
478 unsigned i = u_bit_scan(&enabled_constbufs);
479 buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
480
481 /* If the constant buffer has hw storage, get the buffer winsys handle.
482 * Rebind the resource if needed.
483 */
484 if (buffer && !buffer->use_swbuf)
485 handle = svga_buffer_handle(svga, &buffer->b,
486 PIPE_BIND_CONSTANT_BUFFER);
487 else
488 handle = svga->state.hw_draw.constbufoffsets[shader][i].handle;
489
490 if (svga->rebind.flags.constbufs && handle) {
491 ret = svga->swc->resource_rebind(svga->swc,
492 handle,
493 NULL,
494 SVGA_RELOC_READ);
495 if (ret != PIPE_OK)
496 return ret;
497 }
498 }
499
500 /* Reference raw constant buffers as they are not included in the
501 * hw constant buffers list.
502 */
503 unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader] & ~1u;
504 while (enabled_rawbufs) {
505 unsigned i = u_bit_scan(&enabled_rawbufs);
506 buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
507
508 assert(buffer != NULL);
509 handle = svga_buffer_handle(svga, &buffer->b,
510 PIPE_BIND_SAMPLER_VIEW);
511
512 if (svga->rebind.flags.constbufs && handle) {
513 ret = svga->swc->resource_rebind(svga->swc,
514 handle,
515 NULL,
516 SVGA_RELOC_READ);
517 if (ret != PIPE_OK)
518 return ret;
519 }
520 }
521 }
522 svga->rebind.flags.constbufs = FALSE;
523
524 return PIPE_OK;
525 }
526
527
528 /**
529 * A helper function to validate image view resources to ensure any
530 * pending updates to buffers will be emitted before they are referenced
531 * at draw or dispatch time. It also rebinds the resources if needed.
532 */
533 enum pipe_error
svga_validate_image_views(struct svga_context * svga,enum svga_pipe_type pipe_type)534 svga_validate_image_views(struct svga_context *svga,
535 enum svga_pipe_type pipe_type)
536 {
537 enum pipe_shader_type shader, first_shader, last_shader;
538 bool rebind = svga->rebind.flags.images;
539 enum pipe_error ret;
540
541 assert(svga_have_gl43(svga));
542
543 if (pipe_type == SVGA_PIPE_GRAPHICS) {
544 first_shader = PIPE_SHADER_VERTEX;
545 last_shader = PIPE_SHADER_TESS_EVAL;
546 }
547 else {
548 first_shader = PIPE_SHADER_COMPUTE;
549 last_shader = PIPE_SHADER_COMPUTE;
550 }
551
552 for (shader = first_shader; shader <= last_shader; shader++) {
553 ret = svga_validate_image_view_resources(svga,
554 svga->state.hw_draw.num_image_views[shader],
555 &svga->state.hw_draw.image_views[shader][0], rebind);
556
557 if (ret != PIPE_OK)
558 return ret;
559 }
560
561 svga->rebind.flags.images = FALSE;
562
563 return PIPE_OK;
564 }
565
566
567 /**
568 * A helper function to validate shader buffer and atomic buffer resources to
569 * ensure any pending updates to buffers will be emitted before they are
570 * referenced at draw or dispatch time. It also rebinds the resources if needed.
571 */
572 enum pipe_error
svga_validate_shader_buffers(struct svga_context * svga,enum svga_pipe_type pipe_type)573 svga_validate_shader_buffers(struct svga_context *svga,
574 enum svga_pipe_type pipe_type)
575 {
576 enum pipe_shader_type shader, first_shader, last_shader;
577 bool rebind = svga->rebind.flags.shaderbufs;
578 enum pipe_error ret;
579
580 assert(svga_have_gl43(svga));
581
582 if (pipe_type == SVGA_PIPE_GRAPHICS) {
583 first_shader = PIPE_SHADER_VERTEX;
584 last_shader = PIPE_SHADER_TESS_EVAL;
585 }
586 else {
587 first_shader = PIPE_SHADER_COMPUTE;
588 last_shader = PIPE_SHADER_COMPUTE;
589 }
590
591 for (shader = first_shader; shader <= last_shader; shader++) {
592 ret = svga_validate_shader_buffer_resources(svga,
593 svga->state.hw_draw.num_shader_buffers[shader],
594 &svga->state.hw_draw.shader_buffers[shader][0], rebind);
595
596 if (ret != PIPE_OK)
597 return ret;
598 }
599
600 svga->rebind.flags.shaderbufs = FALSE;
601
602 ret = svga_validate_shader_buffer_resources(svga,
603 svga->state.hw_draw.num_atomic_buffers,
604 svga->state.hw_draw.atomic_buffers,
605 svga->rebind.flags.atomicbufs);
606
607 if (ret != PIPE_OK)
608 return ret;
609
610 svga->rebind.flags.atomicbufs = FALSE;
611
612 return PIPE_OK;
613 }
614
615
616 /**
617 * Was the last command put into the command buffer a drawing command?
618 * We use this to determine if we can skip emitting buffer re-bind
619 * commands when we have a sequence of drawing commands that use the
620 * same vertex/index buffers with no intervening commands.
621 *
622 * The first drawing command will bind the vertex/index buffers. If
623 * the immediately following command is also a drawing command using the
624 * same buffers, we shouldn't have to rebind them.
625 */
626 static bool
last_command_was_draw(const struct svga_context * svga)627 last_command_was_draw(const struct svga_context *svga)
628 {
629 switch (SVGA3D_GetLastCommand(svga->swc)) {
630 case SVGA_3D_CMD_DX_DRAW:
631 case SVGA_3D_CMD_DX_DRAW_INDEXED:
632 case SVGA_3D_CMD_DX_DRAW_INSTANCED:
633 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
634 case SVGA_3D_CMD_DX_DRAW_AUTO:
635 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT:
636 case SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT:
637 return true;
638 default:
639 return false;
640 }
641 }
642
643
644 /**
645 * A helper function to compare vertex buffers.
646 * They are equal if the vertex buffer attributes and the vertex buffer
647 * resources are identical.
648 */
649 static boolean
vertex_buffers_equal(unsigned count,SVGA3dVertexBuffer_v2 * pVBufAttr1,struct pipe_resource ** pVBuf1,SVGA3dVertexBuffer_v2 * pVBufAttr2,struct pipe_resource ** pVBuf2)650 vertex_buffers_equal(unsigned count,
651 SVGA3dVertexBuffer_v2 *pVBufAttr1,
652 struct pipe_resource **pVBuf1,
653 SVGA3dVertexBuffer_v2 *pVBufAttr2,
654 struct pipe_resource **pVBuf2)
655 {
656 return (memcmp(pVBufAttr1, pVBufAttr2,
657 count * sizeof(*pVBufAttr1)) == 0) &&
658 (memcmp(pVBuf1, pVBuf2, count * sizeof(*pVBuf1)) == 0);
659 }
660
661
662 /*
663 * Prepare the vertex buffers for a drawing command.
664 */
665 static enum pipe_error
validate_vertex_buffers(struct svga_hwtnl * hwtnl,const struct pipe_stream_output_target * so_vertex_count)666 validate_vertex_buffers(struct svga_hwtnl *hwtnl,
667 const struct pipe_stream_output_target *so_vertex_count)
668 {
669 struct svga_context *svga = hwtnl->svga;
670 struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
671 struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
672 struct svga_winsys_surface *so_vertex_count_handle = NULL;
673 const unsigned vbuf_count = so_vertex_count ? 1 : hwtnl->cmd.vbuf_count;
674 SVGA3dVertexBuffer_v2 vbuffer_attrs[PIPE_MAX_ATTRIBS];
675 int last_vbuf = -1;
676 unsigned i;
677
678 assert(svga_have_vgpu10(svga));
679
680 /* setup vertex attribute input layout */
681 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
682 enum pipe_error ret =
683 SVGA3D_vgpu10_SetInputLayout(svga->swc,
684 hwtnl->cmd.vdecl_layout_id);
685 if (ret != PIPE_OK)
686 return ret;
687
688 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
689 }
690
691 /* Get handle for each referenced vertex buffer, unless we're using a
692 * stream-out buffer to specify the drawing information (DrawAuto).
693 * Also set up the buffer attributes.
694 */
695 if (so_vertex_count) {
696 so_vertex_count_handle = svga_buffer_handle(svga,
697 so_vertex_count->buffer,
698 (PIPE_BIND_VERTEX_BUFFER |
699 PIPE_BIND_STREAM_OUTPUT));
700 if (!so_vertex_count_handle)
701 return PIPE_ERROR_OUT_OF_MEMORY;
702
703 /* Set IA slot0 input buffer to the SO buffer */
704 assert(vbuf_count == 1);
705 vbuffer_attrs[0].stride = hwtnl->cmd.vbufs[0].stride;
706 vbuffer_attrs[0].offset = hwtnl->cmd.vbufs[0].buffer_offset;
707 vbuffer_attrs[0].sid = 0;
708 assert(so_vertex_count->buffer != NULL);
709 vbuffer_attrs[0].sizeInBytes = svga_buffer(so_vertex_count->buffer)->size;
710 vbuffers[0] = so_vertex_count->buffer;
711 vbuffer_handles[0] = so_vertex_count_handle;
712
713 i = 1;
714 }
715 else {
716 for (i = 0; i < vbuf_count; i++) {
717 struct svga_buffer *sbuf =
718 svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
719
720 vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
721 vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
722 vbuffer_attrs[i].sid = 0;
723
724 if (sbuf) {
725 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
726 PIPE_BIND_VERTEX_BUFFER);
727 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
728 if (vbuffer_handles[i] == NULL)
729 return PIPE_ERROR_OUT_OF_MEMORY;
730 vbuffers[i] = &sbuf->b;
731 last_vbuf = i;
732
733 vbuffer_attrs[i].sizeInBytes = sbuf->size;
734 }
735 else {
736 vbuffers[i] = NULL;
737 vbuffer_handles[i] = NULL;
738 vbuffer_attrs[i].sizeInBytes = 0;
739 }
740 }
741 }
742
743 /* Unbind the unreferenced the vertex buffer handles */
744 for (; i < svga->state.hw_draw.num_vbuffers; i++) {
745 vbuffers[i] = NULL;
746 vbuffer_handles[i] = NULL;
747 vbuffer_attrs[i].sid = 0;
748 vbuffer_attrs[i].stride = 0;
749 vbuffer_attrs[i].offset = 0;
750 vbuffer_attrs[i].sizeInBytes = 0;
751 }
752
753 /* Get handle for each referenced vertex buffer */
754 for (i = 0; i < vbuf_count; i++) {
755 struct svga_buffer *sbuf =
756 svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
757
758 if (sbuf) {
759 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b,
760 PIPE_BIND_VERTEX_BUFFER);
761 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
762 if (vbuffer_handles[i] == NULL)
763 return PIPE_ERROR_OUT_OF_MEMORY;
764 vbuffers[i] = &sbuf->b;
765 last_vbuf = i;
766 }
767 else {
768 vbuffers[i] = NULL;
769 vbuffer_handles[i] = NULL;
770 }
771 }
772
773 for (; i < svga->state.hw_draw.num_vbuffers; i++) {
774 vbuffers[i] = NULL;
775 vbuffer_handles[i] = NULL;
776 }
777
778 /* setup vertex attribute input layout */
779 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
780 enum pipe_error ret =
781 SVGA3D_vgpu10_SetInputLayout(svga->swc,
782 hwtnl->cmd.vdecl_layout_id);
783 if (ret != PIPE_OK)
784 return ret;
785
786 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
787 }
788
789 /* Get handle for the stream out buffer */
790 if (so_vertex_count) {
791 so_vertex_count_handle = svga_buffer_handle(svga,
792 so_vertex_count->buffer,
793 (PIPE_BIND_VERTEX_BUFFER |
794 PIPE_BIND_STREAM_OUTPUT));
795 if (!so_vertex_count_handle)
796 return PIPE_ERROR_OUT_OF_MEMORY;
797 }
798 else {
799 so_vertex_count_handle = NULL;
800 }
801
802 /* setup vertex buffers */
803 {
804 /* If any of the vertex buffer state has changed, issue
805 * the SetVertexBuffers command. Otherwise, we will just
806 * need to rebind the resources.
807 */
808 if (vbuf_count != svga->state.hw_draw.num_vbuffers ||
809 !vertex_buffers_equal(vbuf_count,
810 vbuffer_attrs,
811 vbuffers,
812 svga->state.hw_draw.vbuffer_attrs,
813 svga->state.hw_draw.vbuffers)) {
814
815 unsigned num_vbuffers;
816
817 /* get the max of the current bound vertex buffers count and
818 * the to-be-bound vertex buffers count, so as to unbind
819 * the unused vertex buffers.
820 */
821 num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
822
823 if (num_vbuffers > 0) {
824 SVGA3dVertexBuffer_v2 *pbufAttrs = vbuffer_attrs;
825 struct svga_winsys_surface **pbufHandles = vbuffer_handles;
826 unsigned numVBuf = 0;
827 boolean emitVBufs =
828 !svga_sws(svga)->have_index_vertex_buffer_offset_cmd ||
829 svga->rebind.flags.vertexbufs;
830
831 /* Loop through the vertex buffer lists to only emit
832 * those vertex buffers that are not already in the
833 * corresponding entries in the device's vertex buffer list.
834 */
835 for (i = 0; i < num_vbuffers; i++) {
836 boolean emit =
837 vertex_buffers_equal(1,
838 &vbuffer_attrs[i],
839 &vbuffers[i],
840 &svga->state.hw_draw.vbuffer_attrs[i],
841 &svga->state.hw_draw.vbuffers[i]);
842
843 /* Check if we can use the SetVertexBuffersOffsetAndSize command */
844 emitVBufs = emitVBufs ||
845 (vbuffers[i] != svga->state.hw_draw.vbuffers[i]);
846
847 if (!emit && i == num_vbuffers-1) {
848 /* Include the last vertex buffer in the next emit
849 * if it is different.
850 */
851 emit = TRUE;
852 numVBuf++;
853 i++;
854 }
855
856 if (emit) {
857 /* numVBuf can only be 0 if the first vertex buffer
858 * is the same as the one in the device's list.
859 * In this case, there is nothing to send yet.
860 */
861 if (numVBuf) {
862 enum pipe_error ret;
863
864 /* If all vertex buffers handle are the same as the one
865 * in the device, just use the
866 * SetVertexBuffersOffsetAndSize comand.
867 */
868 if (emitVBufs) {
869 ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc,
870 numVBuf,
871 i - numVBuf,
872 pbufAttrs, pbufHandles);
873 } else {
874 ret = SVGA3D_vgpu10_SetVertexBuffersOffsetAndSize(svga->swc,
875 numVBuf,
876 i - numVBuf,
877 pbufAttrs);
878 }
879 if (ret != PIPE_OK)
880 return ret;
881 }
882 pbufAttrs += (numVBuf + 1);
883 pbufHandles += (numVBuf + 1);
884 numVBuf = 0;
885 }
886 else
887 numVBuf++;
888 }
889
890 /* save the number of vertex buffers sent to the device, not
891 * including trailing unbound vertex buffers.
892 */
893 svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
894 memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
895 num_vbuffers * sizeof(vbuffer_attrs[0]));
896 for (i = 0; i < num_vbuffers; i++) {
897 pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
898 vbuffers[i]);
899 }
900 }
901 }
902 else {
903 /* Even though we can avoid emitting the redundant SetVertexBuffers
904 * command, we still need to reference the vertex buffers surfaces.
905 */
906 for (i = 0; i < vbuf_count; i++) {
907 if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
908 enum pipe_error ret =
909 svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
910 NULL, SVGA_RELOC_READ);
911 if (ret != PIPE_OK)
912 return ret;
913 }
914 }
915 }
916 }
917
918 svga->rebind.flags.vertexbufs = FALSE;
919
920 return PIPE_OK;
921 }
922
923
924 /*
925 * Prepare the index buffer for a drawing command.
926 */
927 static enum pipe_error
validate_index_buffer(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,struct pipe_resource * ib)928 validate_index_buffer(struct svga_hwtnl *hwtnl,
929 const SVGA3dPrimitiveRange *range,
930 struct pipe_resource *ib)
931 {
932 struct svga_context *svga = hwtnl->svga;
933 struct svga_winsys_surface *ib_handle =
934 svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER);
935 enum pipe_error ret;
936
937 if (!ib_handle)
938 return PIPE_ERROR_OUT_OF_MEMORY;
939
940 struct svga_buffer *sbuf = svga_buffer(ib);
941 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
942 (void) sbuf; /* silence unused var warning */
943
944 SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
945
946 if (ib != svga->state.hw_draw.ib ||
947 indexFormat != svga->state.hw_draw.ib_format ||
948 range->indexArray.offset != svga->state.hw_draw.ib_offset) {
949
950 assert(indexFormat != SVGA3D_FORMAT_INVALID);
951
952 if ((ib == svga->state.hw_draw.ib) &&
953 svga_sws(hwtnl->svga)->have_index_vertex_buffer_offset_cmd &&
954 !svga->rebind.flags.indexbuf) {
955
956 ret = SVGA3D_vgpu10_SetIndexBufferOffsetAndSize(svga->swc,
957 indexFormat,
958 range->indexArray.offset,
959 sbuf->size);
960 if (ret != PIPE_OK)
961 return ret;
962 }
963 else {
964
965 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
966 indexFormat,
967 range->indexArray.offset);
968 if (ret != PIPE_OK)
969 return ret;
970 }
971
972 pipe_resource_reference(&svga->state.hw_draw.ib, ib);
973 svga->state.hw_draw.ib_format = indexFormat;
974 svga->state.hw_draw.ib_offset = range->indexArray.offset;
975 }
976 else {
977 /* Even though we can avoid emitting the redundant SetIndexBuffer
978 * command, we still need to reference the index buffer surface.
979 */
980 if (!last_command_was_draw(svga)) {
981 enum pipe_error ret = svga->swc->resource_rebind(svga->swc,
982 ib_handle,
983 NULL,
984 SVGA_RELOC_READ);
985 if (ret != PIPE_OK)
986 return ret;
987 }
988 }
989
990 svga->rebind.flags.indexbuf = FALSE;
991
992 return PIPE_OK;
993 }
994
995
996 static enum pipe_error
draw_vgpu10(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned vcount,unsigned min_index,unsigned max_index,struct pipe_resource * ib,unsigned start_instance,unsigned instance_count,const struct pipe_draw_indirect_info * indirect,const struct pipe_stream_output_target * so_vertex_count)997 draw_vgpu10(struct svga_hwtnl *hwtnl,
998 const SVGA3dPrimitiveRange *range,
999 unsigned vcount,
1000 unsigned min_index, unsigned max_index,
1001 struct pipe_resource *ib,
1002 unsigned start_instance, unsigned instance_count,
1003 const struct pipe_draw_indirect_info *indirect,
1004 const struct pipe_stream_output_target *so_vertex_count)
1005 {
1006 struct svga_context *svga = hwtnl->svga;
1007 struct svga_winsys_surface *indirect_handle;
1008 enum pipe_error ret;
1009
1010 assert(svga_have_vgpu10(svga));
1011 assert(hwtnl->cmd.prim_count == 0);
1012
1013 /* We need to reemit all the current resource bindings along with the Draw
1014 * command to be sure that the referenced resources are available for the
1015 * Draw command, just in case the surfaces associated with the resources
1016 * are paged out.
1017 */
1018 if (svga->rebind.val) {
1019 ret = svga_rebind_framebuffer_bindings(svga);
1020 if (ret != PIPE_OK)
1021 return ret;
1022
1023 ret = svga_rebind_shaders(svga);
1024 if (ret != PIPE_OK)
1025 return ret;
1026
1027 /* Rebind stream output targets */
1028 ret = svga_rebind_stream_output_targets(svga);
1029 if (ret != PIPE_OK)
1030 return ret;
1031
1032 /* No need to explicitly rebind index buffer and vertex buffers here.
1033 * Even if the same index buffer or vertex buffers are referenced for this
1034 * draw and we skip emitting the redundant set command, we will still
1035 * reference the associated resources.
1036 */
1037 }
1038
1039 ret = svga_validate_sampler_resources(svga, SVGA_PIPE_GRAPHICS);
1040 if (ret != PIPE_OK)
1041 return ret;
1042
1043 ret = svga_validate_constant_buffers(svga, SVGA_PIPE_GRAPHICS);
1044 if (ret != PIPE_OK)
1045 return ret;
1046
1047 if (svga_have_gl43(svga)) {
1048 ret = svga_validate_image_views(svga, SVGA_PIPE_GRAPHICS);
1049 if (ret != PIPE_OK)
1050 return ret;
1051
1052 ret = svga_validate_shader_buffers(svga, SVGA_PIPE_GRAPHICS);
1053 if (ret != PIPE_OK)
1054 return ret;
1055
1056 if (svga->rebind.flags.uav) {
1057 ret= svga_rebind_uav(svga);
1058 if (ret != PIPE_OK)
1059 return ret;
1060 }
1061 }
1062
1063 ret = validate_vertex_buffers(hwtnl, so_vertex_count);
1064 if (ret != PIPE_OK)
1065 return ret;
1066
1067 if (ib) {
1068 ret = validate_index_buffer(hwtnl, range, ib);
1069 if (ret != PIPE_OK)
1070 return ret;
1071 }
1072
1073 if (indirect) {
1074 indirect_handle = svga_buffer_handle(svga, indirect->buffer,
1075 PIPE_BIND_COMMAND_ARGS_BUFFER);
1076 if (!indirect_handle)
1077 return PIPE_ERROR_OUT_OF_MEMORY;
1078 }
1079 else {
1080 indirect_handle = NULL;
1081 }
1082
1083 /* Set primitive type (line, tri, etc) */
1084 if (svga->state.hw_draw.topology != range->primType) {
1085 ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
1086 if (ret != PIPE_OK)
1087 return ret;
1088
1089 svga->state.hw_draw.topology = range->primType;
1090 }
1091
1092 if (ib) {
1093 /* indexed drawing */
1094 if (indirect) {
1095 ret = SVGA3D_sm5_DrawIndexedInstancedIndirect(svga->swc,
1096 indirect_handle,
1097 indirect->offset);
1098 }
1099 else if (instance_count > 1) {
1100 ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
1101 vcount,
1102 instance_count,
1103 0, /* startIndexLocation */
1104 range->indexBias,
1105 start_instance);
1106 }
1107 else {
1108 /* non-instanced drawing */
1109 ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
1110 vcount,
1111 0, /* startIndexLocation */
1112 range->indexBias);
1113 }
1114 if (ret != PIPE_OK) {
1115 return ret;
1116 }
1117 }
1118 else {
1119 /* non-indexed drawing */
1120 if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
1121 svga->state.hw_draw.ib != NULL) {
1122 /* Unbind previously bound index buffer */
1123 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
1124 SVGA3D_FORMAT_INVALID, 0);
1125 if (ret != PIPE_OK)
1126 return ret;
1127 pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
1128 svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
1129 }
1130
1131 assert(svga->state.hw_draw.ib == NULL);
1132
1133 if (so_vertex_count) {
1134 /* Stream-output drawing */
1135 ret = SVGA3D_vgpu10_DrawAuto(svga->swc);
1136 }
1137 else if (indirect) {
1138 ret = SVGA3D_sm5_DrawInstancedIndirect(svga->swc,
1139 indirect_handle,
1140 indirect->offset);
1141 }
1142 else if (instance_count > 1) {
1143 ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
1144 vcount,
1145 instance_count,
1146 range->indexBias,
1147 start_instance);
1148 }
1149 else {
1150 /* non-instanced */
1151 ret = SVGA3D_vgpu10_Draw(svga->swc,
1152 vcount,
1153 range->indexBias);
1154 }
1155 if (ret != PIPE_OK) {
1156 return ret;
1157 }
1158 }
1159
1160 hwtnl->cmd.prim_count = 0;
1161
1162 return PIPE_OK;
1163 }
1164
1165
1166
1167 /**
1168 * Emit any pending drawing commands to the command buffer.
1169 * When we receive VGPU9 drawing commands we accumulate them and don't
1170 * immediately emit them into the command buffer.
1171 * This function needs to be called before we change state that could
1172 * effect those pending draws.
1173 */
1174 enum pipe_error
svga_hwtnl_flush(struct svga_hwtnl * hwtnl)1175 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
1176 {
1177 enum pipe_error ret = PIPE_OK;
1178
1179 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
1180
1181 if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
1182 /* we only queue up primitive for VGPU9 */
1183 ret = draw_vgpu9(hwtnl);
1184 }
1185
1186 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1187 return ret;
1188 }
1189
1190
1191 void
svga_hwtnl_set_index_bias(struct svga_hwtnl * hwtnl,int index_bias)1192 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
1193 {
1194 hwtnl->index_bias = index_bias;
1195 }
1196
1197
1198
1199 /***********************************************************************
1200 * Internal functions:
1201 */
1202
1203 /**
1204 * For debugging only.
1205 */
1206 static void
check_draw_params(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned min_index,unsigned max_index,struct pipe_resource * ib)1207 check_draw_params(struct svga_hwtnl *hwtnl,
1208 const SVGA3dPrimitiveRange *range,
1209 unsigned min_index, unsigned max_index,
1210 struct pipe_resource *ib)
1211 {
1212 unsigned i;
1213
1214 assert(!svga_have_vgpu10(hwtnl->svga));
1215
1216 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
1217 unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
1218 const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
1219 unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
1220 unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
1221 unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
1222 int index_bias = (int) range->indexBias + hwtnl->index_bias;
1223 unsigned width;
1224
1225 if (size == 0)
1226 continue;
1227
1228 assert(vb);
1229 assert(size);
1230 assert(offset < size);
1231 assert(min_index <= max_index);
1232 (void) width;
1233 (void) stride;
1234 (void) offset;
1235 (void) size;
1236
1237 switch (hwtnl->cmd.vdecl[i].identity.type) {
1238 case SVGA3D_DECLTYPE_FLOAT1:
1239 width = 4;
1240 break;
1241 case SVGA3D_DECLTYPE_FLOAT2:
1242 width = 4 * 2;
1243 break;
1244 case SVGA3D_DECLTYPE_FLOAT3:
1245 width = 4 * 3;
1246 break;
1247 case SVGA3D_DECLTYPE_FLOAT4:
1248 width = 4 * 4;
1249 break;
1250 case SVGA3D_DECLTYPE_D3DCOLOR:
1251 width = 4;
1252 break;
1253 case SVGA3D_DECLTYPE_UBYTE4:
1254 width = 1 * 4;
1255 break;
1256 case SVGA3D_DECLTYPE_SHORT2:
1257 width = 2 * 2;
1258 break;
1259 case SVGA3D_DECLTYPE_SHORT4:
1260 width = 2 * 4;
1261 break;
1262 case SVGA3D_DECLTYPE_UBYTE4N:
1263 width = 1 * 4;
1264 break;
1265 case SVGA3D_DECLTYPE_SHORT2N:
1266 width = 2 * 2;
1267 break;
1268 case SVGA3D_DECLTYPE_SHORT4N:
1269 width = 2 * 4;
1270 break;
1271 case SVGA3D_DECLTYPE_USHORT2N:
1272 width = 2 * 2;
1273 break;
1274 case SVGA3D_DECLTYPE_USHORT4N:
1275 width = 2 * 4;
1276 break;
1277 case SVGA3D_DECLTYPE_UDEC3:
1278 width = 4;
1279 break;
1280 case SVGA3D_DECLTYPE_DEC3N:
1281 width = 4;
1282 break;
1283 case SVGA3D_DECLTYPE_FLOAT16_2:
1284 width = 2 * 2;
1285 break;
1286 case SVGA3D_DECLTYPE_FLOAT16_4:
1287 width = 2 * 4;
1288 break;
1289 default:
1290 assert(0);
1291 width = 0;
1292 break;
1293 }
1294
1295 if (index_bias >= 0) {
1296 assert(offset + index_bias * stride + width <= size);
1297 }
1298
1299 /*
1300 * min_index/max_index are merely conservative guesses, so we can't
1301 * make buffer overflow detection based on their values.
1302 */
1303 }
1304
1305 assert(range->indexWidth == range->indexArray.stride);
1306
1307 if (ib) {
1308 ASSERTED unsigned size = ib->width0;
1309 ASSERTED unsigned offset = range->indexArray.offset;
1310 ASSERTED unsigned stride = range->indexArray.stride;
1311 ASSERTED unsigned count;
1312
1313 assert(size);
1314 assert(offset < size);
1315 assert(stride);
1316
1317 switch (range->primType) {
1318 case SVGA3D_PRIMITIVE_POINTLIST:
1319 count = range->primitiveCount;
1320 break;
1321 case SVGA3D_PRIMITIVE_LINELIST:
1322 count = range->primitiveCount * 2;
1323 break;
1324 case SVGA3D_PRIMITIVE_LINESTRIP:
1325 count = range->primitiveCount + 1;
1326 break;
1327 case SVGA3D_PRIMITIVE_TRIANGLELIST:
1328 count = range->primitiveCount * 3;
1329 break;
1330 case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
1331 count = range->primitiveCount + 2;
1332 break;
1333 case SVGA3D_PRIMITIVE_TRIANGLEFAN:
1334 count = range->primitiveCount + 2;
1335 break;
1336 default:
1337 assert(0);
1338 count = 0;
1339 break;
1340 }
1341
1342 assert(offset + count * stride <= size);
1343 }
1344 }
1345
1346
1347 /**
1348 * All drawing filters down into this function, either directly
1349 * on the hardware path or after doing software vertex processing.
1350 * \param indirect if non-null, get the vertex count, first vertex, etc.
1351 * from a buffer.
1352 * \param so_vertex_count if non-null, get the vertex count from a
1353 * stream-output target.
1354 */
1355 enum pipe_error
svga_hwtnl_prim(struct svga_hwtnl * hwtnl,const SVGA3dPrimitiveRange * range,unsigned vcount,unsigned min_index,unsigned max_index,struct pipe_resource * ib,unsigned start_instance,unsigned instance_count,const struct pipe_draw_indirect_info * indirect,const struct pipe_stream_output_target * so_vertex_count)1356 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
1357 const SVGA3dPrimitiveRange *range,
1358 unsigned vcount,
1359 unsigned min_index, unsigned max_index,
1360 struct pipe_resource *ib,
1361 unsigned start_instance, unsigned instance_count,
1362 const struct pipe_draw_indirect_info *indirect,
1363 const struct pipe_stream_output_target *so_vertex_count)
1364 {
1365 enum pipe_error ret = PIPE_OK;
1366
1367 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
1368
1369 if (svga_have_vgpu10(hwtnl->svga)) {
1370 /* draw immediately */
1371 SVGA_RETRY(hwtnl->svga, draw_vgpu10(hwtnl, range, vcount, min_index,
1372 max_index, ib, start_instance,
1373 instance_count, indirect,
1374 so_vertex_count));
1375 }
1376 else {
1377 /* batch up drawing commands */
1378 assert(indirect == NULL);
1379 #ifdef DEBUG
1380 check_draw_params(hwtnl, range, min_index, max_index, ib);
1381 assert(start_instance == 0);
1382 assert(instance_count <= 1);
1383 #else
1384 (void) check_draw_params;
1385 #endif
1386
1387 if (hwtnl->cmd.prim_count + 1 >= QSZ) {
1388 ret = svga_hwtnl_flush(hwtnl);
1389 if (ret != PIPE_OK)
1390 goto done;
1391 }
1392
1393 /* min/max indices are relative to bias */
1394 hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
1395 hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
1396
1397 hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
1398 hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
1399
1400 pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
1401 hwtnl->cmd.prim_count++;
1402 }
1403
1404 done:
1405 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1406 return ret;
1407 }
1408
1409
1410 /**
1411 * Return TRUE if there are pending primitives.
1412 */
1413 boolean
svga_hwtnl_has_pending_prim(struct svga_hwtnl * hwtnl)1414 svga_hwtnl_has_pending_prim(struct svga_hwtnl *hwtnl)
1415 {
1416 return hwtnl->cmd.prim_count > 0;
1417 }
1418