"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c" (16 Sep 2020, 11548 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 "nvc0_shader_state.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  * Copyright 2010 Christoph Bumiller
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice shall be included in
   12  * all copies or substantial portions of the Software.
   13  *
   14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   20  * OTHER DEALINGS IN THE SOFTWARE.
   21  */
   22 
   23 #include "pipe/p_context.h"
   24 #include "pipe/p_defines.h"
   25 #include "pipe/p_state.h"
   26 #include "util/u_inlines.h"
   27 
   28 #include "nvc0/nvc0_context.h"
   29 #include "nvc0/nvc0_query_hw.h"
   30 
   31 #include "nvc0/nvc0_compute.xml.h"
   32 
   33 static inline void
   34 nvc0_program_update_context_state(struct nvc0_context *nvc0,
   35                                   struct nvc0_program *prog, int stage)
   36 {
   37    if (prog && prog->need_tls) {
   38       const uint32_t flags = NV_VRAM_DOMAIN(&nvc0->screen->base) | NOUVEAU_BO_RDWR;
   39       if (!nvc0->state.tls_required)
   40          BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TLS, flags, nvc0->screen->tls);
   41       nvc0->state.tls_required |= 1 << stage;
   42    } else {
   43       if (nvc0->state.tls_required == (1 << stage))
   44          nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TLS);
   45       nvc0->state.tls_required &= ~(1 << stage);
   46    }
   47 }
   48 
   49 static inline bool
   50 nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
   51 {
   52    if (prog->mem)
   53       return true;
   54 
   55    if (!prog->translated) {
   56       prog->translated = nvc0_program_translate(
   57          prog, nvc0->screen->base.device->chipset, &nvc0->base.debug);
   58       if (!prog->translated)
   59          return false;
   60    }
   61 
   62    if (likely(prog->code_size))
   63       return nvc0_program_upload(nvc0, prog);
   64    return true; /* stream output info only */
   65 }
   66 
   67 void
   68 nvc0_vertprog_validate(struct nvc0_context *nvc0)
   69 {
   70    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   71    struct nvc0_program *vp = nvc0->vertprog;
   72 
   73    if (!nvc0_program_validate(nvc0, vp))
   74          return;
   75    nvc0_program_update_context_state(nvc0, vp, 0);
   76 
   77    BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2);
   78    PUSH_DATA (push, 0x11);
   79    PUSH_DATA (push, vp->code_base);
   80    BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1);
   81    PUSH_DATA (push, vp->num_gprs);
   82 
   83    // BEGIN_NVC0(push, NVC0_3D_(0x163c), 1);
   84    // PUSH_DATA (push, 0);
   85 }
   86 
   87 void
   88 nvc0_fragprog_validate(struct nvc0_context *nvc0)
   89 {
   90    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   91    struct nvc0_program *fp = nvc0->fragprog;
   92    struct pipe_rasterizer_state *rast = &nvc0->rast->pipe;
   93 
   94    if (fp->fp.force_persample_interp != rast->force_persample_interp) {
   95       /* Force the program to be reuploaded, which will trigger interp fixups
   96        * to get applied
   97        */
   98       if (fp->mem)
   99          nouveau_heap_free(&fp->mem);
  100 
  101       fp->fp.force_persample_interp = rast->force_persample_interp;
  102    }
  103 
  104    /* Shade model works well enough when both colors follow it. However if one
  105     * (or both) is explicitly set, then we have to go the patching route.
  106     */
  107    bool has_explicit_color = fp->fp.colors &&
  108       (((fp->fp.colors & 1) && !fp->fp.color_interp[0]) ||
  109        ((fp->fp.colors & 2) && !fp->fp.color_interp[1]));
  110    bool hwflatshade = false;
  111    if (has_explicit_color && fp->fp.flatshade != rast->flatshade) {
  112       /* Force re-upload */
  113       if (fp->mem)
  114          nouveau_heap_free(&fp->mem);
  115 
  116       fp->fp.flatshade = rast->flatshade;
  117 
  118       /* Always smooth-shade in this mode, the shader will decide on its own
  119        * when to flat-shade.
  120        */
  121    } else if (!has_explicit_color) {
  122       hwflatshade = rast->flatshade;
  123 
  124       /* No need to binary-patch the shader each time, make sure that it's set
  125        * up for the default behaviour.
  126        */
  127       fp->fp.flatshade = 0;
  128    }
  129 
  130    if (hwflatshade != nvc0->state.flatshade) {
  131       nvc0->state.flatshade = hwflatshade;
  132       BEGIN_NVC0(push, NVC0_3D(SHADE_MODEL), 1);
  133       PUSH_DATA (push, hwflatshade ? NVC0_3D_SHADE_MODEL_FLAT :
  134                                      NVC0_3D_SHADE_MODEL_SMOOTH);
  135    }
  136 
  137    if (fp->mem && !(nvc0->dirty_3d & NVC0_NEW_3D_FRAGPROG)) {
  138       return;
  139    }
  140 
  141    if (!nvc0_program_validate(nvc0, fp))
  142          return;
  143    nvc0_program_update_context_state(nvc0, fp, 4);
  144 
  145    if (fp->fp.early_z != nvc0->state.early_z_forced) {
  146       nvc0->state.early_z_forced = fp->fp.early_z;
  147       IMMED_NVC0(push, NVC0_3D(FORCE_EARLY_FRAGMENT_TESTS), fp->fp.early_z);
  148    }
  149    if (fp->fp.post_depth_coverage != nvc0->state.post_depth_coverage) {
  150       nvc0->state.post_depth_coverage = fp->fp.post_depth_coverage;
  151       IMMED_NVC0(push, NVC0_3D(POST_DEPTH_COVERAGE),
  152                  fp->fp.post_depth_coverage);
  153    }
  154 
  155    BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2);
  156    PUSH_DATA (push, 0x51);
  157    PUSH_DATA (push, fp->code_base);
  158    BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1);
  159    PUSH_DATA (push, fp->num_gprs);
  160 
  161    BEGIN_NVC0(push, SUBC_3D(0x0360), 2);
  162    PUSH_DATA (push, 0x20164010);
  163    PUSH_DATA (push, 0x20);
  164    BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1);
  165    PUSH_DATA (push, fp->flags[0]);
  166 }
  167 
  168 void
  169 nvc0_tctlprog_validate(struct nvc0_context *nvc0)
  170 {
  171    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  172    struct nvc0_program *tp = nvc0->tctlprog;
  173 
  174    if (tp && nvc0_program_validate(nvc0, tp)) {
  175       if (tp->tp.tess_mode != ~0) {
  176          BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
  177          PUSH_DATA (push, tp->tp.tess_mode);
  178       }
  179       BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
  180       PUSH_DATA (push, 0x21);
  181       PUSH_DATA (push, tp->code_base);
  182       BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
  183       PUSH_DATA (push, tp->num_gprs);
  184    } else {
  185       tp = nvc0->tcp_empty;
  186       /* not a whole lot we can do to handle this failure */
  187       if (!nvc0_program_validate(nvc0, tp))
  188          assert(!"unable to validate empty tcp");
  189       BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
  190       PUSH_DATA (push, 0x20);
  191       PUSH_DATA (push, tp->code_base);
  192    }
  193    nvc0_program_update_context_state(nvc0, tp, 1);
  194 }
  195 
  196 void
  197 nvc0_tevlprog_validate(struct nvc0_context *nvc0)
  198 {
  199    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  200    struct nvc0_program *tp = nvc0->tevlprog;
  201 
  202    if (tp && nvc0_program_validate(nvc0, tp)) {
  203       if (tp->tp.tess_mode != ~0) {
  204          BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
  205          PUSH_DATA (push, tp->tp.tess_mode);
  206       }
  207       BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
  208       PUSH_DATA (push, 0x31);
  209       BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1);
  210       PUSH_DATA (push, tp->code_base);
  211       BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1);
  212       PUSH_DATA (push, tp->num_gprs);
  213    } else {
  214       BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
  215       PUSH_DATA (push, 0x30);
  216    }
  217    nvc0_program_update_context_state(nvc0, tp, 2);
  218 }
  219 
  220 void
  221 nvc0_gmtyprog_validate(struct nvc0_context *nvc0)
  222 {
  223    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  224    struct nvc0_program *gp = nvc0->gmtyprog;
  225 
  226    /* we allow GPs with no code for specifying stream output state only */
  227    if (gp && nvc0_program_validate(nvc0, gp) && gp->code_size) {
  228       BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
  229       PUSH_DATA (push, 0x41);
  230       BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1);
  231       PUSH_DATA (push, gp->code_base);
  232       BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1);
  233       PUSH_DATA (push, gp->num_gprs);
  234    } else {
  235       BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
  236       PUSH_DATA (push, 0x40);
  237    }
  238    nvc0_program_update_context_state(nvc0, gp, 3);
  239 }
  240 
  241 void
  242 nvc0_compprog_validate(struct nvc0_context *nvc0)
  243 {
  244    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  245    struct nvc0_program *cp = nvc0->compprog;
  246 
  247    if (cp && !nvc0_program_validate(nvc0, cp))
  248       return;
  249 
  250    BEGIN_NVC0(push, NVC0_CP(FLUSH), 1);
  251    PUSH_DATA (push, NVC0_COMPUTE_FLUSH_CODE);
  252 }
  253 
  254 void
  255 nvc0_layer_validate(struct nvc0_context *nvc0)
  256 {
  257    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  258    struct nvc0_program *last;
  259    bool prog_selects_layer = false;
  260    bool layer_viewport_relative = false;
  261 
  262    if (nvc0->gmtyprog)
  263       last = nvc0->gmtyprog;
  264    else if (nvc0->tevlprog)
  265       last = nvc0->tevlprog;
  266    else
  267       last = nvc0->vertprog;
  268 
  269    if (last) {
  270       prog_selects_layer = !!(last->hdr[13] & (1 << 9));
  271       layer_viewport_relative = last->vp.layer_viewport_relative;
  272    }
  273 
  274    BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
  275    PUSH_DATA (push, prog_selects_layer ? NVC0_3D_LAYER_USE_GP : 0);
  276    if (nvc0->screen->eng3d->oclass >= GM200_3D_CLASS) {
  277       IMMED_NVC0(push, NVC0_3D(LAYER_VIEWPORT_RELATIVE),
  278                  layer_viewport_relative);
  279    }
  280 }
  281 
  282 void
  283 nvc0_tfb_validate(struct nvc0_context *nvc0)
  284 {
  285    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
  286    struct nvc0_transform_feedback_state *tfb;
  287    unsigned b;
  288 
  289    if (nvc0->gmtyprog) tfb = nvc0->gmtyprog->tfb;
  290    else
  291    if (nvc0->tevlprog) tfb = nvc0->tevlprog->tfb;
  292    else
  293       tfb = nvc0->vertprog->tfb;
  294 
  295    IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
  296 
  297    if (tfb && tfb != nvc0->state.tfb) {
  298       for (b = 0; b < 4; ++b) {
  299          if (tfb->varying_count[b]) {
  300             unsigned n = (tfb->varying_count[b] + 3) / 4;
  301 
  302             BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3);
  303             PUSH_DATA (push, tfb->stream[b]);
  304             PUSH_DATA (push, tfb->varying_count[b]);
  305             PUSH_DATA (push, tfb->stride[b]);
  306             BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n);
  307             PUSH_DATAp(push, tfb->varying_index[b], n);
  308 
  309             if (nvc0->tfbbuf[b])
  310                nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b];
  311          } else {
  312             IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0);
  313          }
  314       }
  315    }
  316    nvc0->state.tfb = tfb;
  317 
  318    if (!(nvc0->dirty_3d & NVC0_NEW_3D_TFB_TARGETS))
  319       return;
  320 
  321    for (b = 0; b < nvc0->num_tfbbufs; ++b) {
  322       struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]);
  323       struct nv04_resource *buf;
  324 
  325       if (targ && tfb)
  326          targ->stride = tfb->stride[b];
  327 
  328       if (!targ || !targ->stride) {
  329          IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
  330          continue;
  331       }
  332 
  333       buf = nv04_resource(targ->pipe.buffer);
  334 
  335       BCTX_REFN(nvc0->bufctx_3d, 3D_TFB, buf, WR);
  336 
  337       if (!(nvc0->tfbbuf_dirty & (1 << b)))
  338          continue;
  339 
  340       if (!targ->clean)
  341          nvc0_hw_query_fifo_wait(nvc0, nvc0_query(targ->pq));
  342       nouveau_pushbuf_space(push, 0, 0, 1);
  343       BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
  344       PUSH_DATA (push, 1);
  345       PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
  346       PUSH_DATA (push, buf->address + targ->pipe.buffer_offset);
  347       PUSH_DATA (push, targ->pipe.buffer_size);
  348       if (!targ->clean) {
  349          nvc0_hw_query_pushbuf_submit(push, nvc0_query(targ->pq), 0x4);
  350       } else {
  351          PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
  352          targ->clean = false;
  353       }
  354    }
  355    for (; b < 4; ++b)
  356       IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
  357 }