• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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