13464ebd5Sriastradh/* 23464ebd5Sriastradh * Mesa 3-D graphics library 33464ebd5Sriastradh * 43464ebd5Sriastradh * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 53464ebd5Sriastradh * 63464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 73464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"), 83464ebd5Sriastradh * to deal in the Software without restriction, including without limitation 93464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 103464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the 113464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions: 123464ebd5Sriastradh * 133464ebd5Sriastradh * The above copyright notice and this permission notice shall be included 143464ebd5Sriastradh * in all copies or substantial portions of the Software. 153464ebd5Sriastradh * 163464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 173464ebd5Sriastradh * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 183464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 233464ebd5Sriastradh */ 243464ebd5Sriastradh 253464ebd5Sriastradh#define DEBUG_PARSING 0 263464ebd5Sriastradh 273464ebd5Sriastradh/** 283464ebd5Sriastradh * \file arbprogparse.c 293464ebd5Sriastradh * ARB_*_program parser core 303464ebd5Sriastradh * \author Karl Rasche 313464ebd5Sriastradh */ 323464ebd5Sriastradh 333464ebd5Sriastradh/** 343464ebd5SriastradhNotes on program parameters, etc. 353464ebd5Sriastradh 363464ebd5SriastradhThe instructions we emit will use six kinds of source registers: 373464ebd5Sriastradh 383464ebd5Sriastradh PROGRAM_INPUT - input registers 393464ebd5Sriastradh PROGRAM_TEMPORARY - temp registers 403464ebd5Sriastradh PROGRAM_ADDRESS - address/indirect register 413464ebd5Sriastradh PROGRAM_SAMPLER - texture sampler 423464ebd5Sriastradh PROGRAM_CONSTANT - indexes into program->Parameters, a known constant/literal 433464ebd5Sriastradh PROGRAM_STATE_VAR - indexes into program->Parameters, and may actually be: 443464ebd5Sriastradh + a state variable, like "state.fog.color", or 453464ebd5Sriastradh + a pointer to a "program.local[k]" parameter, or 463464ebd5Sriastradh + a pointer to a "program.env[k]" parameter 473464ebd5Sriastradh 483464ebd5SriastradhBasically, all the program.local[] and program.env[] values will get mapped 493464ebd5Sriastradhinto the unified gl_program->Parameters array. This solves the problem of 503464ebd5Sriastradhhaving three separate program parameter arrays. 513464ebd5Sriastradh*/ 523464ebd5Sriastradh 533464ebd5Sriastradh 543464ebd5Sriastradh#include "main/glheader.h" 557ec681f3Smrg 563464ebd5Sriastradh#include "main/context.h" 573464ebd5Sriastradh#include "main/mtypes.h" 583464ebd5Sriastradh#include "arbprogparse.h" 593464ebd5Sriastradh#include "programopt.h" 603464ebd5Sriastradh#include "prog_parameter.h" 613464ebd5Sriastradh#include "prog_statevars.h" 623464ebd5Sriastradh#include "prog_instruction.h" 63af69d88dSmrg#include "prog_optimize.h" 643464ebd5Sriastradh#include "program_parser.h" 653464ebd5Sriastradh 663464ebd5Sriastradh 673464ebd5Sriastradhvoid 683464ebd5Sriastradh_mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target, 693464ebd5Sriastradh const GLvoid *str, GLsizei len, 7001e04c3fSmrg struct gl_program *program) 713464ebd5Sriastradh{ 723464ebd5Sriastradh struct gl_program prog; 733464ebd5Sriastradh struct asm_parser_state state; 743464ebd5Sriastradh GLuint i; 753464ebd5Sriastradh 7601e04c3fSmrg assert(target == GL_FRAGMENT_PROGRAM_ARB); 773464ebd5Sriastradh 783464ebd5Sriastradh memset(&prog, 0, sizeof(prog)); 793464ebd5Sriastradh memset(&state, 0, sizeof(state)); 803464ebd5Sriastradh state.prog = &prog; 8101e04c3fSmrg state.mem_ctx = program; 823464ebd5Sriastradh 833464ebd5Sriastradh if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, 843464ebd5Sriastradh &state)) { 853464ebd5Sriastradh /* Error in the program. Just return. */ 863464ebd5Sriastradh return; 873464ebd5Sriastradh } 883464ebd5Sriastradh 8901e04c3fSmrg ralloc_free(program->String); 903464ebd5Sriastradh 913464ebd5Sriastradh /* Copy the relevant contents of the arb_program struct into the 923464ebd5Sriastradh * fragment_program struct. 933464ebd5Sriastradh */ 9401e04c3fSmrg program->String = prog.String; 9501e04c3fSmrg program->arb.NumInstructions = prog.arb.NumInstructions; 9601e04c3fSmrg program->arb.NumTemporaries = prog.arb.NumTemporaries; 9701e04c3fSmrg program->arb.NumParameters = prog.arb.NumParameters; 9801e04c3fSmrg program->arb.NumAttributes = prog.arb.NumAttributes; 9901e04c3fSmrg program->arb.NumAddressRegs = prog.arb.NumAddressRegs; 10001e04c3fSmrg program->arb.NumNativeInstructions = prog.arb.NumNativeInstructions; 10101e04c3fSmrg program->arb.NumNativeTemporaries = prog.arb.NumNativeTemporaries; 10201e04c3fSmrg program->arb.NumNativeParameters = prog.arb.NumNativeParameters; 10301e04c3fSmrg program->arb.NumNativeAttributes = prog.arb.NumNativeAttributes; 10401e04c3fSmrg program->arb.NumNativeAddressRegs = prog.arb.NumNativeAddressRegs; 10501e04c3fSmrg program->arb.NumAluInstructions = prog.arb.NumAluInstructions; 10601e04c3fSmrg program->arb.NumTexInstructions = prog.arb.NumTexInstructions; 10701e04c3fSmrg program->arb.NumTexIndirections = prog.arb.NumTexIndirections; 10801e04c3fSmrg program->arb.NumNativeAluInstructions = prog.arb.NumAluInstructions; 10901e04c3fSmrg program->arb.NumNativeTexInstructions = prog.arb.NumTexInstructions; 11001e04c3fSmrg program->arb.NumNativeTexIndirections = prog.arb.NumTexIndirections; 11101e04c3fSmrg program->info.inputs_read = prog.info.inputs_read; 11201e04c3fSmrg program->info.outputs_written = prog.info.outputs_written; 11301e04c3fSmrg program->arb.IndirectRegisterFiles = prog.arb.IndirectRegisterFiles; 1143464ebd5Sriastradh for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { 11501e04c3fSmrg program->TexturesUsed[i] = prog.TexturesUsed[i]; 1163464ebd5Sriastradh if (prog.TexturesUsed[i]) 11701e04c3fSmrg program->SamplersUsed |= (1 << i); 1183464ebd5Sriastradh } 11901e04c3fSmrg program->ShadowSamplers = prog.ShadowSamplers; 120b9abf16eSmaya program->info.fs.origin_upper_left = state.option.OriginUpperLeft; 121b9abf16eSmaya program->info.fs.pixel_center_integer = state.option.PixelCenterInteger; 1223464ebd5Sriastradh 12301e04c3fSmrg program->info.fs.uses_discard = state.fragment.UsesKill; 1243464ebd5Sriastradh 12501e04c3fSmrg ralloc_free(program->arb.Instructions); 12601e04c3fSmrg program->arb.Instructions = prog.arb.Instructions; 1273464ebd5Sriastradh 12801e04c3fSmrg if (program->Parameters) 12901e04c3fSmrg _mesa_free_parameter_list(program->Parameters); 13001e04c3fSmrg program->Parameters = prog.Parameters; 1313464ebd5Sriastradh 1323464ebd5Sriastradh /* Append fog instructions now if the program has "OPTION ARB_fog_exp" 1333464ebd5Sriastradh * or similar. We used to leave this up to drivers, but it appears 1343464ebd5Sriastradh * there's no hardware that wants to do fog in a discrete stage separate 1353464ebd5Sriastradh * from the fragment shader. 1363464ebd5Sriastradh */ 1373464ebd5Sriastradh if (state.option.Fog != OPTION_NONE) { 1383464ebd5Sriastradh static const GLenum fog_modes[4] = { 1393464ebd5Sriastradh GL_NONE, GL_EXP, GL_EXP2, GL_LINEAR 1403464ebd5Sriastradh }; 1413464ebd5Sriastradh 1423464ebd5Sriastradh /* XXX: we should somehow recompile this to remove clamping if disabled 1433464ebd5Sriastradh * On the ATI driver, this is unclampled if fragment clamping is disabled 1443464ebd5Sriastradh */ 1453464ebd5Sriastradh _mesa_append_fog_code(ctx, program, fog_modes[state.option.Fog], GL_TRUE); 1463464ebd5Sriastradh } 1473464ebd5Sriastradh 1483464ebd5Sriastradh#if DEBUG_FP 14901e04c3fSmrg printf("____________Fragment program %u ________\n", program->Id); 1503464ebd5Sriastradh _mesa_print_program(&program->Base); 1513464ebd5Sriastradh#endif 1523464ebd5Sriastradh} 1533464ebd5Sriastradh 1543464ebd5Sriastradh 1553464ebd5Sriastradh 1563464ebd5Sriastradh/** 1573464ebd5Sriastradh * Parse the vertex program string. If success, update the given 1583464ebd5Sriastradh * vertex_program object with the new program. Else, leave the vertex_program 1593464ebd5Sriastradh * object unchanged. 1603464ebd5Sriastradh */ 1613464ebd5Sriastradhvoid 1623464ebd5Sriastradh_mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target, 1633464ebd5Sriastradh const GLvoid *str, GLsizei len, 16401e04c3fSmrg struct gl_program *program) 1653464ebd5Sriastradh{ 1663464ebd5Sriastradh struct gl_program prog; 1673464ebd5Sriastradh struct asm_parser_state state; 1683464ebd5Sriastradh 16901e04c3fSmrg assert(target == GL_VERTEX_PROGRAM_ARB); 1703464ebd5Sriastradh 1713464ebd5Sriastradh memset(&prog, 0, sizeof(prog)); 1723464ebd5Sriastradh memset(&state, 0, sizeof(state)); 1733464ebd5Sriastradh state.prog = &prog; 17401e04c3fSmrg state.mem_ctx = program; 1753464ebd5Sriastradh 1763464ebd5Sriastradh if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, 1773464ebd5Sriastradh &state)) { 1783464ebd5Sriastradh _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)"); 1793464ebd5Sriastradh return; 1803464ebd5Sriastradh } 1813464ebd5Sriastradh 18201e04c3fSmrg _mesa_optimize_program(&prog, program); 183af69d88dSmrg 18401e04c3fSmrg ralloc_free(program->String); 1853464ebd5Sriastradh 1867ec681f3Smrg /* Copy the relevant contents of the arb_program struct into the 1873464ebd5Sriastradh * vertex_program struct. 1883464ebd5Sriastradh */ 18901e04c3fSmrg program->String = prog.String; 19001e04c3fSmrg program->arb.NumInstructions = prog.arb.NumInstructions; 19101e04c3fSmrg program->arb.NumTemporaries = prog.arb.NumTemporaries; 19201e04c3fSmrg program->arb.NumParameters = prog.arb.NumParameters; 19301e04c3fSmrg program->arb.NumAttributes = prog.arb.NumAttributes; 19401e04c3fSmrg program->arb.NumAddressRegs = prog.arb.NumAddressRegs; 19501e04c3fSmrg program->arb.NumNativeInstructions = prog.arb.NumNativeInstructions; 19601e04c3fSmrg program->arb.NumNativeTemporaries = prog.arb.NumNativeTemporaries; 19701e04c3fSmrg program->arb.NumNativeParameters = prog.arb.NumNativeParameters; 19801e04c3fSmrg program->arb.NumNativeAttributes = prog.arb.NumNativeAttributes; 19901e04c3fSmrg program->arb.NumNativeAddressRegs = prog.arb.NumNativeAddressRegs; 20001e04c3fSmrg program->info.inputs_read = prog.info.inputs_read; 20101e04c3fSmrg program->info.outputs_written = prog.info.outputs_written; 20201e04c3fSmrg program->arb.IndirectRegisterFiles = prog.arb.IndirectRegisterFiles; 20301e04c3fSmrg program->arb.IsPositionInvariant = (state.option.PositionInvariant) 2043464ebd5Sriastradh ? GL_TRUE : GL_FALSE; 2053464ebd5Sriastradh 20601e04c3fSmrg ralloc_free(program->arb.Instructions); 20701e04c3fSmrg program->arb.Instructions = prog.arb.Instructions; 2083464ebd5Sriastradh 20901e04c3fSmrg if (program->Parameters) 21001e04c3fSmrg _mesa_free_parameter_list(program->Parameters); 21101e04c3fSmrg program->Parameters = prog.Parameters; 2123464ebd5Sriastradh 2133464ebd5Sriastradh#if DEBUG_VP 21401e04c3fSmrg printf("____________Vertex program %u __________\n", program->Id); 21501e04c3fSmrg _mesa_print_program(program); 2163464ebd5Sriastradh#endif 2173464ebd5Sriastradh} 218