xref: /aosp_15_r20/external/mesa3d/src/mesa/main/arbprogram.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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, &param)) {
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