Home | History | Annotate | Download | only in state_tracker
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 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  * Authors:
     30  *   Keith Whitwell <keith (at) tungstengraphics.com>
     31  *   Brian Paul
     32  */
     33 
     34 #include "main/imports.h"
     35 #include "program/prog_parameter.h"
     36 #include "program/prog_print.h"
     37 
     38 #include "pipe/p_context.h"
     39 #include "pipe/p_defines.h"
     40 #include "util/u_inlines.h"
     41 #include "util/u_upload_mgr.h"
     42 
     43 #include "st_debug.h"
     44 #include "st_context.h"
     45 #include "st_atom.h"
     46 #include "st_atom_constbuf.h"
     47 #include "st_program.h"
     48 
     49 
     50 /**
     51  * Pass the given program parameters to the graphics pipe as a
     52  * constant buffer.
     53  * \param shader_type  either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
     54  */
     55 void st_upload_constants( struct st_context *st,
     56                           struct gl_program_parameter_list *params,
     57                           unsigned shader_type)
     58 {
     59    assert(shader_type == PIPE_SHADER_VERTEX ||
     60           shader_type == PIPE_SHADER_FRAGMENT ||
     61           shader_type == PIPE_SHADER_GEOMETRY);
     62 
     63    /* update constants */
     64    if (params && params->NumParameters) {
     65       struct pipe_constant_buffer cb;
     66       const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
     67 
     68       /* Update the constants which come from fixed-function state, such as
     69        * transformation matrices, fog factors, etc.  The rest of the values in
     70        * the parameters list are explicitly set by the user with glUniform,
     71        * glProgramParameter(), etc.
     72        */
     73       _mesa_load_state_parameters(st->ctx, params);
     74 
     75       /* We always need to get a new buffer, to keep the drivers simple and
     76        * avoid gratuitous rendering synchronization.
     77        * Let's use a user buffer to avoid an unnecessary copy.
     78        */
     79       if (st->constbuf_uploader) {
     80          cb.buffer = NULL;
     81          cb.user_buffer = NULL;
     82          u_upload_data(st->constbuf_uploader, 0, paramBytes,
     83                        params->ParameterValues, &cb.buffer_offset, &cb.buffer);
     84          u_upload_unmap(st->constbuf_uploader);
     85       } else {
     86          cb.buffer = NULL;
     87          cb.user_buffer = params->ParameterValues;
     88          cb.buffer_offset = 0;
     89       }
     90       cb.buffer_size = paramBytes;
     91 
     92       if (ST_DEBUG & DEBUG_CONSTANTS) {
     93          debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
     94                       __FUNCTION__, shader_type, params->NumParameters,
     95                       params->StateFlags);
     96          _mesa_print_parameter_list(params);
     97       }
     98 
     99       st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb);
    100       pipe_resource_reference(&cb.buffer, NULL);
    101 
    102       st->state.constants[shader_type].ptr = params->ParameterValues;
    103       st->state.constants[shader_type].size = paramBytes;
    104    }
    105    else if (st->state.constants[shader_type].ptr) {
    106       st->state.constants[shader_type].ptr = NULL;
    107       st->state.constants[shader_type].size = 0;
    108       st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
    109    }
    110 }
    111 
    112 
    113 /**
    114  * Vertex shader:
    115  */
    116 static void update_vs_constants(struct st_context *st )
    117 {
    118    struct st_vertex_program *vp = st->vp;
    119    struct gl_program_parameter_list *params = vp->Base.Base.Parameters;
    120 
    121    st_upload_constants( st, params, PIPE_SHADER_VERTEX );
    122 }
    123 
    124 
    125 const struct st_tracked_state st_update_vs_constants = {
    126    "st_update_vs_constants",				/* name */
    127    {							/* dirty */
    128       (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS),          /* mesa */
    129       ST_NEW_VERTEX_PROGRAM,				/* st */
    130    },
    131    update_vs_constants					/* update */
    132 };
    133 
    134 
    135 
    136 /**
    137  * Fragment shader:
    138  */
    139 static void update_fs_constants(struct st_context *st )
    140 {
    141    struct st_fragment_program *fp = st->fp;
    142    struct gl_program_parameter_list *params = fp->Base.Base.Parameters;
    143 
    144    st_upload_constants( st, params, PIPE_SHADER_FRAGMENT );
    145 }
    146 
    147 
    148 const struct st_tracked_state st_update_fs_constants = {
    149    "st_update_fs_constants",				/* name */
    150    {							/* dirty */
    151       (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS),          /* mesa */
    152       ST_NEW_FRAGMENT_PROGRAM,				/* st */
    153    },
    154    update_fs_constants					/* update */
    155 };
    156 
    157 /* Geometry shader:
    158  */
    159 static void update_gs_constants(struct st_context *st )
    160 {
    161    struct st_geometry_program *gp = st->gp;
    162    struct gl_program_parameter_list *params;
    163 
    164    if (gp) {
    165       params = gp->Base.Base.Parameters;
    166       st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
    167    }
    168 }
    169 
    170 const struct st_tracked_state st_update_gs_constants = {
    171    "st_update_gs_constants",				/* name */
    172    {							/* dirty */
    173       (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS),          /* mesa */
    174       ST_NEW_GEOMETRY_PROGRAM,				/* st */
    175    },
    176    update_gs_constants					/* update */
    177 };
    178