1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
24 **********************************************************/
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"
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"
49 svga_hwtnl_create(struct svga_context
*svga
)
51 struct svga_hwtnl
*hwtnl
= CALLOC_STRUCT(svga_hwtnl
);
57 hwtnl
->cmd
.swc
= svga
->swc
;
67 svga_hwtnl_destroy(struct svga_hwtnl
*hwtnl
)
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
);
77 for (i
= 0; i
< hwtnl
->cmd
.vbuf_count
; i
++)
78 pipe_vertex_buffer_unreference(&hwtnl
->cmd
.vbufs
[i
]);
80 for (i
= 0; i
< hwtnl
->cmd
.prim_count
; i
++)
81 pipe_resource_reference(&hwtnl
->cmd
.prim_ib
[i
], NULL
);
88 svga_hwtnl_set_flatshade(struct svga_hwtnl
*hwtnl
,
89 boolean flatshade
, boolean flatshade_first
)
91 struct svga_screen
*svgascreen
= svga_screen(hwtnl
->svga
->pipe
.screen
);
93 /* User-specified PV */
94 hwtnl
->api_pv
= (flatshade
&& !flatshade_first
) ? PV_LAST
: PV_FIRST
;
96 /* Device supported PV */
97 if (svgascreen
->haveProvokingVertex
) {
98 /* use the mode specified by the user */
99 hwtnl
->hw_pv
= hwtnl
->api_pv
;
102 /* the device only support first provoking vertex */
103 hwtnl
->hw_pv
= PV_FIRST
;
109 svga_hwtnl_set_fillmode(struct svga_hwtnl
*hwtnl
, unsigned mode
)
111 hwtnl
->api_fillmode
= mode
;
116 svga_hwtnl_vertex_decls(struct svga_hwtnl
*hwtnl
,
118 const SVGA3dVertexDecl
* decls
,
119 const unsigned *buffer_indexes
,
120 SVGA3dElementLayoutId layout_id
)
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));
132 * Specify vertex buffers for hardware drawing.
135 svga_hwtnl_vertex_buffers(struct svga_hwtnl
*hwtnl
,
136 unsigned count
, struct pipe_vertex_buffer
*buffers
)
138 struct pipe_vertex_buffer
*dst
= hwtnl
->cmd
.vbufs
;
139 const struct pipe_vertex_buffer
*src
= buffers
;
142 for (i
= 0; i
< count
; i
++) {
143 pipe_vertex_buffer_reference(&dst
[i
], &src
[i
]);
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 */
152 hwtnl
->cmd
.vbuf_count
= count
;
157 * Determine whether the specified buffer is referred in the primitive queue,
158 * for which no commands have been written yet.
161 svga_hwtnl_is_buffer_referred(struct svga_hwtnl
*hwtnl
,
162 struct pipe_resource
*buffer
)
166 if (svga_buffer_is_user_buffer(buffer
)) {
170 if (!hwtnl
->cmd
.prim_count
) {
174 for (i
= 0; i
< hwtnl
->cmd
.vbuf_count
; ++i
) {
175 if (hwtnl
->cmd
.vbufs
[i
].buffer
.resource
== buffer
) {
180 for (i
= 0; i
< hwtnl
->cmd
.prim_count
; ++i
) {
181 if (hwtnl
->cmd
.prim_ib
[i
] == buffer
) {
190 static enum pipe_error
191 draw_vgpu9(struct svga_hwtnl
*hwtnl
)
193 struct svga_winsys_context
*swc
= hwtnl
->cmd
.swc
;
194 struct svga_context
*svga
= hwtnl
->svga
;
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
;
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.
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
);
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
);
226 return PIPE_ERROR_OUT_OF_MEMORY
;
228 vb_handle
[i
] = handle
;
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
);
236 return PIPE_ERROR_OUT_OF_MEMORY
;
241 ib_handle
[i
] = handle
;
244 if (svga
->rebind
.flags
.rendertargets
) {
245 ret
= svga_reemit_framebuffer_bindings(svga
);
246 if (ret
!= PIPE_OK
) {
251 if (svga
->rebind
.flags
.texture_samplers
) {
252 ret
= svga_reemit_tss_bindings(svga
);
253 if (ret
!= PIPE_OK
) {
258 if (svga
->rebind
.flags
.vs
) {
259 ret
= svga_reemit_vs_bindings(svga
);
260 if (ret
!= PIPE_OK
) {
265 if (svga
->rebind
.flags
.fs
) {
266 ret
= svga_reemit_fs_bindings(svga
);
267 if (ret
!= PIPE_OK
) {
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
);
277 ret
= SVGA3D_BeginDrawPrimitives(swc
,
279 hwtnl
->cmd
.vdecl_count
,
280 &prim
, hwtnl
->cmd
.prim_count
);
286 hwtnl
->cmd
.vdecl_count
* sizeof hwtnl
->cmd
.vdecl
[0]);
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);
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.
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;
302 vdecl
[i
].rangeHint
.first
= 0;
303 vdecl
[i
].rangeHint
.last
= 0;
306 swc
->surface_relocation(swc
,
307 &vdecl
[i
].array
.surfaceId
,
308 NULL
, vb_handle
[i
], SVGA_RELOC_READ
);
312 hwtnl
->cmd
.prim
, hwtnl
->cmd
.prim_count
* sizeof hwtnl
->cmd
.prim
[0]);
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
);
321 SVGA_FIFOCommitAll(swc
);
323 hwtnl
->cmd
.prim_count
= 0;
329 static SVGA3dSurfaceFormat
330 xlate_index_format(unsigned indexWidth
)
332 if (indexWidth
== 2) {
333 return SVGA3D_R16_UINT
;
335 else if (indexWidth
== 4) {
336 return SVGA3D_R32_UINT
;
339 assert(!"Bad indexWidth");
340 return SVGA3D_R32_UINT
;
345 static enum pipe_error
346 validate_sampler_resources(struct svga_context
*svga
)
348 enum pipe_shader_type shader
;
350 assert(svga_have_vgpu10(svga
));
352 for (shader
= PIPE_SHADER_VERTEX
; shader
<= PIPE_SHADER_COMPUTE
; shader
++) {
353 unsigned count
= svga
->curr
.num_sampler_views
[shader
];
355 struct svga_winsys_surface
*surfaces
[PIPE_MAX_SAMPLERS
];
359 * Reference bound sampler resources to ensure pending updates are
360 * noticed by the device.
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
]);
367 if (sv
->base
.texture
->target
== PIPE_BUFFER
) {
368 surfaces
[i
] = svga_buffer_handle(svga
, sv
->base
.texture
,
369 PIPE_BIND_SAMPLER_VIEW
);
372 surfaces
[i
] = svga_texture(sv
->base
.texture
)->handle
;
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
;
388 surfaces
[unit
] = svga_texture(sv
->base
.texture
)->handle
;
389 count
= MAX2(count
, unit
+1);
392 /* rebind the shader resources if needed */
393 if (svga
->rebind
.flags
.texture_samplers
) {
394 for (i
= 0; i
< count
; i
++) {
396 ret
= svga
->swc
->resource_rebind(svga
->swc
,
406 svga
->rebind
.flags
.texture_samplers
= FALSE
;
412 static enum pipe_error
413 validate_constant_buffers(struct svga_context
*svga
)
415 enum pipe_shader_type shader
;
417 assert(svga_have_vgpu10(svga
));
419 for (shader
= PIPE_SHADER_VERTEX
; shader
<= PIPE_SHADER_COMPUTE
; shader
++) {
421 struct svga_buffer
*buffer
;
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]);
427 ret
= svga
->swc
->resource_rebind(svga
->swc
,
436 struct svga_winsys_surface
*handle
;
437 unsigned enabled_constbufs
;
440 * Reference other bound constant buffers to ensure pending updates are
441 * noticed by the device.
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
);
448 /* If the constant buffer has hw storage, get the buffer winsys handle.
449 * Rebind the resource if needed.
451 if (buffer
&& !buffer
->use_swbuf
)
452 handle
= svga_buffer_handle(svga
, &buffer
->b
.b
,
453 PIPE_BIND_CONSTANT_BUFFER
);
455 handle
= svga
->state
.hw_draw
.constbufoffsets
[shader
][i
].handle
;
457 if (svga
->rebind
.flags
.constbufs
&& handle
) {
458 ret
= svga
->swc
->resource_rebind(svga
->swc
,
467 svga
->rebind
.flags
.constbufs
= FALSE
;
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.
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.
484 last_command_was_draw(const struct svga_context
*svga
)
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
:
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.
507 vertex_buffers_equal(unsigned count
,
508 SVGA3dVertexBuffer
*pVBufAttr1
,
509 struct pipe_resource
**pVBuf1
,
510 SVGA3dVertexBuffer
*pVBufAttr2
,
511 struct pipe_resource
**pVBuf2
)
513 return (memcmp(pVBufAttr1
, pVBufAttr2
,
514 count
* sizeof(*pVBufAttr1
)) == 0) &&
515 (memcmp(pVBuf1
, pVBuf2
, count
* sizeof(*pVBuf1
)) == 0);
520 * Prepare the vertex buffers for a drawing command.
522 static enum pipe_error
523 validate_vertex_buffers(struct svga_hwtnl
*hwtnl
,
524 const struct pipe_stream_output_target
*so_vertex_count
)
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
;
534 assert(svga_have_vgpu10(svga
));
536 /* Get handle for each referenced vertex buffer, unless we're using a
537 * stream-out buffer to specify the drawing information (DrawAuto).
539 if (so_vertex_count
) {
543 for (i
= 0; i
< vbuf_count
; i
++) {
544 struct svga_buffer
*sbuf
=
545 svga_buffer(hwtnl
->cmd
.vbufs
[i
].buffer
.resource
);
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
;
558 vbuffer_handles
[i
] = NULL
;
563 for (; i
< svga
->state
.hw_draw
.num_vbuffers
; i
++) {
565 vbuffer_handles
[i
] = NULL
;
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
);
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
;
584 vbuffer_handles
[i
] = NULL
;
588 for (; i
< svga
->state
.hw_draw
.num_vbuffers
; i
++) {
590 vbuffer_handles
[i
] = NULL
;
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
);
601 svga
->state
.hw_draw
.layout_id
= hwtnl
->cmd
.vdecl_layout_id
;
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
;
614 so_vertex_count_handle
= NULL
;
617 /* setup vertex buffers */
619 SVGA3dVertexBuffer vbuffer_attrs
[PIPE_MAX_ATTRIBS
];
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
;
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;
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.
642 if (vbuf_count
!= svga
->state
.hw_draw
.num_vbuffers
||
643 !vertex_buffers_equal(vbuf_count
,
646 svga
->state
.hw_draw
.vbuffer_attrs
,
647 svga
->state
.hw_draw
.vbuffers
)) {
649 unsigned num_vbuffers
;
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.
655 num_vbuffers
= MAX2(vbuf_count
, svga
->state
.hw_draw
.num_vbuffers
);
657 /* Zero-out the old buffers we want to unbind (the number of loop
658 * iterations here is typically very small, and often zero.)
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
;
667 if (num_vbuffers
> 0) {
668 SVGA3dVertexBuffer
*pbufAttrs
= vbuffer_attrs
;
669 struct svga_winsys_surface
**pbufHandles
= vbuffer_handles
;
670 unsigned numVBuf
= 0;
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.
676 for (i
= 0; i
< num_vbuffers
; i
++) {
678 vertex_buffers_equal(1,
681 &svga
->state
.hw_draw
.vbuffer_attrs
[i
],
682 &svga
->state
.hw_draw
.vbuffers
[i
]);
684 if (!emit
&& i
== num_vbuffers
-1) {
685 /* Include the last vertex buffer in the next emit
686 * if it is different.
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.
699 enum pipe_error ret
=
700 SVGA3D_vgpu10_SetVertexBuffers(svga
->swc
,
703 pbufAttrs
, pbufHandles
);
707 pbufAttrs
+= (numVBuf
+ 1);
708 pbufHandles
+= (numVBuf
+ 1);
715 /* save the number of vertex buffers sent to the device, not
716 * including trailing unbound vertex buffers.
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
],
728 /* Even though we can avoid emitting the redundant SetVertexBuffers
729 * command, we still need to reference the vertex buffers surfaces.
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
);
748 * Prepare the index buffer for a drawing command.
750 static enum pipe_error
751 validate_index_buffer(struct svga_hwtnl
*hwtnl
,
752 const SVGA3dPrimitiveRange
*range
,
753 struct pipe_resource
*ib
)
755 struct svga_context
*svga
= hwtnl
->svga
;
756 struct svga_winsys_surface
*ib_handle
=
757 svga_buffer_handle(svga
, ib
, PIPE_BIND_INDEX_BUFFER
);
760 return PIPE_ERROR_OUT_OF_MEMORY
;
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 */
766 SVGA3dSurfaceFormat indexFormat
= xlate_index_format(range
->indexWidth
);
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
) {
772 assert(indexFormat
!= SVGA3D_FORMAT_INVALID
);
773 enum pipe_error ret
=
774 SVGA3D_vgpu10_SetIndexBuffer(svga
->swc
, ib_handle
,
776 range
->indexArray
.offset
);
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
;
785 /* Even though we can avoid emitting the redundant SetIndexBuffer
786 * command, we still need to reference the index buffer surface.
788 if (!last_command_was_draw(svga
)) {
789 enum pipe_error ret
= svga
->swc
->resource_rebind(svga
->swc
,
802 static enum pipe_error
803 draw_vgpu10(struct svga_hwtnl
*hwtnl
,
804 const SVGA3dPrimitiveRange
*range
,
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
)
812 struct svga_context
*svga
= hwtnl
->svga
;
813 struct svga_winsys_surface
*indirect_handle
;
816 assert(svga_have_vgpu10(svga
));
817 assert(hwtnl
->cmd
.prim_count
== 0);
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
824 if (svga
->rebind
.val
) {
825 ret
= svga_rebind_framebuffer_bindings(svga
);
829 ret
= svga_rebind_shaders(svga
);
833 /* Rebind stream output targets */
834 ret
= svga_rebind_stream_output_targets(svga
);
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.
845 ret
= validate_sampler_resources(svga
);
849 ret
= validate_constant_buffers(svga
);
853 ret
= validate_vertex_buffers(hwtnl
, so_vertex_count
);
858 ret
= validate_index_buffer(hwtnl
, range
, ib
);
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
;
870 indirect_handle
= NULL
;
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
);
879 svga
->state
.hw_draw
.topology
= range
->primType
;
883 /* indexed drawing */
885 ret
= SVGA3D_sm5_DrawIndexedInstancedIndirect(svga
->swc
,
889 else if (instance_count
> 1) {
890 ret
= SVGA3D_vgpu10_DrawIndexedInstanced(svga
->swc
,
893 0, /* startIndexLocation */
898 /* non-instanced drawing */
899 ret
= SVGA3D_vgpu10_DrawIndexed(svga
->swc
,
901 0, /* startIndexLocation */
904 if (ret
!= PIPE_OK
) {
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);
917 pipe_resource_reference(&svga
->state
.hw_draw
.ib
, NULL
);
918 svga
->state
.hw_draw
.ib_format
= SVGA3D_FORMAT_INVALID
;
921 assert(svga
->state
.hw_draw
.ib
== NULL
);
923 if (so_vertex_count
) {
924 /* Stream-output drawing */
925 ret
= SVGA3D_vgpu10_DrawAuto(svga
->swc
);
928 ret
= SVGA3D_sm5_DrawInstancedIndirect(svga
->swc
,
932 else if (instance_count
> 1) {
933 ret
= SVGA3D_vgpu10_DrawInstanced(svga
->swc
,
941 ret
= SVGA3D_vgpu10_Draw(svga
->swc
,
945 if (ret
!= PIPE_OK
) {
950 hwtnl
->cmd
.prim_count
= 0;
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.
965 svga_hwtnl_flush(struct svga_hwtnl
*hwtnl
)
967 enum pipe_error ret
= PIPE_OK
;
969 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl
->svga
), SVGA_STATS_TIME_HWTNLFLUSH
);
971 if (!svga_have_vgpu10(hwtnl
->svga
) && hwtnl
->cmd
.prim_count
) {
972 /* we only queue up primitive for VGPU9 */
973 ret
= draw_vgpu9(hwtnl
);
976 SVGA_STATS_TIME_POP(svga_screen(hwtnl
->svga
->pipe
.screen
)->sws
);
982 svga_hwtnl_set_index_bias(struct svga_hwtnl
*hwtnl
, int index_bias
)
984 hwtnl
->index_bias
= index_bias
;
989 /***********************************************************************
990 * Internal functions:
994 * For debugging only.
997 check_draw_params(struct svga_hwtnl
*hwtnl
,
998 const SVGA3dPrimitiveRange
*range
,
999 unsigned min_index
, unsigned max_index
,
1000 struct pipe_resource
*ib
)
1004 assert(!svga_have_vgpu10(hwtnl
->svga
));
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
;
1020 assert(offset
< size
);
1021 assert(min_index
<= max_index
);
1027 switch (hwtnl
->cmd
.vdecl
[i
].identity
.type
) {
1028 case SVGA3D_DECLTYPE_FLOAT1
:
1031 case SVGA3D_DECLTYPE_FLOAT2
:
1034 case SVGA3D_DECLTYPE_FLOAT3
:
1037 case SVGA3D_DECLTYPE_FLOAT4
:
1040 case SVGA3D_DECLTYPE_D3DCOLOR
:
1043 case SVGA3D_DECLTYPE_UBYTE4
:
1046 case SVGA3D_DECLTYPE_SHORT2
:
1049 case SVGA3D_DECLTYPE_SHORT4
:
1052 case SVGA3D_DECLTYPE_UBYTE4N
:
1055 case SVGA3D_DECLTYPE_SHORT2N
:
1058 case SVGA3D_DECLTYPE_SHORT4N
:
1061 case SVGA3D_DECLTYPE_USHORT2N
:
1064 case SVGA3D_DECLTYPE_USHORT4N
:
1067 case SVGA3D_DECLTYPE_UDEC3
:
1070 case SVGA3D_DECLTYPE_DEC3N
:
1073 case SVGA3D_DECLTYPE_FLOAT16_2
:
1076 case SVGA3D_DECLTYPE_FLOAT16_4
:
1085 if (index_bias
>= 0) {
1086 assert(offset
+ index_bias
* stride
+ width
<= size
);
1090 * min_index/max_index are merely conservative guesses, so we can't
1091 * make buffer overflow detection based on their values.
1095 assert(range
->indexWidth
== range
->indexArray
.stride
);
1098 ASSERTED
unsigned size
= ib
->width0
;
1099 ASSERTED
unsigned offset
= range
->indexArray
.offset
;
1100 ASSERTED
unsigned stride
= range
->indexArray
.stride
;
1101 ASSERTED
unsigned count
;
1104 assert(offset
< size
);
1107 switch (range
->primType
) {
1108 case SVGA3D_PRIMITIVE_POINTLIST
:
1109 count
= range
->primitiveCount
;
1111 case SVGA3D_PRIMITIVE_LINELIST
:
1112 count
= range
->primitiveCount
* 2;
1114 case SVGA3D_PRIMITIVE_LINESTRIP
:
1115 count
= range
->primitiveCount
+ 1;
1117 case SVGA3D_PRIMITIVE_TRIANGLELIST
:
1118 count
= range
->primitiveCount
* 3;
1120 case SVGA3D_PRIMITIVE_TRIANGLESTRIP
:
1121 count
= range
->primitiveCount
+ 2;
1123 case SVGA3D_PRIMITIVE_TRIANGLEFAN
:
1124 count
= range
->primitiveCount
+ 2;
1132 assert(offset
+ count
* stride
<= size
);
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.
1142 * \param so_vertex_count if non-null, get the vertex count from a
1143 * stream-output target.
1146 svga_hwtnl_prim(struct svga_hwtnl
*hwtnl
,
1147 const SVGA3dPrimitiveRange
*range
,
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
)
1155 enum pipe_error ret
= PIPE_OK
;
1157 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl
->svga
), SVGA_STATS_TIME_HWTNLPRIM
);
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
,
1167 /* batch up drawing commands */
1168 assert(indirect
== NULL
);
1170 check_draw_params(hwtnl
, range
, min_index
, max_index
, ib
);
1171 assert(start_instance
== 0);
1172 assert(instance_count
<= 1);
1174 (void) check_draw_params
;
1177 if (hwtnl
->cmd
.prim_count
+ 1 >= QSZ
) {
1178 ret
= svga_hwtnl_flush(hwtnl
);
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
;
1187 hwtnl
->cmd
.prim
[hwtnl
->cmd
.prim_count
] = *range
;
1188 hwtnl
->cmd
.prim
[hwtnl
->cmd
.prim_count
].indexBias
+= hwtnl
->index_bias
;
1190 pipe_resource_reference(&hwtnl
->cmd
.prim_ib
[hwtnl
->cmd
.prim_count
], ib
);
1191 hwtnl
->cmd
.prim_count
++;
1195 SVGA_STATS_TIME_POP(svga_screen(hwtnl
->svga
->pipe
.screen
)->sws
);
1201 * Return TRUE if there are pending primitives.
1204 svga_hwtnl_has_pending_prim(struct svga_hwtnl
*hwtnl
)
1206 return hwtnl
->cmd
.prim_count
> 0;