1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2011 VMware, Inc. All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26
27 #ifndef SAMPLEROBJ_H
28 #define SAMPLEROBJ_H
29
30 #include "mtypes.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 struct dd_function_table;
37
38 static inline struct gl_sampler_object *
_mesa_get_samplerobj(struct gl_context * ctx,GLuint unit)39 _mesa_get_samplerobj(struct gl_context *ctx, GLuint unit)
40 {
41 if (ctx->Texture.Unit[unit].Sampler)
42 return ctx->Texture.Unit[unit].Sampler;
43 else if (ctx->Texture.Unit[unit]._Current)
44 return &ctx->Texture.Unit[unit]._Current->Sampler;
45 else
46 return NULL;
47 }
48
49
50 /** Does the given filter state do mipmap filtering? */
51 static inline GLboolean
_mesa_is_mipmap_filter(const struct gl_sampler_object * samp)52 _mesa_is_mipmap_filter(const struct gl_sampler_object *samp)
53 {
54 return samp->Attrib.MinFilter != GL_NEAREST && samp->Attrib.MinFilter != GL_LINEAR;
55 }
56
57
58 extern void
59 _mesa_reference_sampler_object_(struct gl_context *ctx,
60 struct gl_sampler_object **ptr,
61 struct gl_sampler_object *samp);
62
63 static inline void
_mesa_reference_sampler_object(struct gl_context * ctx,struct gl_sampler_object ** ptr,struct gl_sampler_object * samp)64 _mesa_reference_sampler_object(struct gl_context *ctx,
65 struct gl_sampler_object **ptr,
66 struct gl_sampler_object *samp)
67 {
68 if (*ptr != samp)
69 _mesa_reference_sampler_object_(ctx, ptr, samp);
70 }
71
72 extern struct gl_sampler_object *
73 _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name);
74
75 extern void
76 _mesa_bind_sampler(struct gl_context *ctx, GLuint unit,
77 struct gl_sampler_object *sampObj);
78
79 extern const enum pipe_tex_wrap wrap_to_gallium_table[32];
80
81 /**
82 * Convert GLenum texcoord wrap tokens to pipe tokens.
83 */
84 static inline enum pipe_tex_wrap
wrap_to_gallium(GLenum wrap)85 wrap_to_gallium(GLenum wrap)
86 {
87 return wrap_to_gallium_table[wrap & 0x1f];
88 }
89
90
91 static inline enum pipe_tex_mipfilter
mipfilter_to_gallium(GLenum filter)92 mipfilter_to_gallium(GLenum filter)
93 {
94 /* Take advantage of how the enums are defined. */
95 if (filter <= GL_LINEAR)
96 return PIPE_TEX_MIPFILTER_NONE;
97 if (filter <= GL_LINEAR_MIPMAP_NEAREST)
98 return PIPE_TEX_MIPFILTER_NEAREST;
99
100 return PIPE_TEX_MIPFILTER_LINEAR;
101 }
102
103
104 static inline enum pipe_tex_filter
filter_to_gallium(GLenum filter)105 filter_to_gallium(GLenum filter)
106 {
107 /* Take advantage of how the enums are defined. */
108 if (filter & 1)
109 return PIPE_TEX_FILTER_LINEAR;
110
111 return PIPE_TEX_FILTER_NEAREST;
112 }
113
114 static inline enum pipe_tex_reduction_mode
reduction_to_gallium(GLenum reduction_mode)115 reduction_to_gallium(GLenum reduction_mode)
116 {
117 switch (reduction_mode) {
118 case GL_MIN:
119 return PIPE_TEX_REDUCTION_MIN;
120 case GL_MAX:
121 return PIPE_TEX_REDUCTION_MAX;
122 case GL_WEIGHTED_AVERAGE_EXT:
123 default:
124 return PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE;
125 }
126 }
127
128 /**
129 * Convert an OpenGL compare mode to a pipe tokens.
130 */
131 static inline enum pipe_compare_func
func_to_gallium(GLenum func)132 func_to_gallium(GLenum func)
133 {
134 /* Same values, just biased */
135 STATIC_ASSERT(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER);
136 STATIC_ASSERT(PIPE_FUNC_LESS == GL_LESS - GL_NEVER);
137 STATIC_ASSERT(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER);
138 STATIC_ASSERT(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER);
139 STATIC_ASSERT(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER);
140 STATIC_ASSERT(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER);
141 STATIC_ASSERT(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER);
142 STATIC_ASSERT(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER);
143 assert(func >= GL_NEVER);
144 assert(func <= GL_ALWAYS);
145 return (enum pipe_compare_func)(func - GL_NEVER);
146 }
147
148 static inline void
_mesa_update_is_border_color_nonzero(struct gl_sampler_object * samp)149 _mesa_update_is_border_color_nonzero(struct gl_sampler_object *samp)
150 {
151 samp->Attrib.IsBorderColorNonZero = samp->Attrib.state.border_color.ui[0] ||
152 samp->Attrib.state.border_color.ui[1] ||
153 samp->Attrib.state.border_color.ui[2] ||
154 samp->Attrib.state.border_color.ui[3];
155 }
156
157 static inline enum pipe_tex_wrap
lower_gl_clamp(enum pipe_tex_wrap old_wrap,GLenum wrap,bool clamp_to_border)158 lower_gl_clamp(enum pipe_tex_wrap old_wrap, GLenum wrap, bool clamp_to_border)
159 {
160 if (wrap == GL_CLAMP)
161 return clamp_to_border ? PIPE_TEX_WRAP_CLAMP_TO_BORDER :
162 PIPE_TEX_WRAP_CLAMP_TO_EDGE;
163 else if (wrap == GL_MIRROR_CLAMP_EXT)
164 return clamp_to_border ? PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER :
165 PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
166 return old_wrap;
167 }
168
169 static inline void
_mesa_lower_gl_clamp(struct gl_context * ctx,struct gl_sampler_object * samp)170 _mesa_lower_gl_clamp(struct gl_context *ctx, struct gl_sampler_object *samp)
171 {
172 if (ctx->DriverFlags.NewSamplersWithClamp) {
173 struct pipe_sampler_state *s = &samp->Attrib.state;
174 bool clamp_to_border = s->min_img_filter != PIPE_TEX_FILTER_NEAREST &&
175 s->mag_img_filter != PIPE_TEX_FILTER_NEAREST;
176
177 s->wrap_s = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_s,
178 samp->Attrib.WrapS, clamp_to_border);
179 s->wrap_t = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_t,
180 samp->Attrib.WrapT, clamp_to_border);
181 s->wrap_r = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_r,
182 samp->Attrib.WrapR, clamp_to_border);
183 }
184 }
185
186 static inline GLboolean
is_wrap_gl_clamp(GLint param)187 is_wrap_gl_clamp(GLint param)
188 {
189 return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT;
190 }
191
192 static inline void
update_sampler_gl_clamp(struct gl_context * ctx,struct gl_sampler_object * samp,bool cur_state,bool new_state,gl_sampler_wrap wrap)193 update_sampler_gl_clamp(struct gl_context *ctx, struct gl_sampler_object *samp, bool cur_state, bool new_state, gl_sampler_wrap wrap)
194 {
195 if (cur_state == new_state)
196 return;
197 ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp;
198 if (new_state)
199 samp->glclamp_mask |= wrap;
200 else
201 samp->glclamp_mask &= ~wrap;
202 }
203 #ifdef __cplusplus
204 }
205 #endif
206
207 #endif /* SAMPLEROBJ_H */
208