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