xref: /third_party/mesa3d/src/mesa/main/samplerobj.h (revision bf215546)
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
33extern "C" {
34#endif
35
36struct dd_function_table;
37
38static inline struct gl_sampler_object *
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? */
51static inline GLboolean
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
58extern void
59_mesa_reference_sampler_object_(struct gl_context *ctx,
60                                struct gl_sampler_object **ptr,
61                                struct gl_sampler_object *samp);
62
63static inline void
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
72extern struct gl_sampler_object *
73_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name);
74
75extern void
76_mesa_bind_sampler(struct gl_context *ctx, GLuint unit,
77                   struct gl_sampler_object *sampObj);
78
79extern const enum pipe_tex_wrap wrap_to_gallium_table[32];
80
81/**
82 * Convert GLenum texcoord wrap tokens to pipe tokens.
83 */
84static inline enum pipe_tex_wrap
85wrap_to_gallium(GLenum wrap)
86{
87   return wrap_to_gallium_table[wrap & 0x1f];
88}
89
90
91static inline enum pipe_tex_mipfilter
92mipfilter_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
104static inline enum pipe_tex_filter
105filter_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
114static inline enum pipe_tex_reduction_mode
115reduction_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 */
131static inline enum pipe_compare_func
132func_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
148static inline void
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
157static inline enum pipe_tex_wrap
158lower_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
169static inline void
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
186static inline GLboolean
187is_wrap_gl_clamp(GLint param)
188{
189   return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT;
190}
191
192static inline void
193update_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