Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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.  * State validation for vertex/fragment shaders.
  30.  * Note that we have to delay most vertex/fragment shader translation
  31.  * until rendering time since the linkage between the vertex outputs and
  32.  * fragment inputs can vary depending on the pairing of shaders.
  33.  *
  34.  * Authors:
  35.  *   Brian Paul
  36.  */
  37.  
  38. #include "main/imports.h"
  39. #include "main/mtypes.h"
  40. #include "program/program.h"
  41.  
  42. #include "pipe/p_context.h"
  43.  
  44. #include "util/u_simple_shaders.h"
  45.  
  46. #include "cso_cache/cso_context.h"
  47.  
  48. #include "st_context.h"
  49. #include "st_atom.h"
  50. #include "st_program.h"
  51.  
  52.  
  53.  
  54. /**
  55.  * Translate fragment program if needed.
  56.  */
  57. static void
  58. translate_fp(struct st_context *st,
  59.              struct st_fragment_program *stfp)
  60. {
  61.    if (!stfp->tgsi.tokens) {
  62.       assert(stfp->Base.Base.NumInstructions > 0);
  63.  
  64.       st_translate_fragment_program(st, stfp);
  65.    }
  66. }
  67.  
  68. /*
  69.  * Translate geometry program if needed.
  70.  */
  71. static void
  72. translate_gp(struct st_context *st,
  73.              struct st_geometry_program *stgp)
  74. {
  75.    if (!stgp->tgsi.tokens) {
  76.       assert(stgp->Base.Base.NumInstructions > 1);
  77.  
  78.       st_translate_geometry_program(st, stgp);
  79.    }
  80. }
  81.  
  82. /**
  83.  * Find a translated vertex program that corresponds to stvp and
  84.  * has outputs matched to stfp's inputs.
  85.  * This performs vertex and fragment translation (to TGSI) when needed.
  86.  */
  87. static struct st_vp_varient *
  88. find_translated_vp(struct st_context *st,
  89.                    struct st_vertex_program *stvp )
  90. {
  91.    struct st_vp_varient *vpv;
  92.    struct st_vp_varient_key key;
  93.  
  94.    /* Nothing in our key yet.  This will change:
  95.     */
  96.    memset(&key, 0, sizeof key);
  97.  
  98.    /* When this is true, we will add an extra input to the vertex
  99.     * shader translation (for edgeflags), an extra output with
  100.     * edgeflag semantics, and extend the vertex shader to pass through
  101.     * the input to the output.  We'll need to use similar logic to set
  102.     * up the extra vertex_element input for edgeflags.
  103.     * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
  104.     */
  105.    key.passthrough_edgeflags = (st->vertdata_edgeflags && (
  106.                                 st->ctx->Polygon.FrontMode != GL_FILL ||
  107.                                 st->ctx->Polygon.BackMode != GL_FILL));
  108.  
  109.  
  110.    /* Do we need to throw away old translations after a change in the
  111.     * GL program string?
  112.     */
  113.    if (stvp->serialNo != stvp->lastSerialNo) {
  114.       /* These may have changed if the program string changed.
  115.        */
  116.       st_prepare_vertex_program( st, stvp );
  117.  
  118.       /* We are now up-to-date:
  119.        */
  120.       stvp->lastSerialNo = stvp->serialNo;
  121.    }
  122.    
  123.    /* See if we've got a translated vertex program whose outputs match
  124.     * the fragment program's inputs.
  125.     */
  126.    for (vpv = stvp->varients; vpv; vpv = vpv->next) {
  127.       if (memcmp(&vpv->key, &key, sizeof key) == 0) {
  128.          break;
  129.       }
  130.    }
  131.  
  132.    /* No?  Perform new translation here. */
  133.    if (!vpv) {
  134.       vpv = st_translate_vertex_program(st, stvp, &key);
  135.       if (!vpv)
  136.          return NULL;
  137.      
  138.       vpv->next = stvp->varients;
  139.       stvp->varients = vpv;
  140.    }
  141.  
  142.    return vpv;
  143. }
  144.  
  145.  
  146. /**
  147.  * Return pointer to a pass-through fragment shader.
  148.  * This shader is used when a texture is missing/incomplete.
  149.  */
  150. static void *
  151. get_passthrough_fs(struct st_context *st)
  152. {
  153.    if (!st->passthrough_fs) {
  154.       st->passthrough_fs =
  155.          util_make_fragment_passthrough_shader(st->pipe);
  156.    }
  157.  
  158.    return st->passthrough_fs;
  159. }
  160.  
  161.  
  162. /**
  163.  * Update fragment program state/atom.  This involves translating the
  164.  * Mesa fragment program into a gallium fragment program and binding it.
  165.  */
  166. static void
  167. update_fp( struct st_context *st )
  168. {
  169.    struct st_fragment_program *stfp;
  170.  
  171.    assert(st->ctx->FragmentProgram._Current);
  172.    stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
  173.    assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
  174.  
  175.    translate_fp(st, stfp);
  176.  
  177.    st_reference_fragprog(st, &st->fp, stfp);
  178.  
  179.    if (st->missing_textures) {
  180.       /* use a pass-through frag shader that uses no textures */
  181.       void *fs = get_passthrough_fs(st);
  182.       cso_set_fragment_shader_handle(st->cso_context, fs);
  183.    }
  184.    else {
  185.       cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
  186.    }
  187. }
  188.  
  189.  
  190. const struct st_tracked_state st_update_fp = {
  191.    "st_update_fp",                                      /* name */
  192.    {                                                    /* dirty */
  193.       0,                                                /* mesa */
  194.       ST_NEW_FRAGMENT_PROGRAM                           /* st */
  195.    },
  196.    update_fp                                    /* update */
  197. };
  198.  
  199.  
  200.  
  201. /**
  202.  * Update vertex program state/atom.  This involves translating the
  203.  * Mesa vertex program into a gallium fragment program and binding it.
  204.  */
  205. static void
  206. update_vp( struct st_context *st )
  207. {
  208.    struct st_vertex_program *stvp;
  209.  
  210.    /* find active shader and params -- Should be covered by
  211.     * ST_NEW_VERTEX_PROGRAM
  212.     */
  213.    assert(st->ctx->VertexProgram._Current);
  214.    stvp = st_vertex_program(st->ctx->VertexProgram._Current);
  215.    assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
  216.  
  217.    st->vp_varient = find_translated_vp(st, stvp);
  218.  
  219.    st_reference_vertprog(st, &st->vp, stvp);
  220.  
  221.    cso_set_vertex_shader_handle(st->cso_context,
  222.                                 st->vp_varient->driver_shader);
  223.  
  224.    st->vertex_result_to_slot = stvp->result_to_output;
  225. }
  226.  
  227.  
  228. const struct st_tracked_state st_update_vp = {
  229.    "st_update_vp",                                      /* name */
  230.    {                                                    /* dirty */
  231.       _NEW_POLYGON,                                     /* mesa */
  232.       ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA     /* st */
  233.    },
  234.    update_vp                                    /* update */
  235. };
  236.  
  237. static void
  238. update_gp( struct st_context *st )
  239. {
  240.  
  241.    struct st_geometry_program *stgp;
  242.  
  243.    if (!st->ctx->GeometryProgram._Current) {
  244.       cso_set_geometry_shader_handle(st->cso_context, NULL);
  245.       return;
  246.    }
  247.  
  248.    stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
  249.    assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
  250.  
  251.    translate_gp(st, stgp);
  252.  
  253.    st_reference_geomprog(st, &st->gp, stgp);
  254.  
  255.    cso_set_geometry_shader_handle(st->cso_context, stgp->driver_shader);
  256. }
  257.  
  258. const struct st_tracked_state st_update_gp = {
  259.    "st_update_gp",                                      /* name */
  260.    {                                                    /* dirty */
  261.       0,                                                /* mesa */
  262.       ST_NEW_GEOMETRY_PROGRAM                           /* st */
  263.    },
  264.    update_gp                                    /* update */
  265. };
  266.