~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/mesa/state_tracker/st_atom_sampler.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 * 
3
 
 * Copyright 2007 VMware, Inc.
4
 
 * 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
8
 
 * "Software"), to deal in the Software without restriction, including
9
 
 * without limitation the rights to use, copy, modify, merge, publish,
10
 
 * distribute, sub license, and/or sell copies of the Software, and to
11
 
 * permit persons to whom the Software is furnished to do so, subject to
12
 
 * the following conditions:
13
 
 * 
14
 
 * The above copyright notice and this permission notice (including the
15
 
 * next paragraph) shall be included in all copies or substantial portions
16
 
 * of the Software.
17
 
 * 
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
 * 
26
 
 **************************************************************************/
27
 
 
28
 
 /*
29
 
  * Authors:
30
 
  *   Keith Whitwell <keithw@vmware.com>
31
 
  *   Brian Paul
32
 
  */
33
 
 
34
 
 
35
 
#include "main/macros.h"
36
 
#include "main/glformats.h"
37
 
#include "main/samplerobj.h"
38
 
#include "main/teximage.h"
39
 
#include "main/texobj.h"
40
 
 
41
 
#include "st_context.h"
42
 
#include "st_cb_texture.h"
43
 
#include "st_format.h"
44
 
#include "st_atom.h"
45
 
#include "st_sampler_view.h"
46
 
#include "st_texture.h"
47
 
#include "pipe/p_context.h"
48
 
#include "pipe/p_defines.h"
49
 
 
50
 
#include "cso_cache/cso_context.h"
51
 
 
52
 
#include "util/format/u_format.h"
53
 
 
54
 
 
55
 
/**
56
 
 * Convert a gl_sampler_object to a pipe_sampler_state object.
57
 
 */
58
 
void
59
 
st_convert_sampler(const struct st_context *st,
60
 
                   const struct gl_texture_object *texobj,
61
 
                   const struct gl_sampler_object *msamp,
62
 
                   float tex_unit_lod_bias,
63
 
                   struct pipe_sampler_state *sampler,
64
 
                   bool seamless_cube_map)
65
 
{
66
 
   memcpy(sampler, &msamp->Attrib.state, sizeof(*sampler));
67
 
 
68
 
   sampler->seamless_cube_map |= seamless_cube_map;
69
 
 
70
 
   if (texobj->_IsIntegerFormat && st->ctx->Const.ForceIntegerTexNearest) {
71
 
      sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
72
 
      sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
73
 
   }
74
 
 
75
 
   if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB || st->lower_rect_tex)
76
 
      sampler->normalized_coords = 1;
77
 
 
78
 
   sampler->lod_bias += tex_unit_lod_bias;
79
 
 
80
 
   /* Check that only wrap modes using the border color have the first bit
81
 
    * set.
82
 
    */
83
 
   STATIC_ASSERT(PIPE_TEX_WRAP_CLAMP & 0x1);
84
 
   STATIC_ASSERT(PIPE_TEX_WRAP_CLAMP_TO_BORDER & 0x1);
85
 
   STATIC_ASSERT(PIPE_TEX_WRAP_MIRROR_CLAMP & 0x1);
86
 
   STATIC_ASSERT(PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER & 0x1);
87
 
   STATIC_ASSERT(((PIPE_TEX_WRAP_REPEAT |
88
 
                   PIPE_TEX_WRAP_CLAMP_TO_EDGE |
89
 
                   PIPE_TEX_WRAP_MIRROR_REPEAT |
90
 
                   PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE) & 0x1) == 0);
91
 
 
92
 
   /* For non-black borders... */
93
 
   if (msamp->Attrib.IsBorderColorNonZero &&
94
 
       /* This is true if wrap modes are using the border color: */
95
 
       (sampler->wrap_s | sampler->wrap_t | sampler->wrap_r) & 0x1) {
96
 
      const GLboolean is_integer = texobj->_IsIntegerFormat;
97
 
      GLenum texBaseFormat = _mesa_base_tex_image(texobj)->_BaseFormat;
98
 
 
99
 
      if (texobj->StencilSampling)
100
 
         texBaseFormat = GL_STENCIL_INDEX;
101
 
 
102
 
      if (st->apply_texture_swizzle_to_border_color) {
103
 
         const struct gl_texture_object *stobj = st_texture_object_const(texobj);
104
 
         /* XXX: clean that up to not use the sampler view at all */
105
 
         const struct st_sampler_view *sv = st_texture_get_current_sampler_view(st, stobj);
106
 
 
107
 
         if (sv) {
108
 
            struct pipe_sampler_view *view = sv->view;
109
 
            union pipe_color_union tmp = sampler->border_color;
110
 
            const unsigned char swz[4] =
111
 
            {
112
 
               view->swizzle_r,
113
 
               view->swizzle_g,
114
 
               view->swizzle_b,
115
 
               view->swizzle_a,
116
 
            };
117
 
 
118
 
            st_translate_color(&tmp, texBaseFormat, is_integer);
119
 
 
120
 
            util_format_apply_color_swizzle(&sampler->border_color,
121
 
                                            &tmp, swz, is_integer);
122
 
         } else {
123
 
            st_translate_color(&sampler->border_color,
124
 
                               texBaseFormat, is_integer);
125
 
         }
126
 
      } else {
127
 
         st_translate_color(&sampler->border_color,
128
 
                            texBaseFormat, is_integer);
129
 
      }
130
 
      sampler->border_color_is_integer = is_integer;
131
 
   }
