"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/softpipe/sp_state_shader.c" (16 Sep 2020, 12760 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sp_state_shader.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    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 #include "sp_context.h"
   29 #include "sp_state.h"
   30 #include "sp_fs.h"
   31 #include "sp_texture.h"
   32 
   33 #include "pipe/p_defines.h"
   34 #include "util/u_memory.h"
   35 #include "util/u_inlines.h"
   36 #include "util/u_pstipple.h"
   37 #include "draw/draw_context.h"
   38 #include "draw/draw_vs.h"
   39 #include "draw/draw_gs.h"
   40 #include "tgsi/tgsi_dump.h"
   41 #include "tgsi/tgsi_scan.h"
   42 #include "tgsi/tgsi_parse.h"
   43 
   44 
   45 /**
   46  * Create a new fragment shader variant.
   47  */
   48 static struct sp_fragment_shader_variant *
   49 create_fs_variant(struct softpipe_context *softpipe,
   50                   struct sp_fragment_shader *fs,
   51                   const struct sp_fragment_shader_variant_key *key)
   52 {
   53    struct sp_fragment_shader_variant *var;
   54    struct pipe_shader_state *curfs = &fs->shader;
   55 
   56    /* codegen, create variant object */
   57    var = softpipe_create_fs_variant_exec(softpipe);
   58 
   59    if (var) {
   60       var->key = *key;
   61 
   62 #if DO_PSTIPPLE_IN_HELPER_MODULE
   63       if (key->polygon_stipple) {
   64          /* get new shader that implements polygon stippling */
   65          var->tokens = 
   66             util_pstipple_create_fragment_shader(curfs->tokens,
   67                                                  &var->stipple_sampler_unit, 0,
   68                                                  TGSI_FILE_INPUT);
   69       }
   70       else
   71 #endif
   72       {
   73          var->tokens = tgsi_dup_tokens(curfs->tokens);
   74          var->stipple_sampler_unit = 0;
   75       }
   76 
   77       tgsi_scan_shader(var->tokens, &var->info);
   78 
   79       /* See comments elsewhere about draw fragment shaders */
   80 #if 0
   81       /* draw's fs state */
   82       var->draw_shader = draw_create_fragment_shader(softpipe->draw,
   83                                                      &fs->shader);
   84       if (!var->draw_shader) {
   85          var->delete(var);
   86          FREE((void *) var->tokens);
   87          return NULL;
   88       }
   89 #endif
   90 
   91       /* insert variant into linked list */
   92       var->next = fs->variants;
   93       fs->variants = var;
   94    }
   95 
   96    return var;
   97 }
   98 
   99 
  100 struct sp_fragment_shader_variant *
  101 softpipe_find_fs_variant(struct softpipe_context *sp,
  102                          struct sp_fragment_shader *fs,
  103                          const struct sp_fragment_shader_variant_key *key)
  104 {
  105    struct sp_fragment_shader_variant *var;
  106 
  107    for (var = fs->variants; var; var = var->next) {
  108       if (memcmp(&var->key, key, sizeof(*key)) == 0) {
  109          /* found it */
  110          return var;
  111       }
  112    }
  113 
  114    return create_fs_variant(sp, fs, key);
  115 }
  116 
  117 
  118 static void *
  119 softpipe_create_fs_state(struct pipe_context *pipe,
  120                          const struct pipe_shader_state *templ)
  121 {
  122    struct softpipe_context *softpipe = softpipe_context(pipe);
  123    struct sp_fragment_shader *state = CALLOC_STRUCT(sp_fragment_shader);
  124 
  125    /* debug */
  126    if (softpipe->dump_fs) 
  127       tgsi_dump(templ->tokens, 0);
  128 
  129    /* we need to keep a local copy of the tokens */
  130    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  131 
  132    /* draw's fs state */
  133    state->draw_shader = draw_create_fragment_shader(softpipe->draw,
  134                                                     &state->shader);
  135    if (!state->draw_shader) {
  136       tgsi_free_tokens(state->shader.tokens);
  137       FREE(state);
  138       return NULL;
  139    }
  140 
  141    return state;
  142 }
  143 
  144 
  145 static void
  146 softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
  147 {
  148    struct softpipe_context *softpipe = softpipe_context(pipe);
  149    struct sp_fragment_shader *state = (struct sp_fragment_shader *) fs;
  150 
  151    if (softpipe->fs == fs)
  152       return;
  153 
  154    draw_flush(softpipe->draw);
  155 
  156    softpipe->fs = fs;
  157 
  158    /* This depends on the current fragment shader and must always be
  159     * re-validated before use.
  160     */
  161    softpipe->fs_variant = NULL;
  162 
  163    if (state)
  164       draw_bind_fragment_shader(softpipe->draw,
  165                                 state->draw_shader);
  166    else
  167       draw_bind_fragment_shader(softpipe->draw, NULL);
  168 
  169    softpipe->dirty |= SP_NEW_FS;
  170 }
  171 
  172 
  173 static void
  174 softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
  175 {
  176    struct softpipe_context *softpipe = softpipe_context(pipe);
  177    struct sp_fragment_shader *state = fs;
  178    struct sp_fragment_shader_variant *var, *next_var;
  179 
  180    assert(fs != softpipe->fs);
  181 
  182    /* delete variants */
  183    for (var = state->variants; var; var = next_var) {
  184       next_var = var->next;
  185 
  186       assert(var != softpipe->fs_variant);
  187 
  188       /* See comments elsewhere about draw fragment shaders */
  189 #if 0
  190       draw_delete_fragment_shader(softpipe->draw, var->draw_shader);
  191 #endif
  192 
  193       var->delete(var, softpipe->fs_machine);
  194    }
  195 
  196    draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
  197 
  198    tgsi_free_tokens(state->shader.tokens);
  199    FREE(state);
  200 }
  201 
  202 
  203 static void *
  204 softpipe_create_vs_state(struct pipe_context *pipe,
  205                          const struct pipe_shader_state *templ)
  206 {
  207    struct softpipe_context *softpipe = softpipe_context(pipe);
  208    struct sp_vertex_shader *state;
  209 
  210    state = CALLOC_STRUCT(sp_vertex_shader);
  211    if (!state)
  212       goto fail;
  213 
  214    /* copy shader tokens, the ones passed in will go away.
  215     */
  216    state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  217    if (state->shader.tokens == NULL)
  218       goto fail;
  219 
  220    state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
  221    if (state->draw_data == NULL) 
  222       goto fail;
  223 
  224    state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  225 
  226    return state;
  227 
  228 fail:
  229    if (state) {
  230       tgsi_free_tokens(state->shader.tokens);
  231       FREE( state->draw_data );
  232       FREE( state );
  233    }
  234    return NULL;
  235 }
  236 
  237 
  238 static void
  239 softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
  240 {
  241    struct softpipe_context *softpipe = softpipe_context(pipe);
  242 
  243    softpipe->vs = (struct sp_vertex_shader *) vs;
  244 
  245    draw_bind_vertex_shader(softpipe->draw,
  246                            (softpipe->vs ? softpipe->vs->draw_data : NULL));
  247 
  248    softpipe->dirty |= SP_NEW_VS;
  249 }
  250 
  251 
  252 static void
  253 softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
  254 {
  255    struct softpipe_context *softpipe = softpipe_context(pipe);
  256 
  257    struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
  258 
  259    draw_delete_vertex_shader(softpipe->draw, state->draw_data);
  260    tgsi_free_tokens(state->shader.tokens);
  261    FREE( state );
  262 }
  263 
  264 
  265 static void *
  266 softpipe_create_gs_state(struct pipe_context *pipe,
  267                          const struct pipe_shader_state *templ)
  268 {
  269    struct softpipe_context *softpipe = softpipe_context(pipe);
  270    struct sp_geometry_shader *state;
  271 
  272    state = CALLOC_STRUCT(sp_geometry_shader);
  273    if (!state)
  274       goto fail;
  275 
  276    state->shader = *templ;
  277 
  278    if (templ->tokens) {
  279       /* debug */
  280       if (softpipe->dump_gs)
  281          tgsi_dump(templ->tokens, 0);
  282 
  283       /* copy shader tokens, the ones passed in will go away.
  284        */
  285       state->shader.tokens = tgsi_dup_tokens(templ->tokens);
  286       if (state->shader.tokens == NULL)
  287          goto fail;
  288 
  289       state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
  290       if (state->draw_data == NULL)
  291          goto fail;
  292 
  293       state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
  294    }
  295 
  296    return state;
  297 
  298 fail:
  299    if (state) {
  300       tgsi_free_tokens(state->shader.tokens);
  301       FREE( state->draw_data );
  302       FREE( state );
  303    }
  304    return NULL;
  305 }
  306 
  307 
  308 static void
  309 softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
  310 {
  311    struct softpipe_context *softpipe = softpipe_context(pipe);
  312 
  313    softpipe->gs = (struct sp_geometry_shader *)gs;
  314 
  315    draw_bind_geometry_shader(softpipe->draw,
  316                              (softpipe->gs ? softpipe->gs->draw_data : NULL));
  317 
  318    softpipe->dirty |= SP_NEW_GS;
  319 }
  320 
  321 
  322 static void
  323 softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
  324 {
  325    struct softpipe_context *softpipe = softpipe_context(pipe);
  326 
  327    struct sp_geometry_shader *state =
  328       (struct sp_geometry_shader *)gs;
  329 
  330    draw_delete_geometry_shader(softpipe->draw,
  331                                (state) ? state->draw_data : 0);
  332 
  333    tgsi_free_tokens(state->shader.tokens);
  334    FREE(state);
  335 }
  336 
  337 
  338 static void
  339 softpipe_set_constant_buffer(struct pipe_context *pipe,
  340                              enum pipe_shader_type shader, uint index,
  341                              const struct pipe_constant_buffer *cb)
  342 {
  343    struct softpipe_context *softpipe = softpipe_context(pipe);
  344    struct pipe_resource *constants = cb ? cb->buffer : NULL;
  345    unsigned size;
  346    const void *data;
  347 
  348    assert(shader < PIPE_SHADER_TYPES);
  349 
  350    if (cb && cb->user_buffer) {
  351       constants = softpipe_user_buffer_create(pipe->screen,
  352                                               (void *) cb->user_buffer,
  353                                               cb->buffer_size,
  354                                               PIPE_BIND_CONSTANT_BUFFER);
  355    }
  356 
  357    size = cb ? cb->buffer_size : 0;
  358    data = constants ? softpipe_resource_data(constants) : NULL;
  359    if (data)
  360       data = (const char *) data + cb->buffer_offset;
  361 
  362    draw_flush(softpipe->draw);
  363 
  364    /* note: reference counting */
  365    pipe_resource_reference(&softpipe->constants[shader][index], constants);
  366 
  367    if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
  368       draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
  369    }
  370 
  371    softpipe->mapped_constants[shader][index] = data;
  372    softpipe->const_buffer_size[shader][index] = size;
  373 
  374    softpipe->dirty |= SP_NEW_CONSTANTS;
  375 
  376    if (cb && cb->user_buffer) {
  377       pipe_resource_reference(&constants, NULL);
  378    }
  379 }
  380 
  381 static void *
  382 softpipe_create_compute_state(struct pipe_context *pipe,
  383                               const struct pipe_compute_state *templ)
  384 {
  385    struct softpipe_context *softpipe = softpipe_context(pipe);
  386    const struct tgsi_token *tokens;
  387    struct sp_compute_shader *state;
  388    if (templ->ir_type != PIPE_SHADER_IR_TGSI)
  389       return NULL;
  390 
  391    tokens = templ->prog;
  392    /* debug */
  393    if (softpipe->dump_cs)
  394       tgsi_dump(tokens, 0);
  395 
  396    state = CALLOC_STRUCT(sp_compute_shader);
  397 
  398    state->shader = *templ;
  399    state->tokens = tgsi_dup_tokens(tokens);
  400    tgsi_scan_shader(state->tokens, &state->info);
  401 
  402    state->max_sampler = state->info.file_max[TGSI_FILE_SAMPLER];
  403 
  404    return state;
  405 }
  406 
  407 static void
  408 softpipe_bind_compute_state(struct pipe_context *pipe,
  409                             void *cs)
  410 {
  411    struct softpipe_context *softpipe = softpipe_context(pipe);
  412    struct sp_compute_shader *state = (struct sp_compute_shader *)cs;
  413    if (softpipe->cs == state)
  414       return;
  415 
  416    softpipe->cs = state;
  417 }
  418 
  419 static void
  420 softpipe_delete_compute_state(struct pipe_context *pipe,
  421                               void *cs)
  422 {
  423    ASSERTED struct softpipe_context *softpipe = softpipe_context(pipe);
  424    struct sp_compute_shader *state = (struct sp_compute_shader *)cs;
  425 
  426    assert(softpipe->cs != state);
  427    tgsi_free_tokens(state->tokens);
  428    FREE(state);
  429 }
  430 
  431 void
  432 softpipe_init_shader_funcs(struct pipe_context *pipe)
  433 {
  434    pipe->create_fs_state = softpipe_create_fs_state;
  435    pipe->bind_fs_state   = softpipe_bind_fs_state;
  436    pipe->delete_fs_state = softpipe_delete_fs_state;
  437 
  438    pipe->create_vs_state = softpipe_create_vs_state;
  439    pipe->bind_vs_state   = softpipe_bind_vs_state;
  440    pipe->delete_vs_state = softpipe_delete_vs_state;
  441 
  442    pipe->create_gs_state = softpipe_create_gs_state;
  443    pipe->bind_gs_state   = softpipe_bind_gs_state;
  444    pipe->delete_gs_state = softpipe_delete_gs_state;
  445 
  446    pipe->set_constant_buffer = softpipe_set_constant_buffer;
  447 
  448    pipe->create_compute_state = softpipe_create_compute_state;
  449    pipe->bind_compute_state = softpipe_bind_compute_state;
  450    pipe->delete_compute_state = softpipe_delete_compute_state;
  451 }