gallium: decrease the size of pipe_vertex_buffer - 24 -> 16 bytes
[mesa.git] / src / gallium / drivers / svga / svga_draw.c
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_shader.h"
42 #include "svga_surface.h"
43 #include "svga_winsys.h"
44 #include "svga_cmd.h"
45
46
47 struct svga_hwtnl *
48 svga_hwtnl_create(struct svga_context *svga)
49 {
50 struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
51 if (!hwtnl)
52 goto fail;
53
54 hwtnl->svga = svga;
55
56 hwtnl->cmd.swc = svga->swc;
57
58 return hwtnl;
59
60 fail:
61 return NULL;
62 }
63
64
65 void
66 svga_hwtnl_destroy(struct svga_hwtnl *hwtnl)
67 {
68 unsigned i, j;
69
70 for (i = 0; i < PIPE_PRIM_MAX; i++) {
71 for (j = 0; j < IDX_CACHE_MAX; j++) {
72 pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
73 }
74 }
75
76 for (i = 0; i < hwtnl->cmd.vbuf_count; i++)
77 pipe_vertex_buffer_unreference(&hwtnl->cmd.vbufs[i]);
78
79 for (i = 0; i < hwtnl->cmd.prim_count; i++)
80 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
81
82 FREE(hwtnl);
83 }
84
85
86 void
87 svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl,
88 boolean flatshade, boolean flatshade_first)
89 {
90 struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen);
91
92 /* User-specified PV */
93 hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
94
95 /* Device supported PV */
96 if (svgascreen->haveProvokingVertex) {
97 /* use the mode specified by the user */
98 hwtnl->hw_pv = hwtnl->api_pv;
99 }
100 else {
101 /* the device only support first provoking vertex */
102 hwtnl->hw_pv = PV_FIRST;
103 }
104 }
105
106
107 void
108 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
109 {
110 hwtnl->api_fillmode = mode;
111 }
112
113
114 void
115 svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl,
116 unsigned count,
117 const SVGA3dVertexDecl * decls,
118 const unsigned *buffer_indexes,
119 SVGA3dElementLayoutId layout_id)
120 {
121 assert(hwtnl->cmd.prim_count == 0);
122 hwtnl->cmd.vdecl_count = count;
123 hwtnl->cmd.vdecl_layout_id = layout_id;
124 memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls));
125 memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes,
126 count * sizeof(unsigned));
127 }
128
129
130 /**
131 * Specify vertex buffers for hardware drawing.
132 */
133 void
134 svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl,
135 unsigned count, struct pipe_vertex_buffer *buffers)
136 {
137 struct pipe_vertex_buffer *dst = hwtnl->cmd.vbufs;
138 const struct pipe_vertex_buffer *src = buffers;
139 unsigned i;
140
141 for (i = 0; i < count; i++) {
142 pipe_vertex_buffer_reference(&dst[i], &src[i]);
143 }
144
145 /* release old buffer references */
146 for ( ; i < hwtnl->cmd.vbuf_count; i++) {
147 pipe_vertex_buffer_unreference(&dst[i]);
148 /* don't bother zeroing stride/offset fields */
149 }
150
151 hwtnl->cmd.vbuf_count = count;
152 }
153
154
155 /**
156 * Determine whether the specified buffer is referred in the primitive queue,
157 * for which no commands have been written yet.
158 */
159 boolean
160 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
161 struct pipe_resource *buffer)
162 {
163 unsigned i;
164
165 if (svga_buffer_is_user_buffer(buffer)) {
166 return FALSE;
167 }
168
169 if (!hwtnl->cmd.prim_count) {
170 return FALSE;
171 }
172
173 for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) {
174 if (hwtnl->cmd.vbufs[i].buffer.resource == buffer) {
175 return TRUE;
176 }
177 }
178
179 for (i = 0; i < hwtnl->cmd.prim_count; ++i) {
180 if (hwtnl->cmd.prim_ib[i] == buffer) {
181 return TRUE;
182 }
183 }
184
185 return FALSE;
186 }
187
188
189 static enum pipe_error
190 draw_vgpu9(struct svga_hwtnl *hwtnl)
191 {
192 struct svga_winsys_context *swc = hwtnl->cmd.swc;
193 struct svga_context *svga = hwtnl->svga;
194 enum pipe_error ret;
195 struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
196 struct svga_winsys_surface *ib_handle[QSZ];
197 struct svga_winsys_surface *handle;
198 SVGA3dVertexDecl *vdecl;
199 SVGA3dPrimitiveRange *prim;
200 unsigned i;
201
202 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
203 unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
204 handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer.resource);
205 if (!handle)
206 return PIPE_ERROR_OUT_OF_MEMORY;
207
208 vb_handle[i] = handle;
209 }
210
211 for (i = 0; i < hwtnl->cmd.prim_count; i++) {
212 if (hwtnl->cmd.prim_ib[i]) {
213 handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
214 if (!handle)
215 return PIPE_ERROR_OUT_OF_MEMORY;
216 }
217 else
218 handle = NULL;
219
220 ib_handle[i] = handle;
221 }
222
223 if (svga->rebind.flags.rendertargets) {
224 ret = svga_reemit_framebuffer_bindings(svga);
225 if (ret != PIPE_OK) {
226 return ret;
227 }
228 }
229
230 if (svga->rebind.flags.texture_samplers) {
231 ret = svga_reemit_tss_bindings(svga);
232 if (ret != PIPE_OK) {
233 return ret;
234 }
235 }
236
237 if (svga->rebind.flags.vs) {
238 ret = svga_reemit_vs_bindings(svga);
239 if (ret != PIPE_OK) {
240 return ret;
241 }
242 }
243
244 if (svga->rebind.flags.fs) {
245 ret = svga_reemit_fs_bindings(svga);
246 if (ret != PIPE_OK) {
247 return ret;
248 }
249 }
250
251 SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
252 svga->curr.framebuffer.cbufs[0] ?
253 svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
254 hwtnl->cmd.prim_count);
255
256 ret = SVGA3D_BeginDrawPrimitives(swc,
257 &vdecl,
258 hwtnl->cmd.vdecl_count,
259 &prim, hwtnl->cmd.prim_count);
260 if (ret != PIPE_OK)
261 return ret;
262
263 memcpy(vdecl,
264 hwtnl->cmd.vdecl,
265 hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
266
267 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
268 /* check for 4-byte alignment */
269 assert(vdecl[i].array.offset % 4 == 0);
270 assert(vdecl[i].array.stride % 4 == 0);
271
272 /* Given rangeHint is considered to be relative to indexBias, and
273 * indexBias varies per primitive, we cannot accurately supply an
274 * rangeHint when emitting more than one primitive per draw command.
275 */
276 if (hwtnl->cmd.prim_count == 1) {
277 vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
278 vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
279 }
280 else {
281 vdecl[i].rangeHint.first = 0;
282 vdecl[i].rangeHint.last = 0;
283 }
284
285 swc->surface_relocation(swc,
286 &vdecl[i].array.surfaceId,
287 NULL, vb_handle[i], SVGA_RELOC_READ);
288 }
289
290 memcpy(prim,
291 hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
292
293 for (i = 0; i < hwtnl->cmd.prim_count; i++) {
294 swc->surface_relocation(swc,
295 &prim[i].indexArray.surfaceId,
296 NULL, ib_handle[i], SVGA_RELOC_READ);
297 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
298 }
299
300 SVGA_FIFOCommitAll(swc);
301
302 hwtnl->cmd.prim_count = 0;
303
304 return PIPE_OK;
305 }
306
307
308 static SVGA3dSurfaceFormat
309 xlate_index_format(unsigned indexWidth)
310 {
311 if (indexWidth == 2) {
312 return SVGA3D_R16_UINT;
313 }
314 else if (indexWidth == 4) {
315 return SVGA3D_R32_UINT;
316 }
317 else {
318 assert(!"Bad indexWidth");
319 return SVGA3D_R32_UINT;
320 }
321 }
322
323
324 static enum pipe_error
325 validate_sampler_resources(struct svga_context *svga)
326 {
327 enum pipe_shader_type shader;
328
329 assert(svga_have_vgpu10(svga));
330
331 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
332 unsigned count = svga->curr.num_sampler_views[shader];
333 unsigned i;
334 struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
335 enum pipe_error ret;
336
337 /*
338 * Reference bound sampler resources to ensure pending updates are
339 * noticed by the device.
340 */
341 for (i = 0; i < count; i++) {
342 struct svga_pipe_sampler_view *sv =
343 svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
344
345 if (sv) {
346 if (sv->base.texture->target == PIPE_BUFFER) {
347 surfaces[i] = svga_buffer_handle(svga, sv->base.texture);
348 }
349 else {
350 surfaces[i] = svga_texture(sv->base.texture)->handle;
351 }
352 }
353 else {
354 surfaces[i] = NULL;
355 }
356 }
357
358 if (shader == PIPE_SHADER_FRAGMENT &&
359 svga->curr.rast->templ.poly_stipple_enable) {
360 const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
361 struct svga_pipe_sampler_view *sv =
362 svga->polygon_stipple.sampler_view;
363
364 assert(sv);
365 surfaces[unit] = svga_texture(sv->base.texture)->handle;
366 count = MAX2(count, unit+1);
367 }
368
369 /* rebind the shader resources if needed */
370 if (svga->rebind.flags.texture_samplers) {
371 for (i = 0; i < count; i++) {
372 if (surfaces[i]) {
373 ret = svga->swc->resource_rebind(svga->swc,
374 surfaces[i],
375 NULL,
376 SVGA_RELOC_READ);
377 if (ret != PIPE_OK)
378 return ret;
379 }
380 }
381 }
382 }
383 svga->rebind.flags.texture_samplers = FALSE;
384
385 return PIPE_OK;
386 }
387
388
389 static enum pipe_error
390 validate_constant_buffers(struct svga_context *svga)
391 {
392 enum pipe_shader_type shader;
393
394 assert(svga_have_vgpu10(svga));
395
396 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
397 enum pipe_error ret;
398 struct svga_buffer *buffer;
399 struct svga_winsys_surface *handle;
400 unsigned enabled_constbufs;
401
402 /* Rebind the default constant buffer if needed */
403 if (svga->rebind.flags.constbufs) {
404 buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]);
405 if (buffer) {
406 ret = svga->swc->resource_rebind(svga->swc,
407 buffer->handle,
408 NULL,
409 SVGA_RELOC_READ);
410 if (ret != PIPE_OK)
411 return ret;
412 }
413 }
414
415 /*
416 * Reference other bound constant buffers to ensure pending updates are
417 * noticed by the device.
418 */
419 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
420 while (enabled_constbufs) {
421 unsigned i = u_bit_scan(&enabled_constbufs);
422 buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
423 if (buffer) {
424 handle = svga_buffer_handle(svga, &buffer->b.b);
425
426 if (svga->rebind.flags.constbufs) {
427 ret = svga->swc->resource_rebind(svga->swc,
428 handle,
429 NULL,
430 SVGA_RELOC_READ);
431 if (ret != PIPE_OK)
432 return ret;
433 }
434 }
435 }
436 }
437 svga->rebind.flags.constbufs = FALSE;
438
439 return PIPE_OK;
440 }
441
442
443 /**
444 * Was the last command put into the command buffer a drawing command?
445 * We use this to determine if we can skip emitting buffer re-bind
446 * commands when we have a sequence of drawing commands that use the
447 * same vertex/index buffers with no intervening commands.
448 *
449 * The first drawing command will bind the vertex/index buffers. If
450 * the immediately following command is also a drawing command using the
451 * same buffers, we shouldn't have to rebind them.
452 */
453 static bool
454 last_command_was_draw(const struct svga_context *svga)
455 {
456 switch (SVGA3D_GetLastCommand(svga->swc)) {
457 case SVGA_3D_CMD_DX_DRAW:
458 case SVGA_3D_CMD_DX_DRAW_INDEXED:
459 case SVGA_3D_CMD_DX_DRAW_INSTANCED:
460 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
461 case SVGA_3D_CMD_DX_DRAW_AUTO:
462 return true;
463 default:
464 return false;
465 }
466 }
467
468
469 static enum pipe_error
470 draw_vgpu10(struct svga_hwtnl *hwtnl,
471 const SVGA3dPrimitiveRange *range,
472 unsigned vcount,
473 unsigned min_index,
474 unsigned max_index, struct pipe_resource *ib,
475 unsigned start_instance, unsigned instance_count)
476 {
477 struct svga_context *svga = hwtnl->svga;
478 struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
479 struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
480 struct svga_winsys_surface *ib_handle;
481 const unsigned vbuf_count = hwtnl->cmd.vbuf_count;
482 int last_vbuf = -1;
483 enum pipe_error ret;
484 unsigned i;
485
486 assert(svga_have_vgpu10(svga));
487 assert(hwtnl->cmd.prim_count == 0);
488
489 /* We need to reemit all the current resource bindings along with the Draw
490 * command to be sure that the referenced resources are available for the
491 * Draw command, just in case the surfaces associated with the resources
492 * are paged out.
493 */
494 if (svga->rebind.val) {
495 ret = svga_rebind_framebuffer_bindings(svga);
496 if (ret != PIPE_OK)
497 return ret;
498
499 ret = svga_rebind_shaders(svga);
500 if (ret != PIPE_OK)
501 return ret;
502
503 /* Rebind stream output targets */
504 ret = svga_rebind_stream_output_targets(svga);
505 if (ret != PIPE_OK)
506 return ret;
507
508 /* No need to explicitly rebind index buffer and vertex buffers here.
509 * Even if the same index buffer or vertex buffers are referenced for this
510 * draw and we skip emitting the redundant set command, we will still
511 * reference the associated resources.
512 */
513 }
514
515 ret = validate_sampler_resources(svga);
516 if (ret != PIPE_OK)
517 return ret;
518
519 ret = validate_constant_buffers(svga);
520 if (ret != PIPE_OK)
521 return ret;
522
523 /* Get handle for each referenced vertex buffer */
524 for (i = 0; i < vbuf_count; i++) {
525 struct svga_buffer *sbuf = svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
526
527 if (sbuf) {
528 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
529 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b);
530 if (vbuffer_handles[i] == NULL)
531 return PIPE_ERROR_OUT_OF_MEMORY;
532 vbuffers[i] = &sbuf->b.b;
533 last_vbuf = i;
534 }
535 else {
536 vbuffers[i] = NULL;
537 vbuffer_handles[i] = NULL;
538 }
539 }
540
541 for (; i < svga->state.hw_draw.num_vbuffers; i++) {
542 vbuffers[i] = NULL;
543 vbuffer_handles[i] = NULL;
544 }
545
546 /* Get handle for the index buffer */
547 if (ib) {
548 struct svga_buffer *sbuf = svga_buffer(ib);
549
550 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
551 (void) sbuf; /* silence unused var warning */
552
553 ib_handle = svga_buffer_handle(svga, ib);
554 if (!ib_handle)
555 return PIPE_ERROR_OUT_OF_MEMORY;
556 }
557 else {
558 ib_handle = NULL;
559 }
560
561 /* setup vertex attribute input layout */
562 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
563 ret = SVGA3D_vgpu10_SetInputLayout(svga->swc,
564 hwtnl->cmd.vdecl_layout_id);
565 if (ret != PIPE_OK)
566 return ret;
567
568 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
569 }
570
571 /* setup vertex buffers */
572 {
573 SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS];
574
575 for (i = 0; i < vbuf_count; i++) {
576 vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
577 vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
578 vbuffer_attrs[i].sid = 0;
579 }
580
581 /* If we haven't yet emitted a drawing command or if any
582 * vertex buffer state is changing, issue that state now.
583 */
584 if (((hwtnl->cmd.swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) == 0) ||
585 vbuf_count != svga->state.hw_draw.num_vbuffers ||
586 memcmp(vbuffer_attrs, svga->state.hw_draw.vbuffer_attrs,
587 vbuf_count * sizeof(vbuffer_attrs[0])) ||
588 memcmp(vbuffers, svga->state.hw_draw.vbuffers,
589 vbuf_count * sizeof(vbuffers[0]))) {
590
591 unsigned num_vbuffers;
592
593 /* get the max of the current bound vertex buffers count and
594 * the to-be-bound vertex buffers count, so as to unbind
595 * the unused vertex buffers.
596 */
597 num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
598
599 /* Zero-out the old buffers we want to unbind (the number of loop
600 * iterations here is typically very small, and often zero.)
601 */
602 for (i = vbuf_count; i < num_vbuffers; i++) {
603 vbuffer_attrs[i].sid = 0;
604 vbuffer_attrs[i].stride = 0;
605 vbuffer_attrs[i].offset = 0;
606 vbuffer_handles[i] = NULL;
607 }
608
609 if (num_vbuffers > 0) {
610
611 ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc, num_vbuffers,
612 0, /* startBuffer */
613 vbuffer_attrs,
614 vbuffer_handles);
615 if (ret != PIPE_OK)
616 return ret;
617
618 /* save the number of vertex buffers sent to the device, not
619 * including trailing unbound vertex buffers.
620 */
621 svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
622 memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
623 num_vbuffers * sizeof(vbuffer_attrs[0]));
624 for (i = 0; i < num_vbuffers; i++) {
625 pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
626 vbuffers[i]);
627 }
628 }
629 }
630 else {
631 /* Even though we can avoid emitting the redundant SetVertexBuffers
632 * command, we still need to reference the vertex buffers surfaces.
633 */
634 for (i = 0; i < vbuf_count; i++) {
635 if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
636 ret = svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
637 NULL, SVGA_RELOC_READ);
638 if (ret != PIPE_OK)
639 return ret;
640 }
641 }
642 }
643 }
644
645 /* Set primitive type (line, tri, etc) */
646 if (svga->state.hw_draw.topology != range->primType) {
647 ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
648 if (ret != PIPE_OK)
649 return ret;
650
651 svga->state.hw_draw.topology = range->primType;
652 }
653
654 if (ib_handle) {
655 /* indexed drawing */
656 SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
657
658 /* setup index buffer */
659 if (ib != svga->state.hw_draw.ib ||
660 indexFormat != svga->state.hw_draw.ib_format ||
661 range->indexArray.offset != svga->state.hw_draw.ib_offset) {
662
663 assert(indexFormat != SVGA3D_FORMAT_INVALID);
664 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
665 indexFormat,
666 range->indexArray.offset);
667 if (ret != PIPE_OK)
668 return ret;
669
670 pipe_resource_reference(&svga->state.hw_draw.ib, ib);
671 svga->state.hw_draw.ib_format = indexFormat;
672 svga->state.hw_draw.ib_offset = range->indexArray.offset;
673 }
674 else {
675 /* Even though we can avoid emitting the redundant SetIndexBuffer
676 * command, we still need to reference the index buffer surface.
677 */
678 if (!last_command_was_draw(svga)) {
679 ret = svga->swc->resource_rebind(svga->swc, ib_handle,
680 NULL, SVGA_RELOC_READ);
681 if (ret != PIPE_OK)
682 return ret;
683 }
684 }
685
686 if (instance_count > 1) {
687 ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
688 vcount,
689 instance_count,
690 0, /* startIndexLocation */
691 range->indexBias,
692 start_instance);
693 if (ret != PIPE_OK)
694 return ret;
695 }
696 else {
697 /* non-instanced drawing */
698 ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
699 vcount,
700 0, /* startIndexLocation */
701 range->indexBias);
702 if (ret != PIPE_OK)
703 return ret;
704 }
705 }
706 else {
707 /* non-indexed drawing */
708 if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
709 svga->state.hw_draw.ib != NULL) {
710 /* Unbind previously bound index buffer */
711 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
712 SVGA3D_FORMAT_INVALID, 0);
713 if (ret != PIPE_OK)
714 return ret;
715 pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
716 svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
717 }
718
719 assert(svga->state.hw_draw.ib == NULL);
720
721 if (instance_count > 1) {
722 ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
723 vcount,
724 instance_count,
725 range->indexBias,
726 start_instance);
727 if (ret != PIPE_OK)
728 return ret;
729 }
730 else {
731 /* non-instanced */
732 ret = SVGA3D_vgpu10_Draw(svga->swc,
733 vcount,
734 range->indexBias);
735 if (ret != PIPE_OK)
736 return ret;
737 }
738 }
739
740 hwtnl->cmd.prim_count = 0;
741
742 return PIPE_OK;
743 }
744
745
746
747 /**
748 * Emit any pending drawing commands to the command buffer.
749 * When we receive VGPU9 drawing commands we accumulate them and don't
750 * immediately emit them into the command buffer.
751 * This function needs to be called before we change state that could
752 * effect those pending draws.
753 */
754 enum pipe_error
755 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
756 {
757 enum pipe_error ret = PIPE_OK;
758
759 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
760
761 if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
762 /* we only queue up primitive for VGPU9 */
763 ret = draw_vgpu9(hwtnl);
764 }
765
766 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
767 return ret;
768 }
769
770
771 void
772 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
773 {
774 hwtnl->index_bias = index_bias;
775 }
776
777
778
779 /***********************************************************************
780 * Internal functions:
781 */
782
783 /**
784 * For debugging only.
785 */
786 static void
787 check_draw_params(struct svga_hwtnl *hwtnl,
788 const SVGA3dPrimitiveRange *range,
789 unsigned min_index, unsigned max_index,
790 struct pipe_resource *ib)
791 {
792 unsigned i;
793
794 assert(!svga_have_vgpu10(hwtnl->svga));
795
796 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
797 unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
798 const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
799 unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
800 unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
801 unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
802 int index_bias = (int) range->indexBias + hwtnl->index_bias;
803 unsigned width;
804
805 if (size == 0)
806 continue;
807
808 assert(vb);
809 assert(size);
810 assert(offset < size);
811 assert(min_index <= max_index);
812 (void) width;
813 (void) stride;
814 (void) offset;
815 (void) size;
816
817 switch (hwtnl->cmd.vdecl[i].identity.type) {
818 case SVGA3D_DECLTYPE_FLOAT1:
819 width = 4;
820 break;
821 case SVGA3D_DECLTYPE_FLOAT2:
822 width = 4 * 2;
823 break;
824 case SVGA3D_DECLTYPE_FLOAT3:
825 width = 4 * 3;
826 break;
827 case SVGA3D_DECLTYPE_FLOAT4:
828 width = 4 * 4;
829 break;
830 case SVGA3D_DECLTYPE_D3DCOLOR:
831 width = 4;
832 break;
833 case SVGA3D_DECLTYPE_UBYTE4:
834 width = 1 * 4;
835 break;
836 case SVGA3D_DECLTYPE_SHORT2:
837 width = 2 * 2;
838 break;
839 case SVGA3D_DECLTYPE_SHORT4:
840 width = 2 * 4;
841 break;
842 case SVGA3D_DECLTYPE_UBYTE4N:
843 width = 1 * 4;
844 break;
845 case SVGA3D_DECLTYPE_SHORT2N:
846 width = 2 * 2;
847 break;
848 case SVGA3D_DECLTYPE_SHORT4N:
849 width = 2 * 4;
850 break;
851 case SVGA3D_DECLTYPE_USHORT2N:
852 width = 2 * 2;
853 break;
854 case SVGA3D_DECLTYPE_USHORT4N:
855 width = 2 * 4;
856 break;
857 case SVGA3D_DECLTYPE_UDEC3:
858 width = 4;
859 break;
860 case SVGA3D_DECLTYPE_DEC3N:
861 width = 4;
862 break;
863 case SVGA3D_DECLTYPE_FLOAT16_2:
864 width = 2 * 2;
865 break;
866 case SVGA3D_DECLTYPE_FLOAT16_4:
867 width = 2 * 4;
868 break;
869 default:
870 assert(0);
871 width = 0;
872 break;
873 }
874
875 if (index_bias >= 0) {
876 assert(offset + index_bias * stride + width <= size);
877 }
878
879 /*
880 * min_index/max_index are merely conservative guesses, so we can't
881 * make buffer overflow detection based on their values.
882 */
883 }
884
885 assert(range->indexWidth == range->indexArray.stride);
886
887 if (ib) {
888 MAYBE_UNUSED unsigned size = ib->width0;
889 MAYBE_UNUSED unsigned offset = range->indexArray.offset;
890 MAYBE_UNUSED unsigned stride = range->indexArray.stride;
891 MAYBE_UNUSED unsigned count;
892
893 assert(size);
894 assert(offset < size);
895 assert(stride);
896
897 switch (range->primType) {
898 case SVGA3D_PRIMITIVE_POINTLIST:
899 count = range->primitiveCount;
900 break;
901 case SVGA3D_PRIMITIVE_LINELIST:
902 count = range->primitiveCount * 2;
903 break;
904 case SVGA3D_PRIMITIVE_LINESTRIP:
905 count = range->primitiveCount + 1;
906 break;
907 case SVGA3D_PRIMITIVE_TRIANGLELIST:
908 count = range->primitiveCount * 3;
909 break;
910 case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
911 count = range->primitiveCount + 2;
912 break;
913 case SVGA3D_PRIMITIVE_TRIANGLEFAN:
914 count = range->primitiveCount + 2;
915 break;
916 default:
917 assert(0);
918 count = 0;
919 break;
920 }
921
922 assert(offset + count * stride <= size);
923 }
924 }
925
926
927 /**
928 * All drawing filters down into this function, either directly
929 * on the hardware path or after doing software vertex processing.
930 */
931 enum pipe_error
932 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
933 const SVGA3dPrimitiveRange * range,
934 unsigned vcount,
935 unsigned min_index,
936 unsigned max_index, struct pipe_resource *ib,
937 unsigned start_instance, unsigned instance_count)
938 {
939 enum pipe_error ret = PIPE_OK;
940
941 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
942
943 if (svga_have_vgpu10(hwtnl->svga)) {
944 /* draw immediately */
945 ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib,
946 start_instance, instance_count);
947 if (ret != PIPE_OK) {
948 svga_context_flush(hwtnl->svga, NULL);
949 ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib,
950 start_instance, instance_count);
951 assert(ret == PIPE_OK);
952 }
953 }
954 else {
955 /* batch up drawing commands */
956 #ifdef DEBUG
957 check_draw_params(hwtnl, range, min_index, max_index, ib);
958 assert(start_instance == 0);
959 assert(instance_count <= 1);
960 #else
961 (void) check_draw_params;
962 #endif
963
964 if (hwtnl->cmd.prim_count + 1 >= QSZ) {
965 ret = svga_hwtnl_flush(hwtnl);
966 if (ret != PIPE_OK)
967 goto done;
968 }
969
970 /* min/max indices are relative to bias */
971 hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
972 hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
973
974 hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
975 hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
976
977 pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
978 hwtnl->cmd.prim_count++;
979 }
980
981 done:
982 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
983 return ret;
984 }