132
 
 
133
 
   /* If sampling a depth texture and using shadow comparison */
134
 
   if (msamp->Attrib.CompareMode == GL_COMPARE_R_TO_TEXTURE) {
135
 
      GLenum texBaseFormat = _mesa_base_tex_image(texobj)->_BaseFormat;
136
 
 
137
 
      if (texBaseFormat == GL_DEPTH_COMPONENT ||
138
 
          (texBaseFormat == GL_DEPTH_STENCIL && !texobj->StencilSampling))
139
 
         sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
140
 
   }
141
 
}
142
 
 
143
 
/**
144
 
 * Get a pipe_sampler_state object from a texture unit.
145
 
 */
146
 
void
147
 
st_convert_sampler_from_unit(const struct st_context *st,
148
 
                             struct pipe_sampler_state *sampler,
149
 
                             GLuint texUnit)
150
 
{
151
 
   const struct gl_texture_object *texobj;
152
 
   struct gl_context *ctx = st->ctx;
153
 
   const struct gl_sampler_object *msamp;
154
 
 
155
 
   texobj = ctx->Texture.Unit[texUnit]._Current;
156
 
   assert(texobj);
157
 
 
158
 
   msamp = _mesa_get_samplerobj(ctx, texUnit);
159
 
 
160
 
   st_convert_sampler(st, texobj, msamp, ctx->Texture.Unit[texUnit].LodBiasQuantized,
161
 
                      sampler, ctx->Texture.CubeMapSeamless);
162
 
}
163
 
 
164
 
 
165
 
/**
166
 
 * Update the gallium driver's sampler state for fragment, vertex or
167
 
 * geometry shader stage.
168
 
 */
169
 
static void
170
 
update_shader_samplers(struct st_context *st,
171
 
                       enum pipe_shader_type shader_stage,
172
 
                       const struct gl_program *prog,
173
 
                       struct pipe_sampler_state *samplers,
174
 
                       unsigned *out_num_samplers)
175
 
{
176
 
   struct gl_context *ctx = st->ctx;
177
 
   GLbitfield samplers_used = prog->SamplersUsed;
178
 
   GLbitfield free_slots = ~prog->SamplersUsed;
179
 
   GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
180
 
   unsigned unit, num_samplers;
181
 
   struct pipe_sampler_state local_samplers[PIPE_MAX_SAMPLERS];
182
 
   const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS];
183
 
 
184
 
   if (samplers_used == 0x0) {
185
 
      if (out_num_samplers)
186
 
         *out_num_samplers = 0;
187
 
      return;
188
 
   }
189
 
 
190
 
   if (!samplers)
191
 
      samplers = local_samplers;
192
 
 
193
 
   num_samplers = util_last_bit(samplers_used);
194
 
 
195
 
   /* loop over sampler units (aka tex image units) */
196
 
   for (unit = 0; samplers_used; unit++, samplers_used >>= 1) {
197
 
      struct pipe_sampler_state *sampler = samplers + unit;
198
 
      unsigned tex_unit = prog->SamplerUnits[unit];
199
 
 
200
 
      /* Don't update the sampler for TBOs. cso_context will not bind sampler
201
 
       * states that are NULL.
202
 
       */
203
 
      if (samplers_used & 1 &&
204
 
          (ctx->Texture.Unit[tex_unit]._Current->Target != GL_TEXTURE_BUFFER ||
205
 
           st->texture_buffer_sampler)) {
206
 
         st_convert_sampler_from_unit(st, sampler, tex_unit);
207
 
         states[unit] = sampler;
208
 
      } else {
209
 
         states[unit] = NULL;
210
 
      }
211
 
   }
212
 
 
213
 
   /* For any external samplers with multiplaner YUV, stuff the additional
214
 
    * sampler states we need at the end.
215
 
    *
216
 
    * Just re-use the existing sampler-state from the primary slot.
217
 
    */
