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