svga: fix blending regression
[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_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 *
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
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
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
109 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode)
110 {
111 hwtnl->api_fillmode = mode;
112 }
113
114
115 void
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
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
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
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
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 static enum pipe_error
346 validate_sampler_resources(struct svga_context *svga)
347 {
348 enum pipe_shader_type shader;
349
350 assert(svga_have_vgpu10(svga));
351
352 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
353 unsigned count = svga->curr.num_sampler_views[shader];
354 unsigned i;
355 struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
356 enum pipe_error ret;
357
358 /*
359 * Reference bound sampler resources to ensure pending updates are
360 * noticed by the device.
361 */
362 for (i = 0; i < count; i++) {
363 struct svga_pipe_sampler_view *sv =
364 svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
365
366 if (sv) {
367 if (sv->base.texture->target == PIPE_BUFFER) {
368 surfaces[i] = svga_buffer_handle(svga, sv->base.texture,
369 PIPE_BIND_SAMPLER_VIEW);
370 }
371 else {
372 surfaces[i] = svga_texture(sv->base.texture)->handle;
373 }
374 }
375 else {
376 surfaces[i] = NULL;
377 }
378 }
379
380 if (shader == PIPE_SHADER_FRAGMENT &&
381 svga->curr.rast->templ.poly_stipple_enable) {
382 const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
383 struct svga_pipe_sampler_view *sv =
384 svga->polygon_stipple.sampler_view;
385
386 assert(sv);
387 surfaces[unit] = svga_texture(sv->base.texture)->handle;
388 count = MAX2(count, unit+1);
389 }
390
391 /* rebind the shader resources if needed */
392 if (svga->rebind.flags.texture_samplers) {
393 for (i = 0; i < count; i++) {
394 if (surfaces[i]) {
395 ret = svga->swc->resource_rebind(svga->swc,
396 surfaces[i],
397 NULL,
398 SVGA_RELOC_READ);
399 if (ret != PIPE_OK)
400 return ret;
401 }
402 }
403 }
404 }
405 svga->rebind.flags.texture_samplers = FALSE;
406
407 return PIPE_OK;
408 }
409
410
411 static enum pipe_error
412 validate_constant_buffers(struct svga_context *svga)
413 {
414 enum pipe_shader_type shader;
415
416 assert(svga_have_vgpu10(svga));
417
418 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
419 enum pipe_error ret;
420 struct svga_buffer *buffer;
421 struct svga_winsys_surface *handle;
422 unsigned enabled_constbufs;
423
424 /* Rebind the default constant buffer if needed */
425 if (svga->rebind.flags.constbufs) {
426 buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]);
427 if (buffer) {
428 ret = svga->swc->resource_rebind(svga->swc,
429 buffer->handle,
430 NULL,
431 SVGA_RELOC_READ);
432 if (ret != PIPE_OK)
433 return ret;
434 }
435 }
436
437 /*
438 * Reference other bound constant buffers to ensure pending updates are
439 * noticed by the device.
440 */
441 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u;
442 while (enabled_constbufs) {
443 unsigned i = u_bit_scan(&enabled_constbufs);
444 buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
445 if (buffer) {
446 handle = svga_buffer_handle(svga, &buffer->b.b,
447 PIPE_BIND_CONSTANT_BUFFER);
448
449 if (svga->rebind.flags.constbufs) {
450 ret = svga->swc->resource_rebind(svga->swc,
451 handle,
452 NULL,
453 SVGA_RELOC_READ);
454 if (ret != PIPE_OK)
455 return ret;
456 }
457 }
458 }
459 }
460 svga->rebind.flags.constbufs = FALSE;
461
462 return PIPE_OK;
463 }
464
465
466 /**
467 * Was the last command put into the command buffer a drawing command?
468 * We use this to determine if we can skip emitting buffer re-bind
469 * commands when we have a sequence of drawing commands that use the
470 * same vertex/index buffers with no intervening commands.
471 *
472 * The first drawing command will bind the vertex/index buffers. If
473 * the immediately following command is also a drawing command using the
474 * same buffers, we shouldn't have to rebind them.
475 */
476 static bool
477 last_command_was_draw(const struct svga_context *svga)
478 {
479 switch (SVGA3D_GetLastCommand(svga->swc)) {
480 case SVGA_3D_CMD_DX_DRAW:
481 case SVGA_3D_CMD_DX_DRAW_INDEXED:
482 case SVGA_3D_CMD_DX_DRAW_INSTANCED:
483 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED:
484 case SVGA_3D_CMD_DX_DRAW_AUTO:
485 return true;
486 default:
487 return false;
488 }
489 }
490
491
492 /**
493 * A helper function to compare vertex buffers.
494 * They are equal if the vertex buffer attributes and the vertex buffer
495 * resources are identical.
496 */
497 static boolean
498 vertex_buffers_equal(unsigned count,
499 SVGA3dVertexBuffer *pVBufAttr1,
500 struct pipe_resource **pVBuf1,
501 SVGA3dVertexBuffer *pVBufAttr2,
502 struct pipe_resource **pVBuf2)
503 {
504 return (memcmp(pVBufAttr1, pVBufAttr2,
505 count * sizeof(*pVBufAttr1)) == 0) &&
506 (memcmp(pVBuf1, pVBuf2, count * sizeof(*pVBuf1)) == 0);
507 }
508
509
510 static enum pipe_error
511 draw_vgpu10(struct svga_hwtnl *hwtnl,
512 const SVGA3dPrimitiveRange *range,
513 unsigned vcount,
514 struct pipe_resource *ib,
515 unsigned start_instance, unsigned instance_count)
516 {
517 struct svga_context *svga = hwtnl->svga;
518 struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX];
519 struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX];
520 struct svga_winsys_surface *ib_handle;
521 const unsigned vbuf_count = hwtnl->cmd.vbuf_count;
522 int last_vbuf = -1;
523 enum pipe_error ret;
524 unsigned i;
525
526 assert(svga_have_vgpu10(svga));
527 assert(hwtnl->cmd.prim_count == 0);
528
529 /* We need to reemit all the current resource bindings along with the Draw
530 * command to be sure that the referenced resources are available for the
531 * Draw command, just in case the surfaces associated with the resources
532 * are paged out.
533 */
534 if (svga->rebind.val) {
535 ret = svga_rebind_framebuffer_bindings(svga);
536 if (ret != PIPE_OK)
537 return ret;
538
539 ret = svga_rebind_shaders(svga);
540 if (ret != PIPE_OK)
541 return ret;
542
543 /* Rebind stream output targets */
544 ret = svga_rebind_stream_output_targets(svga);
545 if (ret != PIPE_OK)
546 return ret;
547
548 /* No need to explicitly rebind index buffer and vertex buffers here.
549 * Even if the same index buffer or vertex buffers are referenced for this
550 * draw and we skip emitting the redundant set command, we will still
551 * reference the associated resources.
552 */
553 }
554
555 ret = validate_sampler_resources(svga);
556 if (ret != PIPE_OK)
557 return ret;
558
559 ret = validate_constant_buffers(svga);
560 if (ret != PIPE_OK)
561 return ret;
562
563 /* Get handle for each referenced vertex buffer */
564 for (i = 0; i < vbuf_count; i++) {
565 struct svga_buffer *sbuf = svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource);
566
567 if (sbuf) {
568 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b,
569 PIPE_BIND_VERTEX_BUFFER);
570 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER);
571 if (vbuffer_handles[i] == NULL)
572 return PIPE_ERROR_OUT_OF_MEMORY;
573 vbuffers[i] = &sbuf->b.b;
574 last_vbuf = i;
575 }
576 else {
577 vbuffers[i] = NULL;
578 vbuffer_handles[i] = NULL;
579 }
580 }
581
582 for (; i < svga->state.hw_draw.num_vbuffers; i++) {
583 vbuffers[i] = NULL;
584 vbuffer_handles[i] = NULL;
585 }
586
587 /* Get handle for the index buffer */
588 if (ib) {
589 struct svga_buffer *sbuf = svga_buffer(ib);
590
591 ib_handle = svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER);
592 if (!ib_handle)
593 return PIPE_ERROR_OUT_OF_MEMORY;
594
595 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER);
596 (void) sbuf; /* silence unused var warning */
597 }
598 else {
599 ib_handle = NULL;
600 }
601
602 /* setup vertex attribute input layout */
603 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) {
604 ret = SVGA3D_vgpu10_SetInputLayout(svga->swc,
605 hwtnl->cmd.vdecl_layout_id);
606 if (ret != PIPE_OK)
607 return ret;
608
609 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id;
610 }
611
612 /* setup vertex buffers */
613 {
614 SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS];
615
616 for (i = 0; i < vbuf_count; i++) {
617 vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride;
618 vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset;
619 vbuffer_attrs[i].sid = 0;
620 }
621
622 /* If we haven't yet emitted a drawing command or if any
623 * vertex buffer state is changing, issue that state now.
624 */
625 if (((hwtnl->cmd.swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) == 0) ||
626 vbuf_count != svga->state.hw_draw.num_vbuffers ||
627 !vertex_buffers_equal(vbuf_count,
628 vbuffer_attrs,
629 vbuffers,
630 svga->state.hw_draw.vbuffer_attrs,
631 svga->state.hw_draw.vbuffers)) {
632
633 unsigned num_vbuffers;
634
635 /* get the max of the current bound vertex buffers count and
636 * the to-be-bound vertex buffers count, so as to unbind
637 * the unused vertex buffers.
638 */
639 num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers);
640
641 /* Zero-out the old buffers we want to unbind (the number of loop
642 * iterations here is typically very small, and often zero.)
643 */
644 for (i = vbuf_count; i < num_vbuffers; i++) {
645 vbuffer_attrs[i].sid = 0;
646 vbuffer_attrs[i].stride = 0;
647 vbuffer_attrs[i].offset = 0;
648 vbuffer_handles[i] = NULL;
649 }
650
651 if (num_vbuffers > 0) {
652 SVGA3dVertexBuffer *pbufAttrs = vbuffer_attrs;
653 struct svga_winsys_surface **pbufHandles = vbuffer_handles;
654 unsigned numVBuf = 0;
655
656 /* Loop through the vertex buffer lists to only emit
657 * those vertex buffers that are not already in the
658 * corresponding entries in the device's vertex buffer list.
659 */
660 for (i = 0; i < num_vbuffers; i++) {
661 boolean emit;
662
663 emit = vertex_buffers_equal(1,
664 &vbuffer_attrs[i],
665 &vbuffers[i],
666 &svga->state.hw_draw.vbuffer_attrs[i],
667 &svga->state.hw_draw.vbuffers[i]);
668
669 if (!emit && i == num_vbuffers-1) {
670 /* Include the last vertex buffer in the next emit
671 * if it is different.
672 */
673 emit = TRUE;
674 numVBuf++;
675 i++;
676 }
677
678 if (emit) {
679 /* numVBuf can only be 0 if the first vertex buffer
680 * is the same as the one in the device's list.
681 * In this case, there is nothing to send yet.
682 */
683 if (numVBuf) {
684 ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc,
685 numVBuf,
686 i - numVBuf,
687 pbufAttrs, pbufHandles);
688 if (ret != PIPE_OK)
689 return ret;
690 }
691 pbufAttrs += (numVBuf + 1);
692 pbufHandles += (numVBuf + 1);
693 numVBuf = 0;
694 }
695 else
696 numVBuf++;
697 }
698
699 /* save the number of vertex buffers sent to the device, not
700 * including trailing unbound vertex buffers.
701 */
702 svga->state.hw_draw.num_vbuffers = last_vbuf + 1;
703 memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs,
704 num_vbuffers * sizeof(vbuffer_attrs[0]));
705 for (i = 0; i < num_vbuffers; i++) {
706 pipe_resource_reference(&svga->state.hw_draw.vbuffers[i],
707 vbuffers[i]);
708 }
709 }
710 }
711 else {
712 /* Even though we can avoid emitting the redundant SetVertexBuffers
713 * command, we still need to reference the vertex buffers surfaces.
714 */
715 for (i = 0; i < vbuf_count; i++) {
716 if (vbuffer_handles[i] && !last_command_was_draw(svga)) {
717 ret = svga->swc->resource_rebind(svga->swc, vbuffer_handles[i],
718 NULL, SVGA_RELOC_READ);
719 if (ret != PIPE_OK)
720 return ret;
721 }
722 }
723 }
724 }
725
726 /* Set primitive type (line, tri, etc) */
727 if (svga->state.hw_draw.topology != range->primType) {
728 ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType);
729 if (ret != PIPE_OK)
730 return ret;
731
732 svga->state.hw_draw.topology = range->primType;
733 }
734
735 if (ib_handle) {
736 /* indexed drawing */
737 SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth);
738
739 /* setup index buffer */
740 if (ib != svga->state.hw_draw.ib ||
741 indexFormat != svga->state.hw_draw.ib_format ||
742 range->indexArray.offset != svga->state.hw_draw.ib_offset) {
743
744 assert(indexFormat != SVGA3D_FORMAT_INVALID);
745 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle,
746 indexFormat,
747 range->indexArray.offset);
748 if (ret != PIPE_OK)
749 return ret;
750
751 pipe_resource_reference(&svga->state.hw_draw.ib, ib);
752 svga->state.hw_draw.ib_format = indexFormat;
753 svga->state.hw_draw.ib_offset = range->indexArray.offset;
754 }
755 else {
756 /* Even though we can avoid emitting the redundant SetIndexBuffer
757 * command, we still need to reference the index buffer surface.
758 */
759 if (!last_command_was_draw(svga)) {
760 ret = svga->swc->resource_rebind(svga->swc, ib_handle,
761 NULL, SVGA_RELOC_READ);
762 if (ret != PIPE_OK)
763 return ret;
764 }
765 }
766
767 if (instance_count > 1) {
768 ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc,
769 vcount,
770 instance_count,
771 0, /* startIndexLocation */
772 range->indexBias,
773 start_instance);
774 if (ret != PIPE_OK)
775 return ret;
776 }
777 else {
778 /* non-instanced drawing */
779 ret = SVGA3D_vgpu10_DrawIndexed(svga->swc,
780 vcount,
781 0, /* startIndexLocation */
782 range->indexBias);
783 if (ret != PIPE_OK)
784 return ret;
785 }
786 }
787 else {
788 /* non-indexed drawing */
789 if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID ||
790 svga->state.hw_draw.ib != NULL) {
791 /* Unbind previously bound index buffer */
792 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL,
793 SVGA3D_FORMAT_INVALID, 0);
794 if (ret != PIPE_OK)
795 return ret;
796 pipe_resource_reference(&svga->state.hw_draw.ib, NULL);
797 svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID;
798 }
799
800 assert(svga->state.hw_draw.ib == NULL);
801
802 if (instance_count > 1) {
803 ret = SVGA3D_vgpu10_DrawInstanced(svga->swc,
804 vcount,
805 instance_count,
806 range->indexBias,
807 start_instance);
808 if (ret != PIPE_OK)
809 return ret;
810 }
811 else {
812 /* non-instanced */
813 ret = SVGA3D_vgpu10_Draw(svga->swc,
814 vcount,
815 range->indexBias);
816 if (ret != PIPE_OK)
817 return ret;
818 }
819 }
820
821 hwtnl->cmd.prim_count = 0;
822
823 return PIPE_OK;
824 }
825
826
827
828 /**
829 * Emit any pending drawing commands to the command buffer.
830 * When we receive VGPU9 drawing commands we accumulate them and don't
831 * immediately emit them into the command buffer.
832 * This function needs to be called before we change state that could
833 * effect those pending draws.
834 */
835 enum pipe_error
836 svga_hwtnl_flush(struct svga_hwtnl *hwtnl)
837 {
838 enum pipe_error ret = PIPE_OK;
839
840 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH);
841
842 if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) {
843 /* we only queue up primitive for VGPU9 */
844 ret = draw_vgpu9(hwtnl);
845 }
846
847 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
848 return ret;
849 }
850
851
852 void
853 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
854 {
855 hwtnl->index_bias = index_bias;
856 }
857
858
859
860 /***********************************************************************
861 * Internal functions:
862 */
863
864 /**
865 * For debugging only.
866 */
867 static void
868 check_draw_params(struct svga_hwtnl *hwtnl,
869 const SVGA3dPrimitiveRange *range,
870 unsigned min_index, unsigned max_index,
871 struct pipe_resource *ib)
872 {
873 unsigned i;
874
875 assert(!svga_have_vgpu10(hwtnl->svga));
876
877 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
878 unsigned j = hwtnl->cmd.vdecl_buffer_index[i];
879 const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j];
880 unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0;
881 unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
882 unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
883 int index_bias = (int) range->indexBias + hwtnl->index_bias;
884 unsigned width;
885
886 if (size == 0)
887 continue;
888
889 assert(vb);
890 assert(size);
891 assert(offset < size);
892 assert(min_index <= max_index);
893 (void) width;
894 (void) stride;
895 (void) offset;
896 (void) size;
897
898 switch (hwtnl->cmd.vdecl[i].identity.type) {
899 case SVGA3D_DECLTYPE_FLOAT1:
900 width = 4;
901 break;
902 case SVGA3D_DECLTYPE_FLOAT2:
903 width = 4 * 2;
904 break;
905 case SVGA3D_DECLTYPE_FLOAT3:
906 width = 4 * 3;
907 break;
908 case SVGA3D_DECLTYPE_FLOAT4:
909 width = 4 * 4;
910 break;
911 case SVGA3D_DECLTYPE_D3DCOLOR:
912 width = 4;
913 break;
914 case SVGA3D_DECLTYPE_UBYTE4:
915 width = 1 * 4;
916 break;
917 case SVGA3D_DECLTYPE_SHORT2:
918 width = 2 * 2;
919 break;
920 case SVGA3D_DECLTYPE_SHORT4:
921 width = 2 * 4;
922 break;
923 case SVGA3D_DECLTYPE_UBYTE4N:
924 width = 1 * 4;
925 break;
926 case SVGA3D_DECLTYPE_SHORT2N:
927 width = 2 * 2;
928 break;
929 case SVGA3D_DECLTYPE_SHORT4N:
930 width = 2 * 4;
931 break;
932 case SVGA3D_DECLTYPE_USHORT2N:
933 width = 2 * 2;
934 break;
935 case SVGA3D_DECLTYPE_USHORT4N:
936 width = 2 * 4;
937 break;
938 case SVGA3D_DECLTYPE_UDEC3:
939 width = 4;
940 break;
941 case SVGA3D_DECLTYPE_DEC3N:
942 width = 4;
943 break;
944 case SVGA3D_DECLTYPE_FLOAT16_2:
945 width = 2 * 2;
946 break;
947 case SVGA3D_DECLTYPE_FLOAT16_4:
948 width = 2 * 4;
949 break;
950 default:
951 assert(0);
952 width = 0;
953 break;
954 }
955
956 if (index_bias >= 0) {
957 assert(offset + index_bias * stride + width <= size);
958 }
959
960 /*
961 * min_index/max_index are merely conservative guesses, so we can't
962 * make buffer overflow detection based on their values.
963 */
964 }
965
966 assert(range->indexWidth == range->indexArray.stride);
967
968 if (ib) {
969 MAYBE_UNUSED unsigned size = ib->width0;
970 MAYBE_UNUSED unsigned offset = range->indexArray.offset;
971 MAYBE_UNUSED unsigned stride = range->indexArray.stride;
972 MAYBE_UNUSED unsigned count;
973
974 assert(size);
975 assert(offset < size);
976 assert(stride);
977
978 switch (range->primType) {
979 case SVGA3D_PRIMITIVE_POINTLIST:
980 count = range->primitiveCount;
981 break;
982 case SVGA3D_PRIMITIVE_LINELIST:
983 count = range->primitiveCount * 2;
984 break;
985 case SVGA3D_PRIMITIVE_LINESTRIP:
986 count = range->primitiveCount + 1;
987 break;
988 case SVGA3D_PRIMITIVE_TRIANGLELIST:
989 count = range->primitiveCount * 3;
990 break;
991 case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
992 count = range->primitiveCount + 2;
993 break;
994 case SVGA3D_PRIMITIVE_TRIANGLEFAN:
995 count = range->primitiveCount + 2;
996 break;
997 default:
998 assert(0);
999 count = 0;
1000 break;
1001 }
1002
1003 assert(offset + count * stride <= size);
1004 }
1005 }
1006
1007
1008 /**
1009 * All drawing filters down into this function, either directly
1010 * on the hardware path or after doing software vertex processing.
1011 */
1012 enum pipe_error
1013 svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
1014 const SVGA3dPrimitiveRange * range,
1015 unsigned vcount,
1016 unsigned min_index,
1017 unsigned max_index, struct pipe_resource *ib,
1018 unsigned start_instance, unsigned instance_count)
1019 {
1020 enum pipe_error ret = PIPE_OK;
1021
1022 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM);
1023
1024 if (svga_have_vgpu10(hwtnl->svga)) {
1025 /* draw immediately */
1026 ret = draw_vgpu10(hwtnl, range, vcount, ib,
1027 start_instance, instance_count);
1028 if (ret != PIPE_OK) {
1029 svga_context_flush(hwtnl->svga, NULL);
1030 ret = draw_vgpu10(hwtnl, range, vcount, ib,
1031 start_instance, instance_count);
1032 assert(ret == PIPE_OK);
1033 }
1034 }
1035 else {
1036 /* batch up drawing commands */
1037 #ifdef DEBUG
1038 check_draw_params(hwtnl, range, min_index, max_index, ib);
1039 assert(start_instance == 0);
1040 assert(instance_count <= 1);
1041 #else
1042 (void) check_draw_params;
1043 #endif
1044
1045 if (hwtnl->cmd.prim_count + 1 >= QSZ) {
1046 ret = svga_hwtnl_flush(hwtnl);
1047 if (ret != PIPE_OK)
1048 goto done;
1049 }
1050
1051 /* min/max indices are relative to bias */
1052 hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
1053 hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
1054
1055 hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
1056 hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
1057
1058 pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
1059 hwtnl->cmd.prim_count++;
1060 }
1061
1062 done:
1063 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
1064 return ret;
1065 }