1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file prog_print.c 28848b8605Smrg * Print vertex/fragment programs - for debugging. 29848b8605Smrg * \author Brian Paul 30848b8605Smrg */ 31848b8605Smrg 32848b8605Smrg#include <inttypes.h> /* for PRIx64 macro */ 33848b8605Smrg 34848b8605Smrg#include "main/glheader.h" 35848b8605Smrg#include "main/context.h" 36848b8605Smrg#include "main/imports.h" 37848b8605Smrg#include "prog_instruction.h" 38848b8605Smrg#include "prog_parameter.h" 39848b8605Smrg#include "prog_print.h" 40848b8605Smrg#include "prog_statevars.h" 41848b8605Smrg 42848b8605Smrg 43848b8605Smrg 44848b8605Smrg/** 45848b8605Smrg * Return string name for given program/register file. 46848b8605Smrg */ 47848b8605Smrgconst char * 48848b8605Smrg_mesa_register_file_name(gl_register_file f) 49848b8605Smrg{ 50848b8605Smrg switch (f) { 51848b8605Smrg case PROGRAM_TEMPORARY: 52848b8605Smrg return "TEMP"; 53b8e80941Smrg case PROGRAM_ARRAY: 54b8e80941Smrg return "ARRAY"; 55848b8605Smrg case PROGRAM_INPUT: 56848b8605Smrg return "INPUT"; 57848b8605Smrg case PROGRAM_OUTPUT: 58848b8605Smrg return "OUTPUT"; 59b8e80941Smrg case PROGRAM_STATE_VAR: 60b8e80941Smrg return "STATE"; 61848b8605Smrg case PROGRAM_CONSTANT: 62848b8605Smrg return "CONST"; 63848b8605Smrg case PROGRAM_UNIFORM: 64848b8605Smrg return "UNIFORM"; 65848b8605Smrg case PROGRAM_ADDRESS: 66848b8605Smrg return "ADDR"; 67848b8605Smrg case PROGRAM_SAMPLER: 68848b8605Smrg return "SAMPLER"; 69848b8605Smrg case PROGRAM_SYSTEM_VALUE: 70848b8605Smrg return "SYSVAL"; 71848b8605Smrg case PROGRAM_UNDEFINED: 72848b8605Smrg return "UNDEFINED"; 73b8e80941Smrg case PROGRAM_IMMEDIATE: 74b8e80941Smrg return "IMM"; 75b8e80941Smrg case PROGRAM_BUFFER: 76b8e80941Smrg return "BUFFER"; 77b8e80941Smrg case PROGRAM_MEMORY: 78b8e80941Smrg return "MEMORY"; 79b8e80941Smrg case PROGRAM_IMAGE: 80b8e80941Smrg return "IMAGE"; 81b8e80941Smrg case PROGRAM_HW_ATOMIC: 82b8e80941Smrg return "HWATOMIC"; 83848b8605Smrg default: 84848b8605Smrg { 85848b8605Smrg static char s[20]; 86848b8605Smrg _mesa_snprintf(s, sizeof(s), "FILE%u", f); 87848b8605Smrg return s; 88848b8605Smrg } 89848b8605Smrg } 90848b8605Smrg} 91848b8605Smrg 92848b8605Smrg 93848b8605Smrg/** 94848b8605Smrg * Return ARB_v/f_prog-style input attrib string. 95848b8605Smrg */ 96848b8605Smrgstatic const char * 97b8e80941Smrgarb_input_attrib_string(GLuint index, GLenum progType) 98848b8605Smrg{ 99848b8605Smrg /* 100848b8605Smrg * These strings should match the VERT_ATTRIB_x and VARYING_SLOT_x tokens. 101848b8605Smrg */ 102848b8605Smrg static const char *const vertAttribs[] = { 103848b8605Smrg "vertex.position", 104848b8605Smrg "vertex.normal", 105848b8605Smrg "vertex.color.primary", 106848b8605Smrg "vertex.color.secondary", 107848b8605Smrg "vertex.fogcoord", 108848b8605Smrg "vertex.(six)", /* VERT_ATTRIB_COLOR_INDEX */ 109848b8605Smrg "vertex.(seven)", /* VERT_ATTRIB_EDGEFLAG */ 110848b8605Smrg "vertex.texcoord[0]", 111848b8605Smrg "vertex.texcoord[1]", 112848b8605Smrg "vertex.texcoord[2]", 113848b8605Smrg "vertex.texcoord[3]", 114848b8605Smrg "vertex.texcoord[4]", 115848b8605Smrg "vertex.texcoord[5]", 116848b8605Smrg "vertex.texcoord[6]", 117848b8605Smrg "vertex.texcoord[7]", 118848b8605Smrg "vertex.(sixteen)", /* VERT_ATTRIB_POINT_SIZE */ 119848b8605Smrg "vertex.attrib[0]", 120848b8605Smrg "vertex.attrib[1]", 121848b8605Smrg "vertex.attrib[2]", 122848b8605Smrg "vertex.attrib[3]", 123848b8605Smrg "vertex.attrib[4]", 124848b8605Smrg "vertex.attrib[5]", 125848b8605Smrg "vertex.attrib[6]", 126848b8605Smrg "vertex.attrib[7]", 127848b8605Smrg "vertex.attrib[8]", 128848b8605Smrg "vertex.attrib[9]", 129848b8605Smrg "vertex.attrib[10]", 130848b8605Smrg "vertex.attrib[11]", 131848b8605Smrg "vertex.attrib[12]", 132848b8605Smrg "vertex.attrib[13]", 133848b8605Smrg "vertex.attrib[14]", 134848b8605Smrg "vertex.attrib[15]" /* MAX_VARYING = 16 */ 135848b8605Smrg }; 136848b8605Smrg static const char *const fragAttribs[] = { 137848b8605Smrg "fragment.position", 138848b8605Smrg "fragment.color.primary", 139848b8605Smrg "fragment.color.secondary", 140848b8605Smrg "fragment.fogcoord", 141848b8605Smrg "fragment.texcoord[0]", 142848b8605Smrg "fragment.texcoord[1]", 143848b8605Smrg "fragment.texcoord[2]", 144848b8605Smrg "fragment.texcoord[3]", 145848b8605Smrg "fragment.texcoord[4]", 146848b8605Smrg "fragment.texcoord[5]", 147848b8605Smrg "fragment.texcoord[6]", 148848b8605Smrg "fragment.texcoord[7]", 149848b8605Smrg "fragment.(twelve)", /* VARYING_SLOT_PSIZ */ 150848b8605Smrg "fragment.(thirteen)", /* VARYING_SLOT_BFC0 */ 151848b8605Smrg "fragment.(fourteen)", /* VARYING_SLOT_BFC1 */ 152848b8605Smrg "fragment.(fifteen)", /* VARYING_SLOT_EDGE */ 153848b8605Smrg "fragment.(sixteen)", /* VARYING_SLOT_CLIP_VERTEX */ 154848b8605Smrg "fragment.(seventeen)", /* VARYING_SLOT_CLIP_DIST0 */ 155848b8605Smrg "fragment.(eighteen)", /* VARYING_SLOT_CLIP_DIST1 */ 156848b8605Smrg "fragment.(nineteen)", /* VARYING_SLOT_PRIMITIVE_ID */ 157848b8605Smrg "fragment.(twenty)", /* VARYING_SLOT_LAYER */ 158848b8605Smrg "fragment.(twenty-one)", /* VARYING_SLOT_VIEWPORT */ 159848b8605Smrg "fragment.(twenty-two)", /* VARYING_SLOT_FACE */ 160848b8605Smrg "fragment.(twenty-three)", /* VARYING_SLOT_PNTC */ 161b8e80941Smrg "fragment.(twenty-four)", /* VARYING_SLOT_TESS_LEVEL_OUTER */ 162b8e80941Smrg "fragment.(twenty-five)", /* VARYING_SLOT_TESS_LEVEL_INNER */ 163b8e80941Smrg "fragment.(twenty-six)", /* VARYING_SLOT_CULL_DIST0 */ 164b8e80941Smrg "fragment.(twenty-seven)", /* VARYING_SLOT_CULL_DIST1 */ 165b8e80941Smrg "fragment.(twenty-eight)", /* VARYING_SLOT_BOUNDING_BOX0 */ 166b8e80941Smrg "fragment.(twenty-nine)", /* VARYING_SLOT_BOUNDING_BOX1 */ 167b8e80941Smrg "fragment.(thirty)", /* VARYING_SLOT_VIEW_INDEX */ 168848b8605Smrg "fragment.varying[0]", 169848b8605Smrg "fragment.varying[1]", 170848b8605Smrg "fragment.varying[2]", 171848b8605Smrg "fragment.varying[3]", 172848b8605Smrg "fragment.varying[4]", 173848b8605Smrg "fragment.varying[5]", 174848b8605Smrg "fragment.varying[6]", 175848b8605Smrg "fragment.varying[7]", 176848b8605Smrg "fragment.varying[8]", 177848b8605Smrg "fragment.varying[9]", 178848b8605Smrg "fragment.varying[10]", 179848b8605Smrg "fragment.varying[11]", 180848b8605Smrg "fragment.varying[12]", 181848b8605Smrg "fragment.varying[13]", 182848b8605Smrg "fragment.varying[14]", 183848b8605Smrg "fragment.varying[15]", 184848b8605Smrg "fragment.varying[16]", 185848b8605Smrg "fragment.varying[17]", 186848b8605Smrg "fragment.varying[18]", 187848b8605Smrg "fragment.varying[19]", 188848b8605Smrg "fragment.varying[20]", 189848b8605Smrg "fragment.varying[21]", 190848b8605Smrg "fragment.varying[22]", 191848b8605Smrg "fragment.varying[23]", 192848b8605Smrg "fragment.varying[24]", 193848b8605Smrg "fragment.varying[25]", 194848b8605Smrg "fragment.varying[26]", 195848b8605Smrg "fragment.varying[27]", 196848b8605Smrg "fragment.varying[28]", 197848b8605Smrg "fragment.varying[29]", 198848b8605Smrg "fragment.varying[30]", 199848b8605Smrg "fragment.varying[31]", /* MAX_VARYING = 32 */ 200848b8605Smrg }; 201848b8605Smrg 202848b8605Smrg /* sanity checks */ 203b8e80941Smrg STATIC_ASSERT(ARRAY_SIZE(vertAttribs) == VERT_ATTRIB_MAX); 204b8e80941Smrg STATIC_ASSERT(ARRAY_SIZE(fragAttribs) == VARYING_SLOT_MAX); 205848b8605Smrg assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0); 206848b8605Smrg assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0); 207848b8605Smrg assert(strcmp(fragAttribs[VARYING_SLOT_TEX0], "fragment.texcoord[0]") == 0); 208848b8605Smrg assert(strcmp(fragAttribs[VARYING_SLOT_VAR0+15], "fragment.varying[15]") == 0); 209848b8605Smrg 210848b8605Smrg if (progType == GL_VERTEX_PROGRAM_ARB) { 211b8e80941Smrg assert(index < ARRAY_SIZE(vertAttribs)); 212848b8605Smrg return vertAttribs[index]; 213848b8605Smrg } 214848b8605Smrg else { 215848b8605Smrg assert(progType == GL_FRAGMENT_PROGRAM_ARB); 216b8e80941Smrg assert(index < ARRAY_SIZE(fragAttribs)); 217848b8605Smrg return fragAttribs[index]; 218848b8605Smrg } 219848b8605Smrg} 220848b8605Smrg 221848b8605Smrg 222848b8605Smrg/** 223b8e80941Smrg * Print a vertex program's inputs_read field in human-readable format. 224848b8605Smrg * For debugging. 225848b8605Smrg */ 226848b8605Smrgvoid 227848b8605Smrg_mesa_print_vp_inputs(GLbitfield inputs) 228848b8605Smrg{ 229848b8605Smrg printf("VP Inputs 0x%x: \n", inputs); 230848b8605Smrg while (inputs) { 231848b8605Smrg GLint attr = ffs(inputs) - 1; 232848b8605Smrg const char *name = arb_input_attrib_string(attr, 233848b8605Smrg GL_VERTEX_PROGRAM_ARB); 234848b8605Smrg printf(" %d: %s\n", attr, name); 235848b8605Smrg inputs &= ~(1 << attr); 236848b8605Smrg } 237848b8605Smrg} 238848b8605Smrg 239848b8605Smrg 240848b8605Smrg/** 241b8e80941Smrg * Print a fragment program's inputs_read field in human-readable format. 242848b8605Smrg * For debugging. 243848b8605Smrg */ 244848b8605Smrgvoid 245848b8605Smrg_mesa_print_fp_inputs(GLbitfield inputs) 246848b8605Smrg{ 247848b8605Smrg printf("FP Inputs 0x%x: \n", inputs); 248848b8605Smrg while (inputs) { 249848b8605Smrg GLint attr = ffs(inputs) - 1; 250848b8605Smrg const char *name = arb_input_attrib_string(attr, 251848b8605Smrg GL_FRAGMENT_PROGRAM_ARB); 252848b8605Smrg printf(" %d: %s\n", attr, name); 253848b8605Smrg inputs &= ~(1 << attr); 254848b8605Smrg } 255848b8605Smrg} 256848b8605Smrg 257848b8605Smrg 258848b8605Smrg 259848b8605Smrg/** 260848b8605Smrg * Return ARB_v/f_prog-style output attrib string. 261848b8605Smrg */ 262848b8605Smrgstatic const char * 263b8e80941Smrgarb_output_attrib_string(GLuint index, GLenum progType) 264848b8605Smrg{ 265848b8605Smrg /* 266848b8605Smrg * These strings should match the VARYING_SLOT_x and FRAG_RESULT_x tokens. 267848b8605Smrg */ 268848b8605Smrg static const char *const vertResults[] = { 269848b8605Smrg "result.position", 270848b8605Smrg "result.color.primary", 271848b8605Smrg "result.color.secondary", 272848b8605Smrg "result.fogcoord", 273848b8605Smrg "result.texcoord[0]", 274848b8605Smrg "result.texcoord[1]", 275848b8605Smrg "result.texcoord[2]", 276848b8605Smrg "result.texcoord[3]", 277848b8605Smrg "result.texcoord[4]", 278848b8605Smrg "result.texcoord[5]", 279848b8605Smrg "result.texcoord[6]", 280848b8605Smrg "result.texcoord[7]", 281848b8605Smrg "result.pointsize", /* VARYING_SLOT_PSIZ */ 282848b8605Smrg "result.(thirteen)", /* VARYING_SLOT_BFC0 */ 283848b8605Smrg "result.(fourteen)", /* VARYING_SLOT_BFC1 */ 284848b8605Smrg "result.(fifteen)", /* VARYING_SLOT_EDGE */ 285848b8605Smrg "result.(sixteen)", /* VARYING_SLOT_CLIP_VERTEX */ 286848b8605Smrg "result.(seventeen)", /* VARYING_SLOT_CLIP_DIST0 */ 287848b8605Smrg "result.(eighteen)", /* VARYING_SLOT_CLIP_DIST1 */ 288848b8605Smrg "result.(nineteen)", /* VARYING_SLOT_PRIMITIVE_ID */ 289848b8605Smrg "result.(twenty)", /* VARYING_SLOT_LAYER */ 290848b8605Smrg "result.(twenty-one)", /* VARYING_SLOT_VIEWPORT */ 291848b8605Smrg "result.(twenty-two)", /* VARYING_SLOT_FACE */ 292848b8605Smrg "result.(twenty-three)", /* VARYING_SLOT_PNTC */ 293b8e80941Smrg "result.(twenty-four)", /* VARYING_SLOT_TESS_LEVEL_OUTER */ 294b8e80941Smrg "result.(twenty-five)", /* VARYING_SLOT_TESS_LEVEL_INNER */ 295b8e80941Smrg "result.(twenty-six)", /* VARYING_SLOT_CULL_DIST0 */ 296b8e80941Smrg "result.(twenty-seven)", /* VARYING_SLOT_CULL_DIST1 */ 297b8e80941Smrg "result.(twenty-eight)", /* VARYING_SLOT_BOUNDING_BOX0 */ 298b8e80941Smrg "result.(twenty-nine)", /* VARYING_SLOT_BOUNDING_BOX1 */ 299b8e80941Smrg "result.(thirty)", /* VARYING_SLOT_VIEW_INDEX */ 300848b8605Smrg "result.varying[0]", 301848b8605Smrg "result.varying[1]", 302848b8605Smrg "result.varying[2]", 303848b8605Smrg "result.varying[3]", 304848b8605Smrg "result.varying[4]", 305848b8605Smrg "result.varying[5]", 306848b8605Smrg "result.varying[6]", 307848b8605Smrg "result.varying[7]", 308848b8605Smrg "result.varying[8]", 309848b8605Smrg "result.varying[9]", 310848b8605Smrg "result.varying[10]", 311848b8605Smrg "result.varying[11]", 312848b8605Smrg "result.varying[12]", 313848b8605Smrg "result.varying[13]", 314848b8605Smrg "result.varying[14]", 315848b8605Smrg "result.varying[15]", 316848b8605Smrg "result.varying[16]", 317848b8605Smrg "result.varying[17]", 318848b8605Smrg "result.varying[18]", 319848b8605Smrg "result.varying[19]", 320848b8605Smrg "result.varying[20]", 321848b8605Smrg "result.varying[21]", 322848b8605Smrg "result.varying[22]", 323848b8605Smrg "result.varying[23]", 324848b8605Smrg "result.varying[24]", 325848b8605Smrg "result.varying[25]", 326848b8605Smrg "result.varying[26]", 327848b8605Smrg "result.varying[27]", 328848b8605Smrg "result.varying[28]", 329848b8605Smrg "result.varying[29]", 330848b8605Smrg "result.varying[30]", 331848b8605Smrg "result.varying[31]", /* MAX_VARYING = 32 */ 332848b8605Smrg }; 333848b8605Smrg static const char *const fragResults[] = { 334848b8605Smrg "result.depth", /* FRAG_RESULT_DEPTH */ 335848b8605Smrg "result.(one)", /* FRAG_RESULT_STENCIL */ 336848b8605Smrg "result.color", /* FRAG_RESULT_COLOR */ 337848b8605Smrg "result.samplemask", /* FRAG_RESULT_SAMPLE_MASK */ 338848b8605Smrg "result.color[0]", /* FRAG_RESULT_DATA0 (named for GLSL's gl_FragData) */ 339848b8605Smrg "result.color[1]", 340848b8605Smrg "result.color[2]", 341848b8605Smrg "result.color[3]", 342848b8605Smrg "result.color[4]", 343848b8605Smrg "result.color[5]", 344848b8605Smrg "result.color[6]", 345848b8605Smrg "result.color[7]" /* MAX_DRAW_BUFFERS = 8 */ 346848b8605Smrg }; 347848b8605Smrg 348848b8605Smrg /* sanity checks */ 349b8e80941Smrg STATIC_ASSERT(ARRAY_SIZE(vertResults) == VARYING_SLOT_MAX); 350b8e80941Smrg STATIC_ASSERT(ARRAY_SIZE(fragResults) == FRAG_RESULT_MAX); 351848b8605Smrg assert(strcmp(vertResults[VARYING_SLOT_POS], "result.position") == 0); 352848b8605Smrg assert(strcmp(vertResults[VARYING_SLOT_VAR0], "result.varying[0]") == 0); 353848b8605Smrg assert(strcmp(fragResults[FRAG_RESULT_DATA0], "result.color[0]") == 0); 354848b8605Smrg 355848b8605Smrg if (progType == GL_VERTEX_PROGRAM_ARB) { 356b8e80941Smrg assert(index < ARRAY_SIZE(vertResults)); 357848b8605Smrg return vertResults[index]; 358848b8605Smrg } 359848b8605Smrg else { 360848b8605Smrg assert(progType == GL_FRAGMENT_PROGRAM_ARB); 361b8e80941Smrg assert(index < ARRAY_SIZE(fragResults)); 362848b8605Smrg return fragResults[index]; 363848b8605Smrg } 364848b8605Smrg} 365848b8605Smrg 366848b8605Smrg 367848b8605Smrg/** 368848b8605Smrg * Return string representation of the given register. 369848b8605Smrg * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined 370848b8605Smrg * by the ARB/NV program languages so we've taken some liberties here. 371848b8605Smrg * \param f the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc) 372848b8605Smrg * \param index number of the register in the register file 373848b8605Smrg * \param mode the output format/mode/style 374848b8605Smrg * \param prog pointer to containing program 375848b8605Smrg */ 376848b8605Smrgstatic const char * 377848b8605Smrgreg_string(gl_register_file f, GLint index, gl_prog_print_mode mode, 378b8e80941Smrg GLboolean relAddr, const struct gl_program *prog) 379848b8605Smrg{ 380848b8605Smrg static char str[100]; 381848b8605Smrg const char *addr = relAddr ? "ADDR+" : ""; 382848b8605Smrg 383848b8605Smrg str[0] = 0; 384848b8605Smrg 385848b8605Smrg switch (mode) { 386848b8605Smrg case PROG_PRINT_DEBUG: 387848b8605Smrg sprintf(str, "%s[%s%d]", 388848b8605Smrg _mesa_register_file_name(f), addr, index); 389848b8605Smrg break; 390848b8605Smrg 391848b8605Smrg case PROG_PRINT_ARB: 392848b8605Smrg switch (f) { 393848b8605Smrg case PROGRAM_INPUT: 394848b8605Smrg sprintf(str, "%s", arb_input_attrib_string(index, prog->Target)); 395848b8605Smrg break; 396848b8605Smrg case PROGRAM_OUTPUT: 397848b8605Smrg sprintf(str, "%s", arb_output_attrib_string(index, prog->Target)); 398848b8605Smrg break; 399848b8605Smrg case PROGRAM_TEMPORARY: 400848b8605Smrg sprintf(str, "temp%d", index); 401848b8605Smrg break; 402848b8605Smrg case PROGRAM_CONSTANT: /* extension */ 403848b8605Smrg sprintf(str, "constant[%s%d]", addr, index); 404848b8605Smrg break; 405848b8605Smrg case PROGRAM_UNIFORM: /* extension */ 406848b8605Smrg sprintf(str, "uniform[%s%d]", addr, index); 407848b8605Smrg break; 408848b8605Smrg case PROGRAM_SYSTEM_VALUE: 409848b8605Smrg sprintf(str, "sysvalue[%s%d]", addr, index); 410848b8605Smrg break; 411848b8605Smrg case PROGRAM_STATE_VAR: 412848b8605Smrg { 413848b8605Smrg struct gl_program_parameter *param 414848b8605Smrg = prog->Parameters->Parameters + index; 415848b8605Smrg char *state = _mesa_program_state_string(param->StateIndexes); 416848b8605Smrg sprintf(str, "%s", state); 417848b8605Smrg free(state); 418848b8605Smrg } 419848b8605Smrg break; 420848b8605Smrg case PROGRAM_ADDRESS: 421848b8605Smrg sprintf(str, "A%d", index); 422848b8605Smrg break; 423848b8605Smrg default: 424848b8605Smrg _mesa_problem(NULL, "bad file in reg_string()"); 425848b8605Smrg } 426848b8605Smrg break; 427848b8605Smrg 428848b8605Smrg default: 429848b8605Smrg _mesa_problem(NULL, "bad mode in reg_string()"); 430848b8605Smrg } 431848b8605Smrg 432848b8605Smrg return str; 433848b8605Smrg} 434848b8605Smrg 435848b8605Smrg 436848b8605Smrg/** 437848b8605Smrg * Return a string representation of the given swizzle word. 438848b8605Smrg * If extended is true, use extended (comma-separated) format. 439848b8605Smrg * \param swizzle the swizzle field 440848b8605Smrg * \param negateBase 4-bit negation vector 441848b8605Smrg * \param extended if true, also allow 0, 1 values 442848b8605Smrg */ 443848b8605Smrgconst char * 444848b8605Smrg_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended) 445848b8605Smrg{ 446848b8605Smrg static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */ 447848b8605Smrg static char s[20]; 448848b8605Smrg GLuint i = 0; 449848b8605Smrg 450848b8605Smrg if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0) 451848b8605Smrg return ""; /* no swizzle/negation */ 452848b8605Smrg 453848b8605Smrg if (!extended) 454848b8605Smrg s[i++] = '.'; 455848b8605Smrg 456848b8605Smrg if (negateMask & NEGATE_X) 457848b8605Smrg s[i++] = '-'; 458848b8605Smrg s[i++] = swz[GET_SWZ(swizzle, 0)]; 459848b8605Smrg 460848b8605Smrg if (extended) { 461848b8605Smrg s[i++] = ','; 462848b8605Smrg } 463848b8605Smrg 464848b8605Smrg if (negateMask & NEGATE_Y) 465848b8605Smrg s[i++] = '-'; 466848b8605Smrg s[i++] = swz[GET_SWZ(swizzle, 1)]; 467848b8605Smrg 468848b8605Smrg if (extended) { 469848b8605Smrg s[i++] = ','; 470848b8605Smrg } 471848b8605Smrg 472848b8605Smrg if (negateMask & NEGATE_Z) 473848b8605Smrg s[i++] = '-'; 474848b8605Smrg s[i++] = swz[GET_SWZ(swizzle, 2)]; 475848b8605Smrg 476848b8605Smrg if (extended) { 477848b8605Smrg s[i++] = ','; 478848b8605Smrg } 479848b8605Smrg 480848b8605Smrg if (negateMask & NEGATE_W) 481848b8605Smrg s[i++] = '-'; 482848b8605Smrg s[i++] = swz[GET_SWZ(swizzle, 3)]; 483848b8605Smrg 484848b8605Smrg s[i] = 0; 485848b8605Smrg return s; 486848b8605Smrg} 487848b8605Smrg 488848b8605Smrg 489848b8605Smrgvoid 490848b8605Smrg_mesa_print_swizzle(GLuint swizzle) 491848b8605Smrg{ 492848b8605Smrg if (swizzle == SWIZZLE_XYZW) { 493848b8605Smrg printf(".xyzw\n"); 494848b8605Smrg } 495848b8605Smrg else { 496848b8605Smrg const char *s = _mesa_swizzle_string(swizzle, 0, 0); 497848b8605Smrg printf("%s\n", s); 498848b8605Smrg } 499848b8605Smrg} 500848b8605Smrg 501848b8605Smrg 502848b8605Smrgconst char * 503848b8605Smrg_mesa_writemask_string(GLuint writeMask) 504848b8605Smrg{ 505848b8605Smrg static char s[10]; 506848b8605Smrg GLuint i = 0; 507848b8605Smrg 508848b8605Smrg if (writeMask == WRITEMASK_XYZW) 509848b8605Smrg return ""; 510848b8605Smrg 511848b8605Smrg s[i++] = '.'; 512848b8605Smrg if (writeMask & WRITEMASK_X) 513848b8605Smrg s[i++] = 'x'; 514848b8605Smrg if (writeMask & WRITEMASK_Y) 515848b8605Smrg s[i++] = 'y'; 516848b8605Smrg if (writeMask & WRITEMASK_Z) 517848b8605Smrg s[i++] = 'z'; 518848b8605Smrg if (writeMask & WRITEMASK_W) 519848b8605Smrg s[i++] = 'w'; 520848b8605Smrg 521848b8605Smrg s[i] = 0; 522848b8605Smrg return s; 523848b8605Smrg} 524848b8605Smrg 525848b8605Smrg 526848b8605Smrgstatic void 527848b8605Smrgfprint_dst_reg(FILE * f, 528848b8605Smrg const struct prog_dst_register *dstReg, 529848b8605Smrg gl_prog_print_mode mode, 530848b8605Smrg const struct gl_program *prog) 531848b8605Smrg{ 532848b8605Smrg fprintf(f, "%s%s", 533848b8605Smrg reg_string((gl_register_file) dstReg->File, 534b8e80941Smrg dstReg->Index, mode, dstReg->RelAddr, prog), 535848b8605Smrg _mesa_writemask_string(dstReg->WriteMask)); 536848b8605Smrg 537848b8605Smrg#if 0 538848b8605Smrg fprintf(f, "%s[%d]%s", 539848b8605Smrg _mesa_register_file_name((gl_register_file) dstReg->File), 540848b8605Smrg dstReg->Index, 541848b8605Smrg _mesa_writemask_string(dstReg->WriteMask)); 542848b8605Smrg#endif 543848b8605Smrg} 544848b8605Smrg 545848b8605Smrg 546848b8605Smrgstatic void 547848b8605Smrgfprint_src_reg(FILE *f, 548848b8605Smrg const struct prog_src_register *srcReg, 549848b8605Smrg gl_prog_print_mode mode, 550848b8605Smrg const struct gl_program *prog) 551848b8605Smrg{ 552b8e80941Smrg fprintf(f, "%s%s", 553848b8605Smrg reg_string((gl_register_file) srcReg->File, 554b8e80941Smrg srcReg->Index, mode, srcReg->RelAddr, prog), 555848b8605Smrg _mesa_swizzle_string(srcReg->Swizzle, 556b8e80941Smrg srcReg->Negate, GL_FALSE)); 557848b8605Smrg#if 0 558848b8605Smrg fprintf(f, "%s[%d]%s", 559848b8605Smrg _mesa_register_file_name((gl_register_file) srcReg->File), 560848b8605Smrg srcReg->Index, 561848b8605Smrg _mesa_swizzle_string(srcReg->Swizzle, 562848b8605Smrg srcReg->Negate, GL_FALSE)); 563848b8605Smrg#endif 564848b8605Smrg} 565848b8605Smrg 566848b8605Smrg 567848b8605Smrgvoid 568848b8605Smrg_mesa_fprint_alu_instruction(FILE *f, 569848b8605Smrg const struct prog_instruction *inst, 570848b8605Smrg const char *opcode_string, GLuint numRegs, 571848b8605Smrg gl_prog_print_mode mode, 572848b8605Smrg const struct gl_program *prog) 573848b8605Smrg{ 574848b8605Smrg GLuint j; 575848b8605Smrg 576848b8605Smrg fprintf(f, "%s", opcode_string); 577848b8605Smrg 578848b8605Smrg /* frag prog only */ 579b8e80941Smrg if (inst->Saturate) 580848b8605Smrg fprintf(f, "_SAT"); 581848b8605Smrg 582848b8605Smrg fprintf(f, " "); 583848b8605Smrg if (inst->DstReg.File != PROGRAM_UNDEFINED) { 584848b8605Smrg fprint_dst_reg(f, &inst->DstReg, mode, prog); 585848b8605Smrg } 586848b8605Smrg else { 587848b8605Smrg fprintf(f, " ???"); 588848b8605Smrg } 589848b8605Smrg 590848b8605Smrg if (numRegs > 0) 591848b8605Smrg fprintf(f, ", "); 592848b8605Smrg 593848b8605Smrg for (j = 0; j < numRegs; j++) { 594848b8605Smrg fprint_src_reg(f, inst->SrcReg + j, mode, prog); 595848b8605Smrg if (j + 1 < numRegs) 596848b8605Smrg fprintf(f, ", "); 597848b8605Smrg } 598848b8605Smrg 599b8e80941Smrg fprintf(f, ";\n"); 600848b8605Smrg} 601848b8605Smrg 602848b8605Smrg 603848b8605Smrgvoid 604848b8605Smrg_mesa_print_alu_instruction(const struct prog_instruction *inst, 605848b8605Smrg const char *opcode_string, GLuint numRegs) 606848b8605Smrg{ 607848b8605Smrg _mesa_fprint_alu_instruction(stderr, inst, opcode_string, 608848b8605Smrg numRegs, PROG_PRINT_DEBUG, NULL); 609848b8605Smrg} 610848b8605Smrg 611848b8605Smrg 612848b8605Smrg/** 613848b8605Smrg * Print a single vertex/fragment program instruction. 614848b8605Smrg */ 615848b8605SmrgGLint 616848b8605Smrg_mesa_fprint_instruction_opt(FILE *f, 617848b8605Smrg const struct prog_instruction *inst, 618848b8605Smrg GLint indent, 619848b8605Smrg gl_prog_print_mode mode, 620848b8605Smrg const struct gl_program *prog) 621848b8605Smrg{ 622848b8605Smrg GLint i; 623848b8605Smrg 624848b8605Smrg if (inst->Opcode == OPCODE_ELSE || 625848b8605Smrg inst->Opcode == OPCODE_ENDIF || 626848b8605Smrg inst->Opcode == OPCODE_ENDLOOP || 627848b8605Smrg inst->Opcode == OPCODE_ENDSUB) { 628848b8605Smrg indent -= 3; 629848b8605Smrg } 630848b8605Smrg for (i = 0; i < indent; i++) { 631848b8605Smrg fprintf(f, " "); 632848b8605Smrg } 633848b8605Smrg 634848b8605Smrg switch (inst->Opcode) { 635848b8605Smrg case OPCODE_SWZ: 636848b8605Smrg fprintf(f, "SWZ"); 637b8e80941Smrg if (inst->Saturate) 638848b8605Smrg fprintf(f, "_SAT"); 639848b8605Smrg fprintf(f, " "); 640848b8605Smrg fprint_dst_reg(f, &inst->DstReg, mode, prog); 641848b8605Smrg fprintf(f, ", %s[%d], %s", 642848b8605Smrg _mesa_register_file_name((gl_register_file) inst->SrcReg[0].File), 643848b8605Smrg inst->SrcReg[0].Index, 644848b8605Smrg _mesa_swizzle_string(inst->SrcReg[0].Swizzle, 645848b8605Smrg inst->SrcReg[0].Negate, GL_TRUE)); 646b8e80941Smrg fprintf(f, ";\n"); 647848b8605Smrg break; 648848b8605Smrg case OPCODE_TEX: 649848b8605Smrg case OPCODE_TXP: 650848b8605Smrg case OPCODE_TXL: 651848b8605Smrg case OPCODE_TXB: 652848b8605Smrg case OPCODE_TXD: 653848b8605Smrg fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); 654b8e80941Smrg if (inst->Saturate) 655848b8605Smrg fprintf(f, "_SAT"); 656848b8605Smrg fprintf(f, " "); 657848b8605Smrg fprint_dst_reg(f, &inst->DstReg, mode, prog); 658848b8605Smrg fprintf(f, ", "); 659848b8605Smrg fprint_src_reg(f, &inst->SrcReg[0], mode, prog); 660848b8605Smrg if (inst->Opcode == OPCODE_TXD) { 661848b8605Smrg fprintf(f, ", "); 662848b8605Smrg fprint_src_reg(f, &inst->SrcReg[1], mode, prog); 663848b8605Smrg fprintf(f, ", "); 664848b8605Smrg fprint_src_reg(f, &inst->SrcReg[2], mode, prog); 665848b8605Smrg } 666848b8605Smrg fprintf(f, ", texture[%d], ", inst->TexSrcUnit); 667848b8605Smrg switch (inst->TexSrcTarget) { 668848b8605Smrg case TEXTURE_1D_INDEX: fprintf(f, "1D"); break; 669848b8605Smrg case TEXTURE_2D_INDEX: fprintf(f, "2D"); break; 670848b8605Smrg case TEXTURE_3D_INDEX: fprintf(f, "3D"); break; 671848b8605Smrg case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break; 672848b8605Smrg case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break; 673848b8605Smrg case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break; 674848b8605Smrg case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break; 675848b8605Smrg default: 676848b8605Smrg ; 677848b8605Smrg } 678848b8605Smrg if (inst->TexShadow) 679848b8605Smrg fprintf(f, " SHADOW"); 680b8e80941Smrg fprintf(f, ";\n"); 681848b8605Smrg break; 682848b8605Smrg 683848b8605Smrg case OPCODE_KIL: 684848b8605Smrg fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); 685848b8605Smrg fprintf(f, " "); 686848b8605Smrg fprint_src_reg(f, &inst->SrcReg[0], mode, prog); 687b8e80941Smrg fprintf(f, ";\n"); 688848b8605Smrg break; 689848b8605Smrg case OPCODE_ARL: 690848b8605Smrg fprintf(f, "ARL "); 691848b8605Smrg fprint_dst_reg(f, &inst->DstReg, mode, prog); 692848b8605Smrg fprintf(f, ", "); 693848b8605Smrg fprint_src_reg(f, &inst->SrcReg[0], mode, prog); 694b8e80941Smrg fprintf(f, ";\n"); 695848b8605Smrg break; 696848b8605Smrg case OPCODE_IF: 697b8e80941Smrg fprintf(f, "IF "); 698b8e80941Smrg fprint_src_reg(f, &inst->SrcReg[0], mode, prog); 699b8e80941Smrg fprintf(f, "; "); 700848b8605Smrg fprintf(f, " # (if false, goto %d)", inst->BranchTarget); 701b8e80941Smrg fprintf(f, ";\n"); 702848b8605Smrg return indent + 3; 703848b8605Smrg case OPCODE_ELSE: 704848b8605Smrg fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget); 705848b8605Smrg return indent + 3; 706848b8605Smrg case OPCODE_ENDIF: 707848b8605Smrg fprintf(f, "ENDIF;\n"); 708848b8605Smrg break; 709848b8605Smrg case OPCODE_BGNLOOP: 710848b8605Smrg fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget); 711848b8605Smrg return indent + 3; 712848b8605Smrg case OPCODE_ENDLOOP: 713848b8605Smrg fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget); 714848b8605Smrg break; 715848b8605Smrg case OPCODE_BRK: 716848b8605Smrg case OPCODE_CONT: 717b8e80941Smrg fprintf(f, "%s; # (goto %d)", 718848b8605Smrg _mesa_opcode_string(inst->Opcode), 719848b8605Smrg inst->BranchTarget); 720b8e80941Smrg fprintf(f, ";\n"); 721848b8605Smrg break; 722848b8605Smrg 723848b8605Smrg case OPCODE_BGNSUB: 724848b8605Smrg fprintf(f, "BGNSUB"); 725b8e80941Smrg fprintf(f, ";\n"); 726848b8605Smrg return indent + 3; 727848b8605Smrg case OPCODE_ENDSUB: 728848b8605Smrg if (mode == PROG_PRINT_DEBUG) { 729848b8605Smrg fprintf(f, "ENDSUB"); 730b8e80941Smrg fprintf(f, ";\n"); 731848b8605Smrg } 732848b8605Smrg break; 733848b8605Smrg case OPCODE_CAL: 734848b8605Smrg fprintf(f, "CAL %u", inst->BranchTarget); 735b8e80941Smrg fprintf(f, ";\n"); 736848b8605Smrg break; 737848b8605Smrg case OPCODE_RET: 738b8e80941Smrg fprintf(f, "RET"); 739b8e80941Smrg fprintf(f, ";\n"); 740848b8605Smrg break; 741848b8605Smrg 742848b8605Smrg case OPCODE_END: 743848b8605Smrg fprintf(f, "END\n"); 744848b8605Smrg break; 745848b8605Smrg case OPCODE_NOP: 746848b8605Smrg if (mode == PROG_PRINT_DEBUG) { 747848b8605Smrg fprintf(f, "NOP"); 748b8e80941Smrg fprintf(f, ";\n"); 749848b8605Smrg } 750848b8605Smrg break; 751848b8605Smrg /* XXX may need other special-case instructions */ 752848b8605Smrg default: 753848b8605Smrg if (inst->Opcode < MAX_OPCODE) { 754848b8605Smrg /* typical alu instruction */ 755848b8605Smrg _mesa_fprint_alu_instruction(f, inst, 756848b8605Smrg _mesa_opcode_string(inst->Opcode), 757848b8605Smrg _mesa_num_inst_src_regs(inst->Opcode), 758848b8605Smrg mode, prog); 759848b8605Smrg } 760848b8605Smrg else { 761848b8605Smrg _mesa_fprint_alu_instruction(f, inst, 762848b8605Smrg _mesa_opcode_string(inst->Opcode), 763848b8605Smrg 3/*_mesa_num_inst_src_regs(inst->Opcode)*/, 764848b8605Smrg mode, prog); 765848b8605Smrg } 766848b8605Smrg break; 767848b8605Smrg } 768848b8605Smrg return indent; 769848b8605Smrg} 770848b8605Smrg 771848b8605Smrg 772848b8605SmrgGLint 773848b8605Smrg_mesa_print_instruction_opt(const struct prog_instruction *inst, 774848b8605Smrg GLint indent, 775848b8605Smrg gl_prog_print_mode mode, 776848b8605Smrg const struct gl_program *prog) 777848b8605Smrg{ 778848b8605Smrg return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog); 779848b8605Smrg} 780848b8605Smrg 781848b8605Smrg 782848b8605Smrgvoid 783848b8605Smrg_mesa_print_instruction(const struct prog_instruction *inst) 784848b8605Smrg{ 785848b8605Smrg /* note: 4th param should be ignored for PROG_PRINT_DEBUG */ 786848b8605Smrg _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL); 787848b8605Smrg} 788848b8605Smrg 789848b8605Smrg 790848b8605Smrg 791848b8605Smrg/** 792848b8605Smrg * Print program, with options. 793848b8605Smrg */ 794848b8605Smrgvoid 795848b8605Smrg_mesa_fprint_program_opt(FILE *f, 796848b8605Smrg const struct gl_program *prog, 797848b8605Smrg gl_prog_print_mode mode, 798848b8605Smrg GLboolean lineNumbers) 799848b8605Smrg{ 800848b8605Smrg GLuint i, indent = 0; 801848b8605Smrg 802848b8605Smrg switch (prog->Target) { 803848b8605Smrg case GL_VERTEX_PROGRAM_ARB: 804848b8605Smrg if (mode == PROG_PRINT_ARB) 805848b8605Smrg fprintf(f, "!!ARBvp1.0\n"); 806848b8605Smrg else 807848b8605Smrg fprintf(f, "# Vertex Program/Shader %u\n", prog->Id); 808848b8605Smrg break; 809848b8605Smrg case GL_FRAGMENT_PROGRAM_ARB: 810848b8605Smrg if (mode == PROG_PRINT_ARB) 811848b8605Smrg fprintf(f, "!!ARBfp1.0\n"); 812848b8605Smrg else 813848b8605Smrg fprintf(f, "# Fragment Program/Shader %u\n", prog->Id); 814848b8605Smrg break; 815b8e80941Smrg case GL_GEOMETRY_PROGRAM_NV: 816848b8605Smrg fprintf(f, "# Geometry Shader\n"); 817848b8605Smrg } 818848b8605Smrg 819b8e80941Smrg for (i = 0; i < prog->arb.NumInstructions; i++) { 820848b8605Smrg if (lineNumbers) 821848b8605Smrg fprintf(f, "%3d: ", i); 822b8e80941Smrg indent = _mesa_fprint_instruction_opt(f, prog->arb.Instructions + i, 823848b8605Smrg indent, mode, prog); 824848b8605Smrg } 825848b8605Smrg} 826848b8605Smrg 827848b8605Smrg 828848b8605Smrg/** 829848b8605Smrg * Print program to stderr, default options. 830848b8605Smrg */ 831848b8605Smrgvoid 832848b8605Smrg_mesa_print_program(const struct gl_program *prog) 833848b8605Smrg{ 834848b8605Smrg _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE); 835848b8605Smrg} 836848b8605Smrg 837848b8605Smrg 838848b8605Smrg/** 839848b8605Smrg * Return binary representation of 64-bit value (as a string). 840848b8605Smrg * Insert a comma to separate each group of 8 bits. 841848b8605Smrg * Note we return a pointer to local static storage so this is not 842848b8605Smrg * re-entrant, etc. 843848b8605Smrg * XXX move to imports.[ch] if useful elsewhere. 844848b8605Smrg */ 845848b8605Smrgstatic const char * 846848b8605Smrgbinary(GLbitfield64 val) 847848b8605Smrg{ 848848b8605Smrg static char buf[80]; 849848b8605Smrg GLint i, len = 0; 850848b8605Smrg for (i = 63; i >= 0; --i) { 851848b8605Smrg if (val & (BITFIELD64_BIT(i))) 852848b8605Smrg buf[len++] = '1'; 853848b8605Smrg else if (len > 0 || i == 0) 854848b8605Smrg buf[len++] = '0'; 855848b8605Smrg if (len > 0 && ((i-1) % 8) == 7) 856848b8605Smrg buf[len++] = ','; 857848b8605Smrg } 858848b8605Smrg buf[len] = '\0'; 859848b8605Smrg return buf; 860848b8605Smrg} 861848b8605Smrg 862848b8605Smrg 863848b8605Smrg/** 864848b8605Smrg * Print all of a program's parameters/fields to given file. 865848b8605Smrg */ 866848b8605Smrgstatic void 867848b8605Smrg_mesa_fprint_program_parameters(FILE *f, 868848b8605Smrg struct gl_context *ctx, 869848b8605Smrg const struct gl_program *prog) 870848b8605Smrg{ 871848b8605Smrg GLuint i; 872848b8605Smrg 873848b8605Smrg fprintf(f, "InputsRead: %" PRIx64 " (0b%s)\n", 874b8e80941Smrg (uint64_t) prog->info.inputs_read, binary(prog->info.inputs_read)); 875848b8605Smrg fprintf(f, "OutputsWritten: %" PRIx64 " (0b%s)\n", 876b8e80941Smrg (uint64_t) prog->info.outputs_written, 877b8e80941Smrg binary(prog->info.outputs_written)); 878b8e80941Smrg fprintf(f, "NumInstructions=%d\n", prog->arb.NumInstructions); 879b8e80941Smrg fprintf(f, "NumTemporaries=%d\n", prog->arb.NumTemporaries); 880b8e80941Smrg fprintf(f, "NumParameters=%d\n", prog->arb.NumParameters); 881b8e80941Smrg fprintf(f, "NumAttributes=%d\n", prog->arb.NumAttributes); 882b8e80941Smrg fprintf(f, "NumAddressRegs=%d\n", prog->arb.NumAddressRegs); 883848b8605Smrg fprintf(f, "IndirectRegisterFiles: 0x%x (0b%s)\n", 884b8e80941Smrg prog->arb.IndirectRegisterFiles, 885b8e80941Smrg binary(prog->arb.IndirectRegisterFiles)); 886848b8605Smrg fprintf(f, "SamplersUsed: 0x%x (0b%s)\n", 887848b8605Smrg prog->SamplersUsed, binary(prog->SamplersUsed)); 888848b8605Smrg fprintf(f, "Samplers=[ "); 889848b8605Smrg for (i = 0; i < MAX_SAMPLERS; i++) { 890848b8605Smrg fprintf(f, "%d ", prog->SamplerUnits[i]); 891848b8605Smrg } 892848b8605Smrg fprintf(f, "]\n"); 893848b8605Smrg 894848b8605Smrg _mesa_load_state_parameters(ctx, prog->Parameters); 895848b8605Smrg 896848b8605Smrg#if 0 897848b8605Smrg fprintf(f, "Local Params:\n"); 898848b8605Smrg for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ 899848b8605Smrg const GLfloat *p = prog->LocalParams[i]; 900848b8605Smrg fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); 901848b8605Smrg } 902848b8605Smrg#endif 903848b8605Smrg _mesa_print_parameter_list(prog->Parameters); 904848b8605Smrg} 905848b8605Smrg 906848b8605Smrg 907848b8605Smrg/** 908848b8605Smrg * Print all of a program's parameters/fields to stderr. 909848b8605Smrg */ 910848b8605Smrgvoid 911848b8605Smrg_mesa_print_program_parameters(struct gl_context *ctx, const struct gl_program *prog) 912848b8605Smrg{ 913848b8605Smrg _mesa_fprint_program_parameters(stderr, ctx, prog); 914848b8605Smrg} 915848b8605Smrg 916848b8605Smrg 917848b8605Smrg/** 918848b8605Smrg * Print a program parameter list to given file. 919848b8605Smrg */ 920848b8605Smrgstatic void 921848b8605Smrg_mesa_fprint_parameter_list(FILE *f, 922848b8605Smrg const struct gl_program_parameter_list *list) 923848b8605Smrg{ 924848b8605Smrg GLuint i; 925848b8605Smrg 926848b8605Smrg if (!list) 927848b8605Smrg return; 928848b8605Smrg 929848b8605Smrg if (0) 930848b8605Smrg fprintf(f, "param list %p\n", (void *) list); 931848b8605Smrg fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags); 932848b8605Smrg for (i = 0; i < list->NumParameters; i++){ 933848b8605Smrg struct gl_program_parameter *param = list->Parameters + i; 934b8e80941Smrg unsigned pvo = list->ParameterValueOffset[i]; 935b8e80941Smrg const GLfloat *v = (GLfloat *) list->ParameterValues + pvo; 936b8e80941Smrg 937848b8605Smrg fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}", 938848b8605Smrg i, param->Size, 939848b8605Smrg _mesa_register_file_name(list->Parameters[i].Type), 940848b8605Smrg param->Name, v[0], v[1], v[2], v[3]); 941848b8605Smrg fprintf(f, "\n"); 942848b8605Smrg } 943848b8605Smrg} 944848b8605Smrg 945848b8605Smrg 946848b8605Smrg/** 947848b8605Smrg * Print a program parameter list to stderr. 948848b8605Smrg */ 949848b8605Smrgvoid 950848b8605Smrg_mesa_print_parameter_list(const struct gl_program_parameter_list *list) 951848b8605Smrg{ 952848b8605Smrg _mesa_fprint_parameter_list(stderr, list); 953848b8605Smrg} 954848b8605Smrg 955848b8605Smrg 956848b8605Smrg/** 957848b8605Smrg * Write shader and associated info to a file. 958848b8605Smrg */ 959848b8605Smrgvoid 960848b8605Smrg_mesa_write_shader_to_file(const struct gl_shader *shader) 961848b8605Smrg{ 962848b8605Smrg const char *type = "????"; 963848b8605Smrg char filename[100]; 964848b8605Smrg FILE *f; 965848b8605Smrg 966848b8605Smrg switch (shader->Stage) { 967848b8605Smrg case MESA_SHADER_FRAGMENT: 968848b8605Smrg type = "frag"; 969848b8605Smrg break; 970b8e80941Smrg case MESA_SHADER_TESS_CTRL: 971b8e80941Smrg type = "tesc"; 972b8e80941Smrg break; 973b8e80941Smrg case MESA_SHADER_TESS_EVAL: 974b8e80941Smrg type = "tese"; 975b8e80941Smrg break; 976848b8605Smrg case MESA_SHADER_VERTEX: 977848b8605Smrg type = "vert"; 978848b8605Smrg break; 979848b8605Smrg case MESA_SHADER_GEOMETRY: 980848b8605Smrg type = "geom"; 981848b8605Smrg break; 982848b8605Smrg case MESA_SHADER_COMPUTE: 983848b8605Smrg type = "comp"; 984848b8605Smrg break; 985b8e80941Smrg default: 986b8e80941Smrg break; 987848b8605Smrg } 988848b8605Smrg 989848b8605Smrg _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type); 990848b8605Smrg f = fopen(filename, "w"); 991848b8605Smrg if (!f) { 992848b8605Smrg fprintf(stderr, "Unable to open %s for writing\n", filename); 993848b8605Smrg return; 994848b8605Smrg } 995848b8605Smrg 996b8e80941Smrg#ifdef DEBUG 997848b8605Smrg fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum); 998b8e80941Smrg#else 999b8e80941Smrg fprintf(f, "/* Shader %u source */\n", shader->Name); 1000b8e80941Smrg#endif 1001848b8605Smrg fputs(shader->Source, f); 1002848b8605Smrg fprintf(f, "\n"); 1003848b8605Smrg 1004848b8605Smrg fprintf(f, "/* Compile status: %s */\n", 1005848b8605Smrg shader->CompileStatus ? "ok" : "fail"); 1006848b8605Smrg fprintf(f, "/* Log Info: */\n"); 1007848b8605Smrg if (shader->InfoLog) { 1008848b8605Smrg fputs(shader->InfoLog, f); 1009848b8605Smrg } 1010848b8605Smrg 1011848b8605Smrg fclose(f); 1012848b8605Smrg} 1013848b8605Smrg 1014848b8605Smrg 1015848b8605Smrg/** 1016848b8605Smrg * Append the shader's uniform info/values to the shader log file. 1017848b8605Smrg * The log file will typically have been created by the 1018848b8605Smrg * _mesa_write_shader_to_file function. 1019848b8605Smrg */ 1020848b8605Smrgvoid 1021b8e80941Smrg_mesa_append_uniforms_to_file(const struct gl_program *prog) 1022848b8605Smrg{ 1023848b8605Smrg const char *type; 1024848b8605Smrg char filename[100]; 1025848b8605Smrg FILE *f; 1026848b8605Smrg 1027b8e80941Smrg if (prog->info.stage == MESA_SHADER_FRAGMENT) 1028848b8605Smrg type = "frag"; 1029848b8605Smrg else 1030848b8605Smrg type = "vert"; 1031848b8605Smrg 1032b8e80941Smrg _mesa_snprintf(filename, sizeof(filename), "shader.%s", type); 1033848b8605Smrg f = fopen(filename, "a"); /* append */ 1034848b8605Smrg if (!f) { 1035848b8605Smrg fprintf(stderr, "Unable to open %s for appending\n", filename); 1036848b8605Smrg return; 1037848b8605Smrg } 1038848b8605Smrg 1039848b8605Smrg fprintf(f, "/* First-draw parameters / constants */\n"); 1040848b8605Smrg fprintf(f, "/*\n"); 1041848b8605Smrg _mesa_fprint_parameter_list(f, prog->Parameters); 1042848b8605Smrg fprintf(f, "*/\n"); 1043848b8605Smrg 1044848b8605Smrg fclose(f); 1045848b8605Smrg} 1046