218
 
   while (unlikely(external_samplers_used)) {
219
 
      GLuint unit = u_bit_scan(&external_samplers_used);
220
 
      GLuint extra = 0;
221
 
      struct gl_texture_object *stObj =
222
 
            st_get_texture_object(st->ctx, prog, unit);
223
 
      struct pipe_sampler_state *sampler = samplers + unit;
224
 
 
225
 
      /* if resource format matches then YUV wasn't lowered */
226
 
      if (!stObj || st_get_view_format(stObj) == stObj->pt->format)
227
 
         continue;
228
 
 
229
 
      switch (st_get_view_format(stObj)) {
230
 
      case PIPE_FORMAT_NV12:
231
 
         if (stObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM)
232
 
            /* no additional views needed */
233
 
            break;
234
 
         FALLTHROUGH;
235
 
      case PIPE_FORMAT_P010:
236
 
      case PIPE_FORMAT_P012:
237
 
      case PIPE_FORMAT_P016:
238
 
      case PIPE_FORMAT_Y210:
239
 
      case PIPE_FORMAT_Y212:
240
 
      case PIPE_FORMAT_Y216:
241
 
      case PIPE_FORMAT_YUYV:
242
 
      case PIPE_FORMAT_UYVY:
243
 
         if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM ||
244
 
             stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) {
245
 
            /* no additional views needed */
246
 
            break;
247
 
         }
248
 
 
249
 
         /* we need one additional sampler: */
250
 
         extra = u_bit_scan(&free_slots);
251
 
         states[extra] = sampler;
252
 
         break;
253
 
      case PIPE_FORMAT_IYUV:
254
 
         /* we need two additional samplers: */
255
 
         extra = u_bit_scan(&free_slots);
256
 
         states[extra] = sampler;
257
 
         extra = u_bit_scan(&free_slots);
258
 
         states[extra] = sampler;
259
 
         break;
260
 
      default:
261
 
         break;
262
 
      }
263
 
 
264
 
      num_samplers = MAX2(num_samplers, extra + 1);
265
 
   }
266
 
 
267
 
   cso_set_samplers(st->cso_context, shader_stage, num_samplers, states);
268
 
 
269
 
   if (out_num_samplers)
270
 
      *out_num_samplers = num_samplers;
271
 
}
272
 
 
273
 
 
274
 
void
275
 
st_update_vertex_samplers(struct st_context *st)
276
 
{
277
 
   const struct gl_context *ctx = st->ctx;
278
 
 
279
 
   update_shader_samplers(st,
280
 
                          PIPE_SHADER_VERTEX,
281
 
                          ctx->VertexProgram._Current,
282
 
                          st->state.vert_samplers,
283
 
                          &st->state.num_vert_samplers);
284
 
}
285
 
 
286
 
 
287
 
void
288
 
st_update_tessctrl_samplers(struct st_context *st)
289
 
{
290
 
   const struct gl_context *ctx = st->ctx;
291
 
 
292
 
   if (ctx->TessCtrlProgram._Current) {
293
 
      update_shader_samplers(st,
294
 
                             PIPE_SHADER_TESS_CTRL,
295
 
                             ctx->TessCtrlProgram._Current, NULL, NULL);
296
 
   }
297
 
}
298
 
 
299
 
 
300
 
void
301
 
st_update_tesseval_samplers(struct st_context *st)
302
 
{
303
 
   const struct gl_context *ctx = st->ctx;
304
 
 
305
 
   if (ctx->TessEvalProgram._Current) {
306
 
      update_shader_samplers(st,
307
 
                             PIPE_SHADER_TESS_EVAL,
308
 
                             ctx->TessEvalProgram._Current, NULL, NULL);
309
 
   }
310
 
}
311
 
 
312
 
 
313
 
void
314
 
st_update_geometry_samplers(struct st_context *st)
315
 
{
316
 
   const struct gl_context *ctx = st->ctx;
317
 
 
318
 
   if (ctx->GeometryProgram._Current) {
319
 
      update_shader_samplers(st,
320
 
                             PIPE_SHADER_GEOMETRY,
321
 
                             ctx->GeometryProgram._Current, NULL, NULL);
322
 
   }
323
 
}
324
 
 
325
 
 
326
 
void
327
 
st_update_fragment_samplers(struct st_context *st)
328
 
{
329
 
   const struct gl_context *ctx = st->ctx;
330
 
 
331
 
   update_shader_samplers(st,
332
 
                          PIPE_SHADER_FRAGMENT,
333
 
                          ctx->FragmentProgram._Current,
334
 
                          st->state.frag_samplers,
335
 
                          &st->state.num_frag_samplers);
336
 
}
337
 
 
338
 
 
339
 
void
340
 
st_update_compute_samplers(struct st_context *st)
341
 
{
342
 
   const struct gl_context *ctx = st->ctx;
343
 
 
344
 
   if (ctx->ComputeProgram._Current) {
345
 
      update_shader_samplers(st,
346
 
                             PIPE_SHADER_COMPUTE,
347
 
                             ctx->ComputeProgram._Current, NULL, NULL);
348
 
   }
349
 
}