summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i965/brw_pipe_sampler.c
blob: bc20eef6fb280a0e3ea8dfe03e7e7d6dc5d59302 (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

#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"



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;
}