summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i965/brw_swtnl.c
blob: d2df8af9f40889b1a8fb2b899bc02bc8a9b0238d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

/* XXX: could split the primitive list to fallback only on the
 * non-conformant primitives.
 */
static GLboolean check_fallbacks( struct brw_context *brw,
				  const struct _mesa_prim *prim,
				  GLuint nr_prims )
{
   GLuint i;

   /* If we don't require strict OpenGL conformance, never 
    * use fallbacks.  If we're forcing fallbacks, always
    * use fallfacks.
    */
   if (brw->flags.no_swtnl)
      return GL_FALSE;

   if (brw->flags.force_swtnl)
      return GL_TRUE;

   if (brw->curr.rast->tmpl.smooth_polys) {
      for (i = 0; i < nr_prims; i++)
	 if (reduced_prim[prim[i].mode] == GL_TRIANGLES) 
	    return GL_TRUE;
   }

   /* BRW hardware will do AA lines, but they are non-conformant it
    * seems.  TBD whether we keep this fallback:
    */
   if (ctx->Line.SmoothFlag) {
      for (i = 0; i < nr_prims; i++)
	 if (reduced_prim[prim[i].mode] == GL_LINES) 
	    return GL_TRUE;
   }

   /* Stipple -- these fallbacks could be resolved with a little
    * bit of work?
    */
   if (ctx->Line.StippleFlag) {
      for (i = 0; i < nr_prims; i++) {
	 /* GS doesn't get enough information to know when to reset
	  * the stipple counter?!?
	  */
	 if (prim[i].mode == GL_LINE_LOOP || prim[i].mode == GL_LINE_STRIP) 
	    return GL_TRUE;
	    
	 if (prim[i].mode == GL_POLYGON &&
	     (ctx->Polygon.FrontMode == GL_LINE ||
	      ctx->Polygon.BackMode == GL_LINE))
	    return GL_TRUE;
      }
   }

   if (ctx->Point.SmoothFlag) {
      for (i = 0; i < nr_prims; i++)
	 if (prim[i].mode == GL_POINTS) 
	    return GL_TRUE;
   }

   /* BRW hardware doesn't handle GL_CLAMP texturing correctly;
    * brw_wm_sampler_state:translate_wrap_mode() treats GL_CLAMP
    * as GL_CLAMP_TO_EDGE instead.  If we're using GL_CLAMP, and
    * we want strict conformance, force the fallback.
    * Right now, we only do this for 2D textures.
    */
   {
      int u;
      for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
         struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
         if (texUnit->Enabled) {
            if (texUnit->Enabled & TEXTURE_1D_BIT) {
               if (texUnit->CurrentTex[TEXTURE_1D_INDEX]->WrapS == GL_CLAMP) {
                   return GL_TRUE;
               }
            }
            if (texUnit->Enabled & TEXTURE_2D_BIT) {
               if (texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapS == GL_CLAMP ||
                   texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapT == GL_CLAMP) {
                   return GL_TRUE;
               }
            }
            if (texUnit->Enabled & TEXTURE_3D_BIT) {
               if (texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapS == GL_CLAMP ||
                   texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapT == GL_CLAMP ||
                   texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapR == GL_CLAMP) {
                   return GL_TRUE;
               }
            }
         }
      }
   }

   /* Exceeding hw limits on number of VS inputs?
    */
   if (brw->nr_ve == 0 ||
       brw->nr_ve >= BRW_VEP_MAX) {
      return TRUE;
   }

   /* Position array with zero stride?
    */
   if (brw->vs[brw->ve[0]]->stride == 0)
      return TRUE;


      
   /* Nothing stopping us from the fast path now */
   return GL_FALSE;
}