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