summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i965/brw_pipe_sampler.c
blob: 08a5d220097b93d8fa71a315fcd5e66feb0d3938 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

#include "util/u_memory.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"

#include "brw_context.h"
#include "brw_defines.h"
#include "brw_debug.h"



/* The brw (and related graphics cores) do not support GL_CLAMP.  The
 * Intel drivers for "other operating systems" implement GL_CLAMP as
 * GL_CLAMP_TO_EDGE, so the same is done here.
 */
static GLuint translate_wrap_mode( unsigned wrap )
{
   switch( wrap ) {
   case PIPE_TEX_WRAP_REPEAT: 
      return BRW_TEXCOORDMODE_WRAP;

   case PIPE_TEX_WRAP_CLAMP:
   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
      return BRW_TEXCOORDMODE_CLAMP;
      
   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
      return BRW_TEXCOORDMODE_CLAMP_BORDER;

   case PIPE_TEX_WRAP_MIRROR_REPEAT: 
      return BRW_TEXCOORDMODE_MIRROR;

   case PIPE_TEX_WRAP_MIRROR_CLAMP: 
   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 
   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 
      return BRW_TEXCOORDMODE_MIRROR_ONCE;

   default: 
      return BRW_TEXCOORDMODE_WRAP;
   }
}



static void *brw_create_sampler_state( struct pipe_context *pipe,
				     const struct pipe_sampler_state *templ )
{
   struct brw_sampler_state *sampler = CALLOC_STRUCT(brw_sampler_state);

   switch (key->minfilter) {
   case GL_NEAREST:
      sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
      sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
      break;
   case GL_LINEAR:
      sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
      sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
      break;
   case GL_NEAREST_MIPMAP_NEAREST:
      sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
      sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
      break;
   case GL_LINEAR_MIPMAP_NEAREST:
      sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
      sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
      break;
   case GL_NEAREST_MIPMAP_LINEAR:
      sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
      sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
      break;
   case GL_LINEAR_MIPMAP_LINEAR:
      sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
      sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
      break;
   default:
      break;
   }

   /* Set Anisotropy: 
    */
   if (key->max_aniso > 1.0) {
      sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; 
      sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;

      if (key->max_aniso > 2.0) {
	 sampler->ss3.max_aniso = MIN2((key->max_aniso - 2) / 2,
				       BRW_ANISORATIO_16);
      }
   }
   else {
      switch (key->magfilter) {
      case GL_NEAREST:
	 sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
	 break;
      case GL_LINEAR:
	 sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
	 break;
      default:
	 break;
      }
   }

   sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
   sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
   sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);

   /* Set LOD bias: 
    */
   sampler->ss0.lod_bias = S_FIXED(CLAMP(key->lod_bias, -16, 15), 6);

   sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
   sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */

   /* Set shadow function: 
    */
   if (key->comparemode == GL_COMPARE_R_TO_TEXTURE_ARB) {
      /* Shadowing is "enabled" by emitting a particular sampler
       * message (sample_c).  So need to recompile WM program when
       * shadow comparison is enabled on each/any texture unit.
       */
      sampler->ss0.shadow_function =
	 intel_translate_shadow_compare_func(key->comparefunc);
   }

   /* Set BaseMipLevel, MaxLOD, MinLOD: 
    */
   sampler->ss0.base_level = U_FIXED(0, 1);

   sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(key->maxlod, 0), 13), 6);
   sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(key->minlod, 0), 13), 6);

   return (void *)sampler;
}

static void brw_bind_sampler_state(struct pipe_context *pipe,
				 void *cso)
{
   struct brw_context *brw = brw_context(pipe);
   brw->curr.sampler = (const struct brw_sampler_state *)cso;
   brw->state.dirty.mesa |= PIPE_NEW_SAMPLER;
}

static void brw_delete_sampler_state(struct pipe_context *pipe,
				  void *cso)
{
   struct brw_context *brw = brw_context(pipe);
   FREE(cso);
}

static void brw_set_sampler_textures(struct pipe_context *pipe,
				     unsigned num_textures,
				     struct pipe_texture **tex)
{
   struct brw_context *brw = brw_context(pipe);

   brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;
}


void brw_sampler_init( struct brw_context *brw )
{
   brw->base.set_sampler_textures = brw_set_sampler_textures;
   brw->base.create_sampler_state = brw_create_sampler_state;
   brw->base.bind_sampler_state = brw_bind_sampler_state;
   brw->base.destroy_sampler_state = brw_destroy_sampler_state;
}