1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker /**
26*61046927SAndroid Build Coastguard Worker * \file arbprogram.c
27*61046927SAndroid Build Coastguard Worker * ARB_vertex/fragment_program state management functions.
28*61046927SAndroid Build Coastguard Worker * \author Brian Paul
29*61046927SAndroid Build Coastguard Worker */
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
33*61046927SAndroid Build Coastguard Worker #include "main/context.h"
34*61046927SAndroid Build Coastguard Worker #include "main/draw_validate.h"
35*61046927SAndroid Build Coastguard Worker #include "main/hash.h"
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker #include "main/macros.h"
38*61046927SAndroid Build Coastguard Worker #include "main/mtypes.h"
39*61046927SAndroid Build Coastguard Worker #include "main/shaderapi.h"
40*61046927SAndroid Build Coastguard Worker #include "main/state.h"
41*61046927SAndroid Build Coastguard Worker #include "program/arbprogparse.h"
42*61046927SAndroid Build Coastguard Worker #include "program/program.h"
43*61046927SAndroid Build Coastguard Worker #include "program/prog_print.h"
44*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_program.h"
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker static void
flush_vertices_for_program_constants(struct gl_context * ctx,GLenum target)49*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(struct gl_context *ctx, GLenum target)
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker uint64_t new_driver_state;
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker if (target == GL_FRAGMENT_PROGRAM_ARB) {
54*61046927SAndroid Build Coastguard Worker new_driver_state =
55*61046927SAndroid Build Coastguard Worker ctx->DriverFlags.NewShaderConstants[MESA_SHADER_FRAGMENT];
56*61046927SAndroid Build Coastguard Worker } else {
57*61046927SAndroid Build Coastguard Worker new_driver_state =
58*61046927SAndroid Build Coastguard Worker ctx->DriverFlags.NewShaderConstants[MESA_SHADER_VERTEX];
59*61046927SAndroid Build Coastguard Worker }
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS, 0);
62*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= new_driver_state;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker static struct gl_program*
lookup_or_create_program(GLuint id,GLenum target,const char * caller)66*61046927SAndroid Build Coastguard Worker lookup_or_create_program(GLuint id, GLenum target, const char* caller)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
69*61046927SAndroid Build Coastguard Worker struct gl_program* newProg;
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker if (id == 0) {
72*61046927SAndroid Build Coastguard Worker /* Bind a default program */
73*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB)
74*61046927SAndroid Build Coastguard Worker newProg = ctx->Shared->DefaultVertexProgram;
75*61046927SAndroid Build Coastguard Worker else
76*61046927SAndroid Build Coastguard Worker newProg = ctx->Shared->DefaultFragmentProgram;
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker else {
79*61046927SAndroid Build Coastguard Worker /* Bind a user program */
80*61046927SAndroid Build Coastguard Worker newProg = _mesa_lookup_program(ctx, id);
81*61046927SAndroid Build Coastguard Worker if (!newProg || newProg == &_mesa_DummyProgram) {
82*61046927SAndroid Build Coastguard Worker /* allocate a new program now */
83*61046927SAndroid Build Coastguard Worker newProg = ctx->Driver.NewProgram(ctx, _mesa_program_enum_to_shader_stage(target),
84*61046927SAndroid Build Coastguard Worker id, true);
85*61046927SAndroid Build Coastguard Worker if (!newProg) {
86*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
87*61046927SAndroid Build Coastguard Worker return NULL;
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker _mesa_HashInsert(&ctx->Shared->Programs, id, newProg);
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker else if (newProg->Target != target) {
92*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
93*61046927SAndroid Build Coastguard Worker "%s(target mismatch)", caller);
94*61046927SAndroid Build Coastguard Worker return NULL;
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker }
97*61046927SAndroid Build Coastguard Worker return newProg;
98*61046927SAndroid Build Coastguard Worker }
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker /**
101*61046927SAndroid Build Coastguard Worker * Bind a program (make it current)
102*61046927SAndroid Build Coastguard Worker * \note Called from the GL API dispatcher by both glBindProgramNV
103*61046927SAndroid Build Coastguard Worker * and glBindProgramARB.
104*61046927SAndroid Build Coastguard Worker */
105*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindProgramARB(GLenum target,GLuint id)106*61046927SAndroid Build Coastguard Worker _mesa_BindProgramARB(GLenum target, GLuint id)
107*61046927SAndroid Build Coastguard Worker {
108*61046927SAndroid Build Coastguard Worker struct gl_program *curProg, *newProg;
109*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker /* Error-check target and get curProg */
112*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) {
113*61046927SAndroid Build Coastguard Worker curProg = ctx->VertexProgram.Current;
114*61046927SAndroid Build Coastguard Worker }
115*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB
116*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
117*61046927SAndroid Build Coastguard Worker curProg = ctx->FragmentProgram.Current;
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker else {
120*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramARB(target)");
121*61046927SAndroid Build Coastguard Worker return;
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker /*
125*61046927SAndroid Build Coastguard Worker * Get pointer to new program to bind.
126*61046927SAndroid Build Coastguard Worker * NOTE: binding to a non-existant program is not an error.
127*61046927SAndroid Build Coastguard Worker * That's supposed to be caught in glBegin.
128*61046927SAndroid Build Coastguard Worker */
129*61046927SAndroid Build Coastguard Worker newProg = lookup_or_create_program(id, target, "glBindProgram");
130*61046927SAndroid Build Coastguard Worker if (!newProg)
131*61046927SAndroid Build Coastguard Worker return;
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker /** All error checking is complete now **/
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker if (curProg->Id == id) {
136*61046927SAndroid Build Coastguard Worker /* binding same program - no change */
137*61046927SAndroid Build Coastguard Worker return;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker /* signal new program (and its new constants) */
141*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_PROGRAM, 0);
142*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker /* bind newProg */
145*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB) {
146*61046927SAndroid Build Coastguard Worker _mesa_reference_program(ctx, &ctx->VertexProgram.Current, newProg);
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB) {
149*61046927SAndroid Build Coastguard Worker _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, newProg);
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker _mesa_update_vertex_processing_mode(ctx);
153*61046927SAndroid Build Coastguard Worker _mesa_update_valid_to_render_state(ctx);
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker /* Never null pointers */
156*61046927SAndroid Build Coastguard Worker assert(ctx->VertexProgram.Current);
157*61046927SAndroid Build Coastguard Worker assert(ctx->FragmentProgram.Current);
158*61046927SAndroid Build Coastguard Worker }
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker /**
162*61046927SAndroid Build Coastguard Worker * Delete a list of programs.
163*61046927SAndroid Build Coastguard Worker * \note Not compiled into display lists.
164*61046927SAndroid Build Coastguard Worker * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
165*61046927SAndroid Build Coastguard Worker */
166*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DeleteProgramsARB(GLsizei n,const GLuint * ids)167*61046927SAndroid Build Coastguard Worker _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids)
168*61046927SAndroid Build Coastguard Worker {
169*61046927SAndroid Build Coastguard Worker GLint i;
170*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker if (n < 0) {
175*61046927SAndroid Build Coastguard Worker _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" );
176*61046927SAndroid Build Coastguard Worker return;
177*61046927SAndroid Build Coastguard Worker }
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
180*61046927SAndroid Build Coastguard Worker if (ids[i] != 0) {
181*61046927SAndroid Build Coastguard Worker struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]);
182*61046927SAndroid Build Coastguard Worker if (prog == &_mesa_DummyProgram) {
183*61046927SAndroid Build Coastguard Worker _mesa_HashRemove(&ctx->Shared->Programs, ids[i]);
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker else if (prog) {
186*61046927SAndroid Build Coastguard Worker /* Unbind program if necessary */
187*61046927SAndroid Build Coastguard Worker switch (prog->Target) {
188*61046927SAndroid Build Coastguard Worker case GL_VERTEX_PROGRAM_ARB:
189*61046927SAndroid Build Coastguard Worker if (ctx->VertexProgram.Current &&
190*61046927SAndroid Build Coastguard Worker ctx->VertexProgram.Current->Id == ids[i]) {
191*61046927SAndroid Build Coastguard Worker /* unbind this currently bound program */
192*61046927SAndroid Build Coastguard Worker _mesa_BindProgramARB(prog->Target, 0);
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker break;
195*61046927SAndroid Build Coastguard Worker case GL_FRAGMENT_PROGRAM_ARB:
196*61046927SAndroid Build Coastguard Worker if (ctx->FragmentProgram.Current &&
197*61046927SAndroid Build Coastguard Worker ctx->FragmentProgram.Current->Id == ids[i]) {
198*61046927SAndroid Build Coastguard Worker /* unbind this currently bound program */
199*61046927SAndroid Build Coastguard Worker _mesa_BindProgramARB(prog->Target, 0);
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker break;
202*61046927SAndroid Build Coastguard Worker default:
203*61046927SAndroid Build Coastguard Worker _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
204*61046927SAndroid Build Coastguard Worker return;
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker /* The ID is immediately available for re-use now */
207*61046927SAndroid Build Coastguard Worker _mesa_HashRemove(&ctx->Shared->Programs, ids[i]);
208*61046927SAndroid Build Coastguard Worker _mesa_reference_program(ctx, &prog, NULL);
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker
215*61046927SAndroid Build Coastguard Worker /**
216*61046927SAndroid Build Coastguard Worker * Generate a list of new program identifiers.
217*61046927SAndroid Build Coastguard Worker * \note Not compiled into display lists.
218*61046927SAndroid Build Coastguard Worker * \note Called by both glGenProgramsNV and glGenProgramsARB.
219*61046927SAndroid Build Coastguard Worker */
220*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenProgramsARB(GLsizei n,GLuint * ids)221*61046927SAndroid Build Coastguard Worker _mesa_GenProgramsARB(GLsizei n, GLuint *ids)
222*61046927SAndroid Build Coastguard Worker {
223*61046927SAndroid Build Coastguard Worker GLuint i;
224*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Worker if (n < 0) {
227*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
228*61046927SAndroid Build Coastguard Worker return;
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker if (!ids)
232*61046927SAndroid Build Coastguard Worker return;
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->Programs);
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeys(&ctx->Shared->Programs, ids, n);
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker /* Insert pointer to dummy program as placeholder */
239*61046927SAndroid Build Coastguard Worker for (i = 0; i < (GLuint) n; i++) {
240*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->Programs, ids[i],
241*61046927SAndroid Build Coastguard Worker &_mesa_DummyProgram);
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->Programs);
245*61046927SAndroid Build Coastguard Worker }
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker /**
249*61046927SAndroid Build Coastguard Worker * Determine if id names a vertex or fragment program.
250*61046927SAndroid Build Coastguard Worker * \note Not compiled into display lists.
251*61046927SAndroid Build Coastguard Worker * \note Called from both glIsProgramNV and glIsProgramARB.
252*61046927SAndroid Build Coastguard Worker * \param id is the program identifier
253*61046927SAndroid Build Coastguard Worker * \return GL_TRUE if id is a program, else GL_FALSE.
254*61046927SAndroid Build Coastguard Worker */
255*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_IsProgramARB(GLuint id)256*61046927SAndroid Build Coastguard Worker _mesa_IsProgramARB(GLuint id)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker struct gl_program *prog = NULL;
259*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
260*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker if (id == 0)
263*61046927SAndroid Build Coastguard Worker return GL_FALSE;
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker prog = _mesa_lookup_program(ctx, id);
266*61046927SAndroid Build Coastguard Worker if (prog && (prog != &_mesa_DummyProgram))
267*61046927SAndroid Build Coastguard Worker return GL_TRUE;
268*61046927SAndroid Build Coastguard Worker else
269*61046927SAndroid Build Coastguard Worker return GL_FALSE;
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker static struct gl_program*
get_current_program(struct gl_context * ctx,GLenum target,const char * caller)273*61046927SAndroid Build Coastguard Worker get_current_program(struct gl_context* ctx, GLenum target, const char* caller)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB
276*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_vertex_program) {
277*61046927SAndroid Build Coastguard Worker return ctx->VertexProgram.Current;
278*61046927SAndroid Build Coastguard Worker }
279*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB
280*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
281*61046927SAndroid Build Coastguard Worker return ctx->FragmentProgram.Current;
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker else {
284*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
285*61046927SAndroid Build Coastguard Worker "%s(target)", caller);
286*61046927SAndroid Build Coastguard Worker return NULL;
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker static GLboolean
get_local_param_pointer(struct gl_context * ctx,const char * func,struct gl_program * prog,GLenum target,GLuint index,unsigned count,GLfloat ** param)291*61046927SAndroid Build Coastguard Worker get_local_param_pointer(struct gl_context *ctx, const char *func,
292*61046927SAndroid Build Coastguard Worker struct gl_program* prog, GLenum target,
293*61046927SAndroid Build Coastguard Worker GLuint index, unsigned count, GLfloat **param)
294*61046927SAndroid Build Coastguard Worker {
295*61046927SAndroid Build Coastguard Worker if (unlikely(index + count > prog->arb.MaxLocalParams)) {
296*61046927SAndroid Build Coastguard Worker /* If arb.MaxLocalParams == 0, we need to do initialization. */
297*61046927SAndroid Build Coastguard Worker if (!prog->arb.MaxLocalParams) {
298*61046927SAndroid Build Coastguard Worker unsigned max;
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB)
301*61046927SAndroid Build Coastguard Worker max = ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams;
302*61046927SAndroid Build Coastguard Worker else
303*61046927SAndroid Build Coastguard Worker max = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams;
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker /* Allocate LocalParams. */
306*61046927SAndroid Build Coastguard Worker if (!prog->arb.LocalParams) {
307*61046927SAndroid Build Coastguard Worker prog->arb.LocalParams = rzalloc_array_size(prog, sizeof(float[4]),
308*61046927SAndroid Build Coastguard Worker max);
309*61046927SAndroid Build Coastguard Worker if (!prog->arb.LocalParams) {
310*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
311*61046927SAndroid Build Coastguard Worker return GL_FALSE;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker /* Initialize MaxLocalParams. */
316*61046927SAndroid Build Coastguard Worker prog->arb.MaxLocalParams = max;
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker /* Check again after initializing MaxLocalParams. */
320*61046927SAndroid Build Coastguard Worker if (index + count > prog->arb.MaxLocalParams) {
321*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
322*61046927SAndroid Build Coastguard Worker return GL_FALSE;
323*61046927SAndroid Build Coastguard Worker }
324*61046927SAndroid Build Coastguard Worker }
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker *param = prog->arb.LocalParams[index];
327*61046927SAndroid Build Coastguard Worker return GL_TRUE;
328*61046927SAndroid Build Coastguard Worker }
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker static GLboolean
get_env_param_pointer(struct gl_context * ctx,const char * func,GLenum target,GLuint index,GLfloat ** param)332*61046927SAndroid Build Coastguard Worker get_env_param_pointer(struct gl_context *ctx, const char *func,
333*61046927SAndroid Build Coastguard Worker GLenum target, GLuint index, GLfloat **param)
334*61046927SAndroid Build Coastguard Worker {
335*61046927SAndroid Build Coastguard Worker if (target == GL_FRAGMENT_PROGRAM_ARB
336*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
337*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) {
338*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
339*61046927SAndroid Build Coastguard Worker return GL_FALSE;
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker *param = ctx->FragmentProgram.Parameters[index];
342*61046927SAndroid Build Coastguard Worker return GL_TRUE;
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker else if (target == GL_VERTEX_PROGRAM_ARB &&
345*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_vertex_program) {
346*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) {
347*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
348*61046927SAndroid Build Coastguard Worker return GL_FALSE;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker *param = ctx->VertexProgram.Parameters[index];
351*61046927SAndroid Build Coastguard Worker return GL_TRUE;
352*61046927SAndroid Build Coastguard Worker } else {
353*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
354*61046927SAndroid Build Coastguard Worker return GL_FALSE;
355*61046927SAndroid Build Coastguard Worker }
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker static void
set_program_string(struct gl_program * prog,GLenum target,GLenum format,GLsizei len,const GLvoid * string)359*61046927SAndroid Build Coastguard Worker set_program_string(struct gl_program *prog, GLenum target, GLenum format, GLsizei len,
360*61046927SAndroid Build Coastguard Worker const GLvoid *string)
361*61046927SAndroid Build Coastguard Worker {
362*61046927SAndroid Build Coastguard Worker bool failed;
363*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, _NEW_PROGRAM, 0);
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_vertex_program
368*61046927SAndroid Build Coastguard Worker && !ctx->Extensions.ARB_fragment_program) {
369*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()");
370*61046927SAndroid Build Coastguard Worker return;
371*61046927SAndroid Build Coastguard Worker }
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
374*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
375*61046927SAndroid Build Coastguard Worker return;
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker #ifdef ENABLE_SHADER_CACHE
379*61046927SAndroid Build Coastguard Worker GLcharARB *replacement;
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = _mesa_program_enum_to_shader_stage(target);
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker blake3_hash blake3;
384*61046927SAndroid Build Coastguard Worker _mesa_blake3_compute(string, len, blake3);
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
387*61046927SAndroid Build Coastguard Worker * if corresponding entry found from MESA_SHADER_READ_PATH.
388*61046927SAndroid Build Coastguard Worker */
389*61046927SAndroid Build Coastguard Worker _mesa_dump_shader_source(stage, string, blake3);
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker replacement = _mesa_read_shader_source(stage, string, blake3);
392*61046927SAndroid Build Coastguard Worker if (replacement)
393*61046927SAndroid Build Coastguard Worker string = replacement;
394*61046927SAndroid Build Coastguard Worker #endif /* ENABLE_SHADER_CACHE */
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) {
397*61046927SAndroid Build Coastguard Worker _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB
400*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
401*61046927SAndroid Build Coastguard Worker _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker else {
404*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
405*61046927SAndroid Build Coastguard Worker #ifdef ENABLE_SHADER_CACHE
406*61046927SAndroid Build Coastguard Worker free(replacement);
407*61046927SAndroid Build Coastguard Worker #endif
408*61046927SAndroid Build Coastguard Worker return;
409*61046927SAndroid Build Coastguard Worker }
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker failed = ctx->Program.ErrorPos != -1;
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker if (!failed) {
414*61046927SAndroid Build Coastguard Worker /* finally, give the program to the driver for translation/checking */
415*61046927SAndroid Build Coastguard Worker if (!st_program_string_notify(ctx, target, prog)) {
416*61046927SAndroid Build Coastguard Worker failed = true;
417*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
418*61046927SAndroid Build Coastguard Worker "glProgramStringARB(rejected by driver");
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker }
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker _mesa_update_vertex_processing_mode(ctx);
423*61046927SAndroid Build Coastguard Worker _mesa_update_valid_to_render_state(ctx);
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker if (ctx->_Shader->Flags & GLSL_DUMP) {
426*61046927SAndroid Build Coastguard Worker const char *shader_type =
427*61046927SAndroid Build Coastguard Worker target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker fprintf(stderr, "ARB_%s_program source for program %d:\n",
430*61046927SAndroid Build Coastguard Worker shader_type, prog->Id);
431*61046927SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", (const char *) string);
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker if (failed) {
434*61046927SAndroid Build Coastguard Worker fprintf(stderr, "ARB_%s_program %d failed to compile.\n",
435*61046927SAndroid Build Coastguard Worker shader_type, prog->Id);
436*61046927SAndroid Build Coastguard Worker } else {
437*61046927SAndroid Build Coastguard Worker fprintf(stderr, "Mesa IR for ARB_%s_program %d:\n",
438*61046927SAndroid Build Coastguard Worker shader_type, prog->Id);
439*61046927SAndroid Build Coastguard Worker _mesa_print_program(prog);
440*61046927SAndroid Build Coastguard Worker fprintf(stderr, "\n");
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker fflush(stderr);
443*61046927SAndroid Build Coastguard Worker }
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker /* Capture vp-*.shader_test/fp-*.shader_test files. */
446*61046927SAndroid Build Coastguard Worker const char *capture_path = _mesa_get_shader_capture_path();
447*61046927SAndroid Build Coastguard Worker if (capture_path != NULL) {
448*61046927SAndroid Build Coastguard Worker FILE *file;
449*61046927SAndroid Build Coastguard Worker const char *shader_type =
450*61046927SAndroid Build Coastguard Worker target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
451*61046927SAndroid Build Coastguard Worker char *filename =
452*61046927SAndroid Build Coastguard Worker ralloc_asprintf(NULL, "%s/%cp-%u.shader_test",
453*61046927SAndroid Build Coastguard Worker capture_path, shader_type[0], prog->Id);
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker file = fopen(filename, "w");
456*61046927SAndroid Build Coastguard Worker if (file) {
457*61046927SAndroid Build Coastguard Worker fprintf(file,
458*61046927SAndroid Build Coastguard Worker "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n",
459*61046927SAndroid Build Coastguard Worker shader_type, shader_type, (const char *) string);
460*61046927SAndroid Build Coastguard Worker fclose(file);
461*61046927SAndroid Build Coastguard Worker } else {
462*61046927SAndroid Build Coastguard Worker _mesa_warning(ctx, "Failed to open %s", filename);
463*61046927SAndroid Build Coastguard Worker }
464*61046927SAndroid Build Coastguard Worker ralloc_free(filename);
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker #ifdef ENABLE_SHADER_CACHE
467*61046927SAndroid Build Coastguard Worker free(replacement);
468*61046927SAndroid Build Coastguard Worker #endif
469*61046927SAndroid Build Coastguard Worker }
470*61046927SAndroid Build Coastguard Worker
471*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramStringARB(GLenum target,GLenum format,GLsizei len,const GLvoid * string)472*61046927SAndroid Build Coastguard Worker _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
473*61046927SAndroid Build Coastguard Worker const GLvoid *string)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
476*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) {
477*61046927SAndroid Build Coastguard Worker set_program_string(ctx->VertexProgram.Current, target, format, len, string);
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB
480*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
481*61046927SAndroid Build Coastguard Worker set_program_string(ctx->FragmentProgram.Current, target, format, len, string);
482*61046927SAndroid Build Coastguard Worker }
483*61046927SAndroid Build Coastguard Worker else {
484*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
485*61046927SAndroid Build Coastguard Worker return;
486*61046927SAndroid Build Coastguard Worker }
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramStringEXT(GLuint program,GLenum target,GLenum format,GLsizei len,const GLvoid * string)490*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei len,
491*61046927SAndroid Build Coastguard Worker const GLvoid *string)
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker struct gl_program* prog = lookup_or_create_program(program, target, "glNamedProgramStringEXT");
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker if (!prog) {
496*61046927SAndroid Build Coastguard Worker return;
497*61046927SAndroid Build Coastguard Worker }
498*61046927SAndroid Build Coastguard Worker set_program_string(prog, target, format, len, string);
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker /**
503*61046927SAndroid Build Coastguard Worker * Set a program env parameter register.
504*61046927SAndroid Build Coastguard Worker * \note Called from the GL API dispatcher.
505*61046927SAndroid Build Coastguard Worker */
506*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramEnvParameter4dARB(GLenum target,GLuint index,GLdouble x,GLdouble y,GLdouble z,GLdouble w)507*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
508*61046927SAndroid Build Coastguard Worker GLdouble x, GLdouble y, GLdouble z, GLdouble w)
509*61046927SAndroid Build Coastguard Worker {
510*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
511*61046927SAndroid Build Coastguard Worker (GLfloat) z, (GLfloat) w);
512*61046927SAndroid Build Coastguard Worker }
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker /**
516*61046927SAndroid Build Coastguard Worker * Set a program env parameter register.
517*61046927SAndroid Build Coastguard Worker * \note Called from the GL API dispatcher.
518*61046927SAndroid Build Coastguard Worker */
519*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramEnvParameter4dvARB(GLenum target,GLuint index,const GLdouble * params)520*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
521*61046927SAndroid Build Coastguard Worker const GLdouble *params)
522*61046927SAndroid Build Coastguard Worker {
523*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0],
524*61046927SAndroid Build Coastguard Worker (GLfloat) params[1], (GLfloat) params[2],
525*61046927SAndroid Build Coastguard Worker (GLfloat) params[3]);
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker /**
530*61046927SAndroid Build Coastguard Worker * Set a program env parameter register.
531*61046927SAndroid Build Coastguard Worker * \note Called from the GL API dispatcher.
532*61046927SAndroid Build Coastguard Worker */
533*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramEnvParameter4fARB(GLenum target,GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)534*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
535*61046927SAndroid Build Coastguard Worker GLfloat x, GLfloat y, GLfloat z, GLfloat w)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker GLfloat *param;
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
540*61046927SAndroid Build Coastguard Worker
541*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker if (get_env_param_pointer(ctx, "glProgramEnvParameter",
544*61046927SAndroid Build Coastguard Worker target, index, ¶m)) {
545*61046927SAndroid Build Coastguard Worker ASSIGN_4V(param, x, y, z, w);
546*61046927SAndroid Build Coastguard Worker }
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker /**
552*61046927SAndroid Build Coastguard Worker * Set a program env parameter register.
553*61046927SAndroid Build Coastguard Worker * \note Called from the GL API dispatcher.
554*61046927SAndroid Build Coastguard Worker */
555*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramEnvParameter4fvARB(GLenum target,GLuint index,const GLfloat * params)556*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
557*61046927SAndroid Build Coastguard Worker const GLfloat *params)
558*61046927SAndroid Build Coastguard Worker {
559*61046927SAndroid Build Coastguard Worker GLfloat *param;
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker if (get_env_param_pointer(ctx, "glProgramEnvParameter4fv",
566*61046927SAndroid Build Coastguard Worker target, index, ¶m)) {
567*61046927SAndroid Build Coastguard Worker memcpy(param, params, 4 * sizeof(GLfloat));
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker
572*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramEnvParameters4fvEXT(GLenum target,GLuint index,GLsizei count,const GLfloat * params)573*61046927SAndroid Build Coastguard Worker _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
574*61046927SAndroid Build Coastguard Worker const GLfloat *params)
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
577*61046927SAndroid Build Coastguard Worker GLfloat * dest;
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker if (count <= 0) {
582*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker
585*61046927SAndroid Build Coastguard Worker if (target == GL_FRAGMENT_PROGRAM_ARB
586*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_fragment_program) {
587*61046927SAndroid Build Coastguard Worker if ((index + count) > ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) {
588*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
589*61046927SAndroid Build Coastguard Worker return;
590*61046927SAndroid Build Coastguard Worker }
591*61046927SAndroid Build Coastguard Worker dest = ctx->FragmentProgram.Parameters[index];
592*61046927SAndroid Build Coastguard Worker }
593*61046927SAndroid Build Coastguard Worker else if (target == GL_VERTEX_PROGRAM_ARB
594*61046927SAndroid Build Coastguard Worker && ctx->Extensions.ARB_vertex_program) {
595*61046927SAndroid Build Coastguard Worker if ((index + count) > ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) {
596*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
597*61046927SAndroid Build Coastguard Worker return;
598*61046927SAndroid Build Coastguard Worker }
599*61046927SAndroid Build Coastguard Worker dest = ctx->VertexProgram.Parameters[index];
600*61046927SAndroid Build Coastguard Worker }
601*61046927SAndroid Build Coastguard Worker else {
602*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
603*61046927SAndroid Build Coastguard Worker return;
604*61046927SAndroid Build Coastguard Worker }
605*61046927SAndroid Build Coastguard Worker
606*61046927SAndroid Build Coastguard Worker memcpy(dest, params, count * 4 * sizeof(GLfloat));
607*61046927SAndroid Build Coastguard Worker }
608*61046927SAndroid Build Coastguard Worker
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramEnvParameterdvARB(GLenum target,GLuint index,GLdouble * params)611*61046927SAndroid Build Coastguard Worker _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
612*61046927SAndroid Build Coastguard Worker GLdouble *params)
613*61046927SAndroid Build Coastguard Worker {
614*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
615*61046927SAndroid Build Coastguard Worker GLfloat *fparam;
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker if (get_env_param_pointer(ctx, "glGetProgramEnvParameterdv",
618*61046927SAndroid Build Coastguard Worker target, index, &fparam)) {
619*61046927SAndroid Build Coastguard Worker COPY_4V(params, fparam);
620*61046927SAndroid Build Coastguard Worker }
621*61046927SAndroid Build Coastguard Worker }
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker
624*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramEnvParameterfvARB(GLenum target,GLuint index,GLfloat * params)625*61046927SAndroid Build Coastguard Worker _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
626*61046927SAndroid Build Coastguard Worker GLfloat *params)
627*61046927SAndroid Build Coastguard Worker {
628*61046927SAndroid Build Coastguard Worker GLfloat *param;
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker if (get_env_param_pointer(ctx, "glGetProgramEnvParameterfv",
633*61046927SAndroid Build Coastguard Worker target, index, ¶m)) {
634*61046927SAndroid Build Coastguard Worker COPY_4V(params, param);
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramLocalParameter4fARB(GLenum target,GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)640*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
641*61046927SAndroid Build Coastguard Worker GLfloat x, GLfloat y, GLfloat z, GLfloat w)
642*61046927SAndroid Build Coastguard Worker {
643*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
644*61046927SAndroid Build Coastguard Worker GLfloat *param;
645*61046927SAndroid Build Coastguard Worker struct gl_program* prog = get_current_program(ctx, target, "glProgramLocalParameterARB");
646*61046927SAndroid Build Coastguard Worker if (!prog) {
647*61046927SAndroid Build Coastguard Worker return;
648*61046927SAndroid Build Coastguard Worker }
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
651*61046927SAndroid Build Coastguard Worker
652*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glProgramLocalParameterARB",
653*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
654*61046927SAndroid Build Coastguard Worker assert(index < MAX_PROGRAM_LOCAL_PARAMS);
655*61046927SAndroid Build Coastguard Worker ASSIGN_4V(param, x, y, z, w);
656*61046927SAndroid Build Coastguard Worker }
657*61046927SAndroid Build Coastguard Worker }
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramLocalParameter4fEXT(GLuint program,GLenum target,GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)660*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index,
661*61046927SAndroid Build Coastguard Worker GLfloat x, GLfloat y, GLfloat z, GLfloat w)
662*61046927SAndroid Build Coastguard Worker {
663*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
664*61046927SAndroid Build Coastguard Worker GLfloat *param;
665*61046927SAndroid Build Coastguard Worker struct gl_program* prog = lookup_or_create_program(program, target,
666*61046927SAndroid Build Coastguard Worker "glNamedProgramLocalParameter4fEXT");
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker if (!prog) {
669*61046927SAndroid Build Coastguard Worker return;
670*61046927SAndroid Build Coastguard Worker }
671*61046927SAndroid Build Coastguard Worker
672*61046927SAndroid Build Coastguard Worker if ((target == GL_VERTEX_PROGRAM_ARB && prog == ctx->VertexProgram.Current) ||
673*61046927SAndroid Build Coastguard Worker (target == GL_FRAGMENT_PROGRAM_ARB && prog == ctx->FragmentProgram.Current)) {
674*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, target);
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glNamedProgramLocalParameter4fEXT",
678*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
679*61046927SAndroid Build Coastguard Worker assert(index < MAX_PROGRAM_LOCAL_PARAMS);
680*61046927SAndroid Build Coastguard Worker ASSIGN_4V(param, x, y, z, w);
681*61046927SAndroid Build Coastguard Worker }
682*61046927SAndroid Build Coastguard Worker }
683*61046927SAndroid Build Coastguard Worker
684*61046927SAndroid Build Coastguard Worker
685*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramLocalParameter4fvARB(GLenum target,GLuint index,const GLfloat * params)686*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
687*61046927SAndroid Build Coastguard Worker const GLfloat *params)
688*61046927SAndroid Build Coastguard Worker {
689*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
690*61046927SAndroid Build Coastguard Worker params[2], params[3]);
691*61046927SAndroid Build Coastguard Worker }
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker
694*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramLocalParameter4fvEXT(GLuint program,GLenum target,GLuint index,const GLfloat * params)695*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index,
696*61046927SAndroid Build Coastguard Worker const GLfloat *params)
697*61046927SAndroid Build Coastguard Worker {
698*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4fEXT(program, target, index, params[0],
699*61046927SAndroid Build Coastguard Worker params[1], params[2], params[3]);
700*61046927SAndroid Build Coastguard Worker }
701*61046927SAndroid Build Coastguard Worker
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker static void
program_local_parameters4fv(struct gl_program * prog,GLuint index,GLsizei count,const GLfloat * params,const char * caller)704*61046927SAndroid Build Coastguard Worker program_local_parameters4fv(struct gl_program* prog, GLuint index, GLsizei count,
705*61046927SAndroid Build Coastguard Worker const GLfloat *params, const char* caller)
706*61046927SAndroid Build Coastguard Worker {
707*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
708*61046927SAndroid Build Coastguard Worker GLfloat *dest;
709*61046927SAndroid Build Coastguard Worker flush_vertices_for_program_constants(ctx, prog->Target);
710*61046927SAndroid Build Coastguard Worker
711*61046927SAndroid Build Coastguard Worker if (count <= 0) {
712*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller);
713*61046927SAndroid Build Coastguard Worker }
714*61046927SAndroid Build Coastguard Worker
715*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, caller,
716*61046927SAndroid Build Coastguard Worker prog, prog->Target, index, count, &dest))
717*61046927SAndroid Build Coastguard Worker memcpy(dest, params, count * 4 * sizeof(GLfloat));
718*61046927SAndroid Build Coastguard Worker }
719*61046927SAndroid Build Coastguard Worker
720*61046927SAndroid Build Coastguard Worker
721*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramLocalParameters4fvEXT(GLenum target,GLuint index,GLsizei count,const GLfloat * params)722*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
723*61046927SAndroid Build Coastguard Worker const GLfloat *params)
724*61046927SAndroid Build Coastguard Worker {
725*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
726*61046927SAndroid Build Coastguard Worker struct gl_program* prog = get_current_program(ctx, target,
727*61046927SAndroid Build Coastguard Worker "glProgramLocalParameters4fv");
728*61046927SAndroid Build Coastguard Worker if (!prog) {
729*61046927SAndroid Build Coastguard Worker return;
730*61046927SAndroid Build Coastguard Worker }
731*61046927SAndroid Build Coastguard Worker
732*61046927SAndroid Build Coastguard Worker program_local_parameters4fv(prog, index, count, params,
733*61046927SAndroid Build Coastguard Worker "glProgramLocalParameters4fv");
734*61046927SAndroid Build Coastguard Worker }
735*61046927SAndroid Build Coastguard Worker
736*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramLocalParameters4fvEXT(GLuint program,GLenum target,GLuint index,GLsizei count,const GLfloat * params)737*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index,
738*61046927SAndroid Build Coastguard Worker GLsizei count, const GLfloat *params)
739*61046927SAndroid Build Coastguard Worker {
740*61046927SAndroid Build Coastguard Worker struct gl_program* prog =
741*61046927SAndroid Build Coastguard Worker lookup_or_create_program(program, target,
742*61046927SAndroid Build Coastguard Worker "glNamedProgramLocalParameters4fvEXT");
743*61046927SAndroid Build Coastguard Worker if (!prog) {
744*61046927SAndroid Build Coastguard Worker return;
745*61046927SAndroid Build Coastguard Worker }
746*61046927SAndroid Build Coastguard Worker
747*61046927SAndroid Build Coastguard Worker program_local_parameters4fv(prog, index, count, params,
748*61046927SAndroid Build Coastguard Worker "glNamedProgramLocalParameters4fvEXT");
749*61046927SAndroid Build Coastguard Worker }
750*61046927SAndroid Build Coastguard Worker
751*61046927SAndroid Build Coastguard Worker
752*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramLocalParameter4dARB(GLenum target,GLuint index,GLdouble x,GLdouble y,GLdouble z,GLdouble w)753*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
754*61046927SAndroid Build Coastguard Worker GLdouble x, GLdouble y,
755*61046927SAndroid Build Coastguard Worker GLdouble z, GLdouble w)
756*61046927SAndroid Build Coastguard Worker {
757*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
758*61046927SAndroid Build Coastguard Worker (GLfloat) z, (GLfloat) w);
759*61046927SAndroid Build Coastguard Worker }
760*61046927SAndroid Build Coastguard Worker
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramLocalParameter4dEXT(GLuint program,GLenum target,GLuint index,GLdouble x,GLdouble y,GLdouble z,GLdouble w)763*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index,
764*61046927SAndroid Build Coastguard Worker GLdouble x, GLdouble y,
765*61046927SAndroid Build Coastguard Worker GLdouble z, GLdouble w)
766*61046927SAndroid Build Coastguard Worker {
767*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4fEXT(program, target, index, (GLfloat) x, (GLfloat) y,
768*61046927SAndroid Build Coastguard Worker (GLfloat) z, (GLfloat) w);
769*61046927SAndroid Build Coastguard Worker }
770*61046927SAndroid Build Coastguard Worker
771*61046927SAndroid Build Coastguard Worker
772*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProgramLocalParameter4dvARB(GLenum target,GLuint index,const GLdouble * params)773*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
774*61046927SAndroid Build Coastguard Worker const GLdouble *params)
775*61046927SAndroid Build Coastguard Worker {
776*61046927SAndroid Build Coastguard Worker _mesa_ProgramLocalParameter4fARB(target, index,
777*61046927SAndroid Build Coastguard Worker (GLfloat) params[0], (GLfloat) params[1],
778*61046927SAndroid Build Coastguard Worker (GLfloat) params[2], (GLfloat) params[3]);
779*61046927SAndroid Build Coastguard Worker }
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker
782*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedProgramLocalParameter4dvEXT(GLuint program,GLenum target,GLuint index,const GLdouble * params)783*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint index,
784*61046927SAndroid Build Coastguard Worker const GLdouble *params)
785*61046927SAndroid Build Coastguard Worker {
786*61046927SAndroid Build Coastguard Worker _mesa_NamedProgramLocalParameter4fEXT(program, target, index,
787*61046927SAndroid Build Coastguard Worker (GLfloat) params[0], (GLfloat) params[1],
788*61046927SAndroid Build Coastguard Worker (GLfloat) params[2], (GLfloat) params[3]);
789*61046927SAndroid Build Coastguard Worker }
790*61046927SAndroid Build Coastguard Worker
791*61046927SAndroid Build Coastguard Worker
792*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramLocalParameterfvARB(GLenum target,GLuint index,GLfloat * params)793*61046927SAndroid Build Coastguard Worker _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
794*61046927SAndroid Build Coastguard Worker GLfloat *params)
795*61046927SAndroid Build Coastguard Worker {
796*61046927SAndroid Build Coastguard Worker GLfloat *param;
797*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
798*61046927SAndroid Build Coastguard Worker struct gl_program* prog = get_current_program(ctx, target, "glGetProgramLocalParameterfvARB");
799*61046927SAndroid Build Coastguard Worker if (!prog) {
800*61046927SAndroid Build Coastguard Worker return;
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker
803*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
804*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
805*61046927SAndroid Build Coastguard Worker COPY_4V(params, param);
806*61046927SAndroid Build Coastguard Worker }
807*61046927SAndroid Build Coastguard Worker }
808*61046927SAndroid Build Coastguard Worker
809*61046927SAndroid Build Coastguard Worker
810*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedProgramLocalParameterfvEXT(GLuint program,GLenum target,GLuint index,GLfloat * params)811*61046927SAndroid Build Coastguard Worker _mesa_GetNamedProgramLocalParameterfvEXT(GLuint program, GLenum target, GLuint index,
812*61046927SAndroid Build Coastguard Worker GLfloat *params)
813*61046927SAndroid Build Coastguard Worker {
814*61046927SAndroid Build Coastguard Worker GLfloat *param;
815*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
816*61046927SAndroid Build Coastguard Worker struct gl_program* prog = lookup_or_create_program(program, target,
817*61046927SAndroid Build Coastguard Worker "glGetNamedProgramLocalParameterfvEXT");
818*61046927SAndroid Build Coastguard Worker if (!prog) {
819*61046927SAndroid Build Coastguard Worker return;
820*61046927SAndroid Build Coastguard Worker }
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glGetNamedProgramLocalParameterfvEXT",
823*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
824*61046927SAndroid Build Coastguard Worker COPY_4V(params, param);
825*61046927SAndroid Build Coastguard Worker }
826*61046927SAndroid Build Coastguard Worker }
827*61046927SAndroid Build Coastguard Worker
828*61046927SAndroid Build Coastguard Worker
829*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramLocalParameterdvARB(GLenum target,GLuint index,GLdouble * params)830*61046927SAndroid Build Coastguard Worker _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
831*61046927SAndroid Build Coastguard Worker GLdouble *params)
832*61046927SAndroid Build Coastguard Worker {
833*61046927SAndroid Build Coastguard Worker GLfloat *param;
834*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
835*61046927SAndroid Build Coastguard Worker struct gl_program* prog = get_current_program(ctx, target, "glGetProgramLocalParameterdvARB");
836*61046927SAndroid Build Coastguard Worker if (!prog) {
837*61046927SAndroid Build Coastguard Worker return;
838*61046927SAndroid Build Coastguard Worker }
839*61046927SAndroid Build Coastguard Worker
840*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
841*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
842*61046927SAndroid Build Coastguard Worker COPY_4V(params, param);
843*61046927SAndroid Build Coastguard Worker }
844*61046927SAndroid Build Coastguard Worker }
845*61046927SAndroid Build Coastguard Worker
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedProgramLocalParameterdvEXT(GLuint program,GLenum target,GLuint index,GLdouble * params)848*61046927SAndroid Build Coastguard Worker _mesa_GetNamedProgramLocalParameterdvEXT(GLuint program, GLenum target, GLuint index,
849*61046927SAndroid Build Coastguard Worker GLdouble *params)
850*61046927SAndroid Build Coastguard Worker {
851*61046927SAndroid Build Coastguard Worker GLfloat *param;
852*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
853*61046927SAndroid Build Coastguard Worker struct gl_program* prog = lookup_or_create_program(program, target,
854*61046927SAndroid Build Coastguard Worker "glGetNamedProgramLocalParameterdvEXT");
855*61046927SAndroid Build Coastguard Worker if (!prog) {
856*61046927SAndroid Build Coastguard Worker return;
857*61046927SAndroid Build Coastguard Worker }
858*61046927SAndroid Build Coastguard Worker
859*61046927SAndroid Build Coastguard Worker if (get_local_param_pointer(ctx, "glGetNamedProgramLocalParameterdvEXT",
860*61046927SAndroid Build Coastguard Worker prog, target, index, 1, ¶m)) {
861*61046927SAndroid Build Coastguard Worker COPY_4V(params, param);
862*61046927SAndroid Build Coastguard Worker }
863*61046927SAndroid Build Coastguard Worker }
864*61046927SAndroid Build Coastguard Worker
865*61046927SAndroid Build Coastguard Worker
866*61046927SAndroid Build Coastguard Worker static void
get_program_iv(struct gl_program * prog,GLenum target,GLenum pname,GLint * params)867*61046927SAndroid Build Coastguard Worker get_program_iv(struct gl_program *prog, GLenum target, GLenum pname,
868*61046927SAndroid Build Coastguard Worker GLint *params)
869*61046927SAndroid Build Coastguard Worker {
870*61046927SAndroid Build Coastguard Worker const struct gl_program_constants *limits;
871*61046927SAndroid Build Coastguard Worker
872*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
873*61046927SAndroid Build Coastguard Worker
874*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB) {
875*61046927SAndroid Build Coastguard Worker limits = &ctx->Const.Program[MESA_SHADER_VERTEX];
876*61046927SAndroid Build Coastguard Worker }
877*61046927SAndroid Build Coastguard Worker else {
878*61046927SAndroid Build Coastguard Worker limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
879*61046927SAndroid Build Coastguard Worker }
880*61046927SAndroid Build Coastguard Worker
881*61046927SAndroid Build Coastguard Worker assert(prog);
882*61046927SAndroid Build Coastguard Worker assert(limits);
883*61046927SAndroid Build Coastguard Worker
884*61046927SAndroid Build Coastguard Worker /* Queries supported for both vertex and fragment programs */
885*61046927SAndroid Build Coastguard Worker switch (pname) {
886*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_LENGTH_ARB:
887*61046927SAndroid Build Coastguard Worker *params
888*61046927SAndroid Build Coastguard Worker = prog->String ? (GLint) strlen((char *) prog->String) : 0;
889*61046927SAndroid Build Coastguard Worker return;
890*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_FORMAT_ARB:
891*61046927SAndroid Build Coastguard Worker *params = prog->Format;
892*61046927SAndroid Build Coastguard Worker return;
893*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_BINDING_ARB:
894*61046927SAndroid Build Coastguard Worker *params = prog->Id;
895*61046927SAndroid Build Coastguard Worker return;
896*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_INSTRUCTIONS_ARB:
897*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumInstructions;
898*61046927SAndroid Build Coastguard Worker return;
899*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
900*61046927SAndroid Build Coastguard Worker *params = limits->MaxInstructions;
901*61046927SAndroid Build Coastguard Worker return;
902*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
903*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumNativeInstructions;
904*61046927SAndroid Build Coastguard Worker return;
905*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
906*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeInstructions;
907*61046927SAndroid Build Coastguard Worker return;
908*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_TEMPORARIES_ARB:
909*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumTemporaries;
910*61046927SAndroid Build Coastguard Worker return;
911*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_TEMPORARIES_ARB:
912*61046927SAndroid Build Coastguard Worker *params = limits->MaxTemps;
913*61046927SAndroid Build Coastguard Worker return;
914*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
915*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumNativeTemporaries;
916*61046927SAndroid Build Coastguard Worker return;
917*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
918*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeTemps;
919*61046927SAndroid Build Coastguard Worker return;
920*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_PARAMETERS_ARB:
921*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumParameters;
922*61046927SAndroid Build Coastguard Worker return;
923*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_PARAMETERS_ARB:
924*61046927SAndroid Build Coastguard Worker *params = limits->MaxParameters;
925*61046927SAndroid Build Coastguard Worker return;
926*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
927*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumNativeParameters;
928*61046927SAndroid Build Coastguard Worker return;
929*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
930*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeParameters;
931*61046927SAndroid Build Coastguard Worker return;
932*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_ATTRIBS_ARB:
933*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumAttributes;
934*61046927SAndroid Build Coastguard Worker return;
935*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_ATTRIBS_ARB:
936*61046927SAndroid Build Coastguard Worker *params = limits->MaxAttribs;
937*61046927SAndroid Build Coastguard Worker return;
938*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
939*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumNativeAttributes;
940*61046927SAndroid Build Coastguard Worker return;
941*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
942*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeAttribs;
943*61046927SAndroid Build Coastguard Worker return;
944*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
945*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumAddressRegs;
946*61046927SAndroid Build Coastguard Worker return;
947*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
948*61046927SAndroid Build Coastguard Worker *params = limits->MaxAddressRegs;
949*61046927SAndroid Build Coastguard Worker return;
950*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
951*61046927SAndroid Build Coastguard Worker *params = prog->arb.NumNativeAddressRegs;
952*61046927SAndroid Build Coastguard Worker return;
953*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
954*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeAddressRegs;
955*61046927SAndroid Build Coastguard Worker return;
956*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
957*61046927SAndroid Build Coastguard Worker *params = limits->MaxLocalParams;
958*61046927SAndroid Build Coastguard Worker return;
959*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
960*61046927SAndroid Build Coastguard Worker *params = limits->MaxEnvParams;
961*61046927SAndroid Build Coastguard Worker return;
962*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
963*61046927SAndroid Build Coastguard Worker /*
964*61046927SAndroid Build Coastguard Worker * XXX we may not really need a driver callback here.
965*61046927SAndroid Build Coastguard Worker * If the number of native instructions, registers, etc. used
966*61046927SAndroid Build Coastguard Worker * are all below the maximums, we could return true.
967*61046927SAndroid Build Coastguard Worker * The spec says that even if this query returns true, there's
968*61046927SAndroid Build Coastguard Worker * no guarantee that the program will run in hardware.
969*61046927SAndroid Build Coastguard Worker */
970*61046927SAndroid Build Coastguard Worker if (prog->Id == 0) {
971*61046927SAndroid Build Coastguard Worker /* default/null program */
972*61046927SAndroid Build Coastguard Worker *params = GL_FALSE;
973*61046927SAndroid Build Coastguard Worker }
974*61046927SAndroid Build Coastguard Worker else {
975*61046927SAndroid Build Coastguard Worker /* probably running in software */
976*61046927SAndroid Build Coastguard Worker *params = GL_TRUE;
977*61046927SAndroid Build Coastguard Worker }
978*61046927SAndroid Build Coastguard Worker return;
979*61046927SAndroid Build Coastguard Worker default:
980*61046927SAndroid Build Coastguard Worker /* continue with fragment-program only queries below */
981*61046927SAndroid Build Coastguard Worker break;
982*61046927SAndroid Build Coastguard Worker }
983*61046927SAndroid Build Coastguard Worker
984*61046927SAndroid Build Coastguard Worker /*
985*61046927SAndroid Build Coastguard Worker * The following apply to fragment programs only (at this time)
986*61046927SAndroid Build Coastguard Worker */
987*61046927SAndroid Build Coastguard Worker if (target == GL_FRAGMENT_PROGRAM_ARB) {
988*61046927SAndroid Build Coastguard Worker const struct gl_program *fp = ctx->FragmentProgram.Current;
989*61046927SAndroid Build Coastguard Worker switch (pname) {
990*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
991*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumNativeAluInstructions;
992*61046927SAndroid Build Coastguard Worker return;
993*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
994*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumAluInstructions;
995*61046927SAndroid Build Coastguard Worker return;
996*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
997*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumTexInstructions;
998*61046927SAndroid Build Coastguard Worker return;
999*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
1000*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumNativeTexInstructions;
1001*61046927SAndroid Build Coastguard Worker return;
1002*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
1003*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumTexIndirections;
1004*61046927SAndroid Build Coastguard Worker return;
1005*61046927SAndroid Build Coastguard Worker case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
1006*61046927SAndroid Build Coastguard Worker *params = fp->arb.NumNativeTexIndirections;
1007*61046927SAndroid Build Coastguard Worker return;
1008*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
1009*61046927SAndroid Build Coastguard Worker *params = limits->MaxAluInstructions;
1010*61046927SAndroid Build Coastguard Worker return;
1011*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
1012*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeAluInstructions;
1013*61046927SAndroid Build Coastguard Worker return;
1014*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
1015*61046927SAndroid Build Coastguard Worker *params = limits->MaxTexInstructions;
1016*61046927SAndroid Build Coastguard Worker return;
1017*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
1018*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeTexInstructions;
1019*61046927SAndroid Build Coastguard Worker return;
1020*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
1021*61046927SAndroid Build Coastguard Worker *params = limits->MaxTexIndirections;
1022*61046927SAndroid Build Coastguard Worker return;
1023*61046927SAndroid Build Coastguard Worker case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
1024*61046927SAndroid Build Coastguard Worker *params = limits->MaxNativeTexIndirections;
1025*61046927SAndroid Build Coastguard Worker return;
1026*61046927SAndroid Build Coastguard Worker default:
1027*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
1028*61046927SAndroid Build Coastguard Worker return;
1029*61046927SAndroid Build Coastguard Worker }
1030*61046927SAndroid Build Coastguard Worker } else {
1031*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
1032*61046927SAndroid Build Coastguard Worker return;
1033*61046927SAndroid Build Coastguard Worker }
1034*61046927SAndroid Build Coastguard Worker }
1035*61046927SAndroid Build Coastguard Worker
1036*61046927SAndroid Build Coastguard Worker
1037*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramivARB(GLenum target,GLenum pname,GLint * params)1038*61046927SAndroid Build Coastguard Worker _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
1039*61046927SAndroid Build Coastguard Worker {
1040*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1041*61046927SAndroid Build Coastguard Worker struct gl_program* prog = get_current_program(ctx, target,
1042*61046927SAndroid Build Coastguard Worker "glGetProgramivARB");
1043*61046927SAndroid Build Coastguard Worker if (!prog) {
1044*61046927SAndroid Build Coastguard Worker return;
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker get_program_iv(prog, target, pname, params);
1047*61046927SAndroid Build Coastguard Worker }
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedProgramivEXT(GLuint program,GLenum target,GLenum pname,GLint * params)1050*61046927SAndroid Build Coastguard Worker _mesa_GetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname,
1051*61046927SAndroid Build Coastguard Worker GLint *params)
1052*61046927SAndroid Build Coastguard Worker {
1053*61046927SAndroid Build Coastguard Worker struct gl_program* prog;
1054*61046927SAndroid Build Coastguard Worker if (pname == GL_PROGRAM_BINDING_ARB) {
1055*61046927SAndroid Build Coastguard Worker _mesa_GetProgramivARB(target, pname, params);
1056*61046927SAndroid Build Coastguard Worker return;
1057*61046927SAndroid Build Coastguard Worker }
1058*61046927SAndroid Build Coastguard Worker prog = lookup_or_create_program(program, target,
1059*61046927SAndroid Build Coastguard Worker "glGetNamedProgramivEXT");
1060*61046927SAndroid Build Coastguard Worker if (!prog) {
1061*61046927SAndroid Build Coastguard Worker return;
1062*61046927SAndroid Build Coastguard Worker }
1063*61046927SAndroid Build Coastguard Worker get_program_iv(prog, target, pname, params);
1064*61046927SAndroid Build Coastguard Worker }
1065*61046927SAndroid Build Coastguard Worker
1066*61046927SAndroid Build Coastguard Worker
1067*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramStringARB(GLenum target,GLenum pname,GLvoid * string)1068*61046927SAndroid Build Coastguard Worker _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
1069*61046927SAndroid Build Coastguard Worker {
1070*61046927SAndroid Build Coastguard Worker const struct gl_program *prog;
1071*61046927SAndroid Build Coastguard Worker char *dst = (char *) string;
1072*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1073*61046927SAndroid Build Coastguard Worker
1074*61046927SAndroid Build Coastguard Worker if (target == GL_VERTEX_PROGRAM_ARB) {
1075*61046927SAndroid Build Coastguard Worker prog = ctx->VertexProgram.Current;
1076*61046927SAndroid Build Coastguard Worker }
1077*61046927SAndroid Build Coastguard Worker else if (target == GL_FRAGMENT_PROGRAM_ARB) {
1078*61046927SAndroid Build Coastguard Worker prog = ctx->FragmentProgram.Current;
1079*61046927SAndroid Build Coastguard Worker }
1080*61046927SAndroid Build Coastguard Worker else {
1081*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
1082*61046927SAndroid Build Coastguard Worker return;
1083*61046927SAndroid Build Coastguard Worker }
1084*61046927SAndroid Build Coastguard Worker
1085*61046927SAndroid Build Coastguard Worker assert(prog);
1086*61046927SAndroid Build Coastguard Worker
1087*61046927SAndroid Build Coastguard Worker if (pname != GL_PROGRAM_STRING_ARB) {
1088*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
1089*61046927SAndroid Build Coastguard Worker return;
1090*61046927SAndroid Build Coastguard Worker }
1091*61046927SAndroid Build Coastguard Worker
1092*61046927SAndroid Build Coastguard Worker if (prog->String)
1093*61046927SAndroid Build Coastguard Worker memcpy(dst, prog->String, strlen((char *) prog->String));
1094*61046927SAndroid Build Coastguard Worker else
1095*61046927SAndroid Build Coastguard Worker *dst = '\0';
1096*61046927SAndroid Build Coastguard Worker }
1097*61046927SAndroid Build Coastguard Worker
1098*61046927SAndroid Build Coastguard Worker
1099*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedProgramStringEXT(GLuint program,GLenum target,GLenum pname,GLvoid * string)1100*61046927SAndroid Build Coastguard Worker _mesa_GetNamedProgramStringEXT(GLuint program, GLenum target,
1101*61046927SAndroid Build Coastguard Worker GLenum pname, GLvoid *string) {
1102*61046927SAndroid Build Coastguard Worker char *dst = (char *) string;
1103*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1104*61046927SAndroid Build Coastguard Worker struct gl_program* prog = lookup_or_create_program(program, target,
1105*61046927SAndroid Build Coastguard Worker "glGetNamedProgramStringEXT");
1106*61046927SAndroid Build Coastguard Worker if (!prog)
1107*61046927SAndroid Build Coastguard Worker return;
1108*61046927SAndroid Build Coastguard Worker
1109*61046927SAndroid Build Coastguard Worker if (pname != GL_PROGRAM_STRING_ARB) {
1110*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetNamedProgramStringEXT(pname)");
1111*61046927SAndroid Build Coastguard Worker return;
1112*61046927SAndroid Build Coastguard Worker }
1113*61046927SAndroid Build Coastguard Worker
1114*61046927SAndroid Build Coastguard Worker if (prog->String)
1115*61046927SAndroid Build Coastguard Worker memcpy(dst, prog->String, strlen((char *) prog->String));
1116*61046927SAndroid Build Coastguard Worker else
1117*61046927SAndroid Build Coastguard Worker *dst = '\0';
1118*61046927SAndroid Build Coastguard Worker }
1119