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 "util/u_inlines.h"
27
#include "pipe/p_state.h"
28
#include "svga_context.h"
29
#include "svga_shader.h"
30
#include "svga_state.h"
31
#include "svga_debug.h"
32
#include "svga_hw_reg.h"
35
static enum pipe_error
36
update_need_swvfetch(struct svga_context *svga, uint64_t dirty)
38
if (!svga->curr.velems) {
39
/* No vertex elements bound. */
43
if (svga->state.sw.need_swvfetch != svga->curr.velems->need_swvfetch) {
44
svga->state.sw.need_swvfetch = svga->curr.velems->need_swvfetch;
45
svga->dirty |= SVGA_NEW_NEED_SWVFETCH;
51
struct svga_tracked_state svga_update_need_swvfetch =
53
"update need_swvfetch",
54
( SVGA_NEW_VELEMENT ),
60
static enum pipe_error
61
update_need_pipeline(struct svga_context *svga, uint64_t dirty)
63
boolean need_pipeline = FALSE;
64
struct svga_vertex_shader *vs = svga->curr.vs;
65
const char *reason = "";
67
/* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
69
if (svga->curr.rast &&
70
(svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim))) {
71
SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (0x%x) & prim (0x%x)\n",
73
svga->curr.rast->need_pipeline,
74
(1 << svga->curr.reduced_prim) );
75
SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline tris (%s), lines (%s), points (%s)\n",
77
svga->curr.rast->need_pipeline_tris_str,
78
svga->curr.rast->need_pipeline_lines_str,
79
svga->curr.rast->need_pipeline_points_str);
82
switch (svga->curr.reduced_prim) {
83
case PIPE_PRIM_POINTS:
84
reason = svga->curr.rast->need_pipeline_points_str;
87
reason = svga->curr.rast->need_pipeline_lines_str;
89
case PIPE_PRIM_TRIANGLES:
90
reason = svga->curr.rast->need_pipeline_tris_str;
93
assert(!"Unexpected reduced prim type");
99
if (vs && vs->base.info.writes_edgeflag) {
100
SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__);
101
need_pipeline = TRUE;
102
reason = "edge flags";
105
/* SVGA_NEW_FS, SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
107
if (svga->curr.rast && svga->curr.reduced_prim == PIPE_PRIM_POINTS) {
108
unsigned sprite_coord_gen = svga->curr.rast->templ.sprite_coord_enable;
109
unsigned generic_inputs =
110
svga->curr.fs ? svga->curr.fs->generic_inputs : 0;
112
if (!svga_have_vgpu10(svga) && sprite_coord_gen &&
113
(generic_inputs & ~sprite_coord_gen)) {
114
/* The fragment shader is using some generic inputs that are
115
* not being replaced by auto-generated point/sprite coords (and
116
* auto sprite coord generation is turned on).
117
* The SVGA3D interface does not support that: if we enable
118
* SVGA3D_RS_POINTSPRITEENABLE it gets enabled for _all_
119
* texture coordinate sets.
120
* To solve this, we have to use the draw-module's wide/sprite
123
need_pipeline = TRUE;
124
reason = "point sprite coordinate generation";
128
if (need_pipeline != svga->state.sw.need_pipeline) {
129
svga->state.sw.need_pipeline = need_pipeline;
130
svga->dirty |= SVGA_NEW_NEED_PIPELINE;
134
if (0 && svga->state.sw.need_pipeline)
135
debug_printf("sw.need_pipeline = %d\n", svga->state.sw.need_pipeline);
137
if (svga->state.sw.need_pipeline) {
139
util_debug_message(&svga->debug.callback, FALLBACK,
140
"Using semi-fallback for %s", reason);
147
struct svga_tracked_state svga_update_need_pipeline =
153
SVGA_NEW_REDUCED_PRIMITIVE),
158
static enum pipe_error
159
update_need_swtnl(struct svga_context *svga, uint64_t dirty)
163
if (svga->debug.no_swtnl) {
164
svga->state.sw.need_swvfetch = FALSE;
165
svga->state.sw.need_pipeline = FALSE;
168
need_swtnl = (svga->state.sw.need_swvfetch ||
169
svga->state.sw.need_pipeline);
171
if (svga->debug.force_swtnl) {
176
* Some state changes the draw module does makes us believe we
177
* we don't need swtnl. This causes the vdecl code to pickup
178
* the wrong buffers and vertex formats. Try trivial/line-wide.
180
if (svga->state.sw.in_swtnl_draw)
183
if (need_swtnl != svga->state.sw.need_swtnl) {
184
SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF,
185
"%s: need_swvfetch %s, need_pipeline %s\n",
187
svga->state.sw.need_swvfetch ? "true" : "false",
188
svga->state.sw.need_pipeline ? "true" : "false");
190
svga->state.sw.need_swtnl = need_swtnl;
191
svga->dirty |= SVGA_NEW_NEED_SWTNL;
192
svga->swtnl.new_vdecl = TRUE;
199
struct svga_tracked_state svga_update_need_swtnl =
202
(SVGA_NEW_NEED_PIPELINE |
203
SVGA_NEW_NEED_SWVFETCH),