Home | History | Annotate | Download | only in state_tracker
      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 (at) vmware.com>
     31   *   Brian Paul
     32   */
     33 
     34 
     35 #include "main/context.h"
     36 #include "main/macros.h"
     37 #include "main/mtypes.h"
     38 #include "main/samplerobj.h"
     39 #include "main/teximage.h"
     40 #include "main/texobj.h"
     41 #include "program/prog_instruction.h"
     42 
     43 #include "st_context.h"
     44 #include "st_atom.h"
     45 #include "st_sampler_view.h"
     46 #include "st_texture.h"
     47 #include "st_format.h"
     48 #include "st_cb_texture.h"
     49 #include "pipe/p_context.h"
     50 #include "util/u_format.h"
     51 #include "util/u_inlines.h"
     52 #include "cso_cache/cso_context.h"
     53 
     54 
     55 static GLboolean
     56 update_single_texture(struct st_context *st,
     57                       struct pipe_sampler_view **sampler_view,
     58 		      GLuint texUnit, unsigned glsl_version)
     59 {
     60    struct gl_context *ctx = st->ctx;
     61    const struct gl_sampler_object *samp;
     62    struct gl_texture_object *texObj;
     63    struct st_texture_object *stObj;
     64    GLboolean retval;
     65 
     66    samp = _mesa_get_samplerobj(ctx, texUnit);
     67 
     68    texObj = ctx->Texture.Unit[texUnit]._Current;
     69 
     70    if (!texObj) {
     71       texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
     72       samp = &texObj->Sampler;
     73    }
     74    stObj = st_texture_object(texObj);
     75 
     76    retval = st_finalize_texture(ctx, st->pipe, texObj, 0);
     77    if (!retval) {
     78       /* out of mem */
     79       return GL_FALSE;
     80    }
     81 
     82    /* Check a few pieces of state outside the texture object to see if we
     83     * need to force revalidation.
     84     */
     85    if (stObj->prev_glsl_version != glsl_version ||
     86        stObj->prev_sRGBDecode != samp->sRGBDecode) {
     87 
     88       st_texture_release_all_sampler_views(st, stObj);
     89 
     90       stObj->prev_glsl_version = glsl_version;
     91       stObj->prev_sRGBDecode = samp->sRGBDecode;
     92    }
     93 
     94    *sampler_view =
     95       st_get_texture_sampler_view_from_stobj(st, stObj, samp, glsl_version);
     96    return GL_TRUE;
     97 }
     98 
     99 
    100 
    101 static void
    102 update_textures(struct st_context *st,
    103                 gl_shader_stage mesa_shader,
    104                 const struct gl_program *prog,
    105                 unsigned max_units,
    106                 struct pipe_sampler_view **sampler_views,
    107                 unsigned *num_textures)
    108 {
    109    const GLuint old_max = *num_textures;
    110    GLbitfield samplers_used = prog->SamplersUsed;
    111    GLbitfield free_slots = ~prog->SamplersUsed;
    112    GLbitfield external_samplers_used = prog->ExternalSamplersUsed;
    113    GLuint unit;
    114    enum pipe_shader_type shader_stage = st_shader_stage_to_ptarget(mesa_shader);
    115 
    116    if (samplers_used == 0x0 && old_max == 0)
    117       return;
    118 
    119    *num_textures = 0;
    120 
    121    /* loop over sampler units (aka tex image units) */
    122    for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) {
    123       struct pipe_sampler_view *sampler_view = NULL;
    124 
    125       if (samplers_used & 1) {
    126          /* prog->sh.data is NULL if it's ARB_fragment_program */
    127          unsigned glsl_version = prog->sh.data ? prog->sh.data->Version : 0;
    128          const GLuint texUnit = prog->SamplerUnits[unit];
    129          GLboolean retval;
    130 
    131          retval = update_single_texture(st, &sampler_view, texUnit,
    132                                         glsl_version);
    133          if (retval == GL_FALSE)
    134             continue;
    135 
    136          *num_textures = unit + 1;
    137       }
    138       else if (samplers_used == 0 && unit >= old_max) {
    139          /* if we've reset all the old views and we have no more new ones */
    140          break;
    141       }
    142 
    143       pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view);
    144    }
    145 
    146    /* For any external samplers with multiplaner YUV, stuff the additional
    147     * sampler views we need at the end.
    148     *
    149     * Trying to cache the sampler view in the stObj looks painful, so just
    150     * re-create the sampler view for the extra planes each time.  Main use
    151     * case is video playback (ie. fps games wouldn't be using this) so I
    152     * guess no point to try to optimize this feature.
    153     */
    154    while (unlikely(external_samplers_used)) {
    155       GLuint unit = u_bit_scan(&external_samplers_used);
    156       GLuint extra = 0;
    157       struct st_texture_object *stObj =
    158             st_get_texture_object(st->ctx, prog, unit);
    159       struct pipe_sampler_view tmpl;
    160 
    161       if (!stObj)
    162          continue;
    163 
    164       /* use original view as template: */
    165       tmpl = *sampler_views[unit];
    166 
    167       switch (st_get_view_format(stObj)) {
    168       case PIPE_FORMAT_NV12:
    169          /* we need one additional R8G8 view: */
    170          tmpl.format = PIPE_FORMAT_RG88_UNORM;
    171          tmpl.swizzle_g = PIPE_SWIZZLE_Y;   /* tmpl from Y plane is R8 */
    172          extra = u_bit_scan(&free_slots);
    173          sampler_views[extra] =
    174                st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl);
    175          break;
    176       case PIPE_FORMAT_IYUV:
    177          /* we need two additional R8 views: */
    178          tmpl.format = PIPE_FORMAT_R8_UNORM;
    179          extra = u_bit_scan(&free_slots);
    180          sampler_views[extra] =
    181                st->pipe->create_sampler_view(st->pipe, stObj->pt->next, &tmpl);
    182          extra = u_bit_scan(&free_slots);
    183          sampler_views[extra] =
    184                st->pipe->create_sampler_view(st->pipe, stObj->pt->next->next, &tmpl);
    185          break;
    186       default:
    187          break;
    188       }
    189 
    190       *num_textures = MAX2(*num_textures, extra + 1);
    191    }
    192 
    193    cso_set_sampler_views(st->cso_context,
    194                          shader_stage,
    195                          *num_textures,
    196                          sampler_views);
    197 }
    198 
    199 
    200 
    201 static void
    202 update_vertex_textures(struct st_context *st)
    203 {
    204    const struct gl_context *ctx = st->ctx;
    205 
    206    if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) {
    207       update_textures(st,
    208                       MESA_SHADER_VERTEX,
    209                       ctx->VertexProgram._Current,
    210                       ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits,
    211                       st->state.sampler_views[PIPE_SHADER_VERTEX],
    212                       &st->state.num_sampler_views[PIPE_SHADER_VERTEX]);
    213    }
    214 }
    215 
    216 
    217 static void
    218 update_fragment_textures(struct st_context *st)
    219 {
    220    const struct gl_context *ctx = st->ctx;
    221 
    222    update_textures(st,
    223                    MESA_SHADER_FRAGMENT,
    224                    ctx->FragmentProgram._Current,
    225                    ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
    226                    st->state.sampler_views[PIPE_SHADER_FRAGMENT],
    227                    &st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
    228 }
    229 
    230 
    231 static void
    232 update_geometry_textures(struct st_context *st)
    233 {
    234    const struct gl_context *ctx = st->ctx;
    235 
    236    if (ctx->GeometryProgram._Current) {
    237       update_textures(st,
    238                       MESA_SHADER_GEOMETRY,
    239                       ctx->GeometryProgram._Current,
    240                       ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
    241                       st->state.sampler_views[PIPE_SHADER_GEOMETRY],
    242                       &st->state.num_sampler_views[PIPE_SHADER_GEOMETRY]);
    243    }
    244 }
    245 
    246 
    247 static void
    248 update_tessctrl_textures(struct st_context *st)
    249 {
    250    const struct gl_context *ctx = st->ctx;
    251 
    252    if (ctx->TessCtrlProgram._Current) {
    253       update_textures(st,
    254                       MESA_SHADER_TESS_CTRL,
    255                       ctx->TessCtrlProgram._Current,
    256                       ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits,
    257                       st->state.sampler_views[PIPE_SHADER_TESS_CTRL],
    258                       &st->state.num_sampler_views[PIPE_SHADER_TESS_CTRL]);
    259    }
    260 }
    261 
    262 
    263 static void
    264 update_tesseval_textures(struct st_context *st)
    265 {
    266    const struct gl_context *ctx = st->ctx;
    267 
    268    if (ctx->TessEvalProgram._Current) {
    269       update_textures(st,
    270                       MESA_SHADER_TESS_EVAL,
    271                       ctx->TessEvalProgram._Current,
    272                       ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits,
    273                       st->state.sampler_views[PIPE_SHADER_TESS_EVAL],
    274                       &st->state.num_sampler_views[PIPE_SHADER_TESS_EVAL]);
    275    }
    276 }
    277 
    278 
    279 static void
    280 update_compute_textures(struct st_context *st)
    281 {
    282    const struct gl_context *ctx = st->ctx;
    283 
    284    if (ctx->ComputeProgram._Current) {
    285       update_textures(st,
    286                       MESA_SHADER_COMPUTE,
    287                       ctx->ComputeProgram._Current,
    288                       ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits,
    289                       st->state.sampler_views[PIPE_SHADER_COMPUTE],
    290                       &st->state.num_sampler_views[PIPE_SHADER_COMPUTE]);
    291    }
    292 }
    293 
    294 
    295 const struct st_tracked_state st_update_fragment_texture = {
    296    update_fragment_textures				/* update */
    297 };
    298 
    299 
    300 const struct st_tracked_state st_update_vertex_texture = {
    301    update_vertex_textures				/* update */
    302 };
    303 
    304 
    305 const struct st_tracked_state st_update_geometry_texture = {
    306    update_geometry_textures				/* update */
    307 };
    308 
    309 
    310 const struct st_tracked_state st_update_tessctrl_texture = {
    311    update_tessctrl_textures				/* update */
    312 };
    313 
    314 
    315 const struct st_tracked_state st_update_tesseval_texture = {
    316    update_tesseval_textures				/* update */
    317 };
    318 
    319 
    320 const struct st_tracked_state st_update_compute_texture = {
    321    update_compute_textures				/* update */
    322 };
    323