Path: blob/21.2-virgl/src/freedreno/decode/pgmdump.c
4565 views
/*1* Copyright (c) 2012 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*/2223#include <fcntl.h>24#include <stdint.h>25#include <stdio.h>26#include <stdlib.h>27#include <string.h>28#include <unistd.h>29#include <sys/stat.h>30#include <sys/types.h>3132#include "disasm.h"33#include "io.h"34#include "redump.h"3536#define ASCII_XOR 0xff37#include "util.h"3839struct pgm_header {40uint32_t size;41uint32_t unknown1;42uint32_t unknown2;43uint32_t revision;44uint32_t unknown4;45uint32_t unknown5;46uint32_t unknown6;47uint32_t unknown7;48uint32_t unknown8;49uint32_t num_attribs;50uint32_t num_uniforms;51uint32_t num_samplers;52uint32_t num_varyings;53uint32_t num_uniformblocks;54};5556struct vs_header {57uint32_t unknown1; /* seems to be # of sections up to and including shader */58uint32_t unknown2; /* seems to be low byte or so of SQ_PROGRAM_CNTL */59uint32_t unknown3;60uint32_t unknown4;61uint32_t unknown5;62uint32_t unknown6;63uint32_t unknown7;64uint32_t unknown8;65uint32_t unknown9; /* seems to be # of sections following shader */66};6768struct fs_header {69uint32_t unknown1;70};71/*72// Covers a lot of type_info73// varying, attribute, uniform, sampler74type_info & 0xFF75if ((type_info >> 8) == 0x8b) // vector760x50 = vec2770x51 = vec3780x52 = vec4790x53 = ivec2800x54 = ivec3810x55 = ivec4820x56 = bool // Why is this in vector?830x57 = bvec2840x58 = bvec3850x59 = bvec4860x5a = mat2870x5b = mat3880x5c = mat4890x5a = mat2x2 // Same as mat2900x65 = mat2x3910x66 = mat2x4920x67 = mat3x2930x5b = mat3x3 // Same as mat3940x68 = mat3x4950x69 = mat4x2960x6a = mat4x3970x5c = mat4x4 // same as mat4980x5e = sampler2D990x5f = sampler3D1000x60 = samplerCube // XXX: Doesn't work1010x62 = sampler2DShadow1020xc6 = uvec21030xc7 = uvec31040xc8 = uvec4105else if ((type_info >> 8) == 0x8d) // GLES3 samplers1060xC1 = sampler2DArray1070xC4 = sampler2DArrayShadow1080xC5 = samplerCubeShadow1090xCA = isampler2D1100xCB = isampler3D1110xCC = isamplerCube1120xD2 = usampler2D1130xD3 = usampler3D1140xD4 = usamplerCube1150xD7 = isampler2DArray1160xD7 = usampler2DArray // Is the same as isampler2DArray?117else // 0x14 = single1180x04 = int1190x05 = uint1200x06 = float121*/122struct attribute {123uint32_t type_info;124uint32_t reg; /* seems to be the register the fetch instruction loads to */125uint32_t const_idx; /* the CONST() indx value for sampler */126uint32_t unknown2;127uint32_t unknown3;128uint32_t unknown4;129uint32_t unknown5;130char name[];131};132133struct uniform {134uint32_t type_info;135uint32_t unknown2;136uint32_t unknown3;137uint32_t unknown4;138uint32_t const_base; /* const base register (for uniforms that take more than139one const reg, ie. matrices) */140uint32_t unknown6;141uint32_t const_reg; /* the const register holding the value */142uint32_t unknown7;143uint32_t unknown8;144uint32_t unknown9;145union {146struct {147char name[1];148} v1;149struct {150uint32_t unknown10;151uint32_t unknown11;152uint32_t unknown12;153char name[];154} v2;155};156};157158struct uniformblockmember {159uint32_t type_info;160uint32_t is_array;161uint32_t array_size; /* elements in the array */162uint32_t unknown2; /* Same as array_size */163uint32_t164unknown3; /* Seems to be a offset within UBO in vertex (by components) */165uint32_t unknown4;166uint32_t167unknown5; /* Seems to be a offset within UBO in fragment (by vec4) */168uint32_t unknown6;169uint32_t unknown7;170uint32_t unknown8;171uint32_t unknown9; /* UBO block index? */172uint32_t unknown10;173uint32_t unknown11;174uint32_t unknown12;175char name[];176};177178struct uniformblock {179uint32_t type_info;180uint32_t unknown1;181uint32_t unknown2;182uint32_t unknown3;183uint32_t unknown4;184uint32_t num_members;185uint32_t num_members2;186uint32_t unknown5;187uint32_t unknown6;188uint32_t unknown7;189char name[];190};191192struct sampler {193uint32_t type_info;194uint32_t is_array;195uint32_t array_size; /* elements in the array */196uint32_t unknown4; /* same as array_size */197uint32_t unknown5;198uint32_t unknown6;199uint32_t const_idx; /* the CONST() indx value for the sampler */200uint32_t unknown7;201char name[];202};203204struct varying {205uint32_t type_info;206uint32_t unknown2;207uint32_t unknown3;208uint32_t reg; /* the register holding the value (on entry to the shader) */209char name[];210};211212struct output {213uint32_t type_info;214uint32_t unknown2;215uint32_t unknown3;216uint32_t unknown4;217uint32_t unknown5;218uint32_t unknown6;219uint32_t unknown7;220uint32_t unknown8;221char name[];222};223224struct constant {225uint32_t unknown1;226uint32_t unknown2;227uint32_t unknown3;228uint32_t const_idx;229float val[];230};231232struct state {233char *buf;234int sz;235struct pgm_header *hdr;236struct attribute *attribs[32]; /* don't really know the upper limit.. */237struct uniform *uniforms[32];238struct sampler *samplers[32];239struct varying *varyings[32];240struct {241struct uniformblock *header;242struct uniformblockmember **members; /* GL ES 3.0 spec mandates minimum24316K support. a3xx supports 65K */244} uniformblocks[24]; /* Maximum a330 supports */245struct output *outputs[0]; /* I guess only one?? */246};247248static const char *infile;249static int full_dump = 1;250static int dump_shaders = 0;251static int gpu_id;252253static char *254find_sect_end(char *buf, int sz)255{256uint8_t *ptr = (uint8_t *)buf;257uint8_t *end = ptr + sz - 3;258259while (ptr < end) {260uint32_t d = 0;261262d |= ptr[0] << 0;263d |= ptr[1] << 8;264d |= ptr[2] << 16;265d |= ptr[3] << 24;266267/* someone at QC likes baseball */268if (d == 0xba5eba11)269return (char *)ptr;270271ptr++;272}273return NULL;274}275276static void *277next_sect(struct state *state, int *sect_size)278{279char *end = find_sect_end(state->buf, state->sz);280void *sect;281282if (!end)283return NULL;284285*sect_size = end - state->buf;286287/* copy the section to keep things nicely 32b aligned: */288sect = malloc(ALIGN(*sect_size, 4));289memcpy(sect, state->buf, *sect_size);290291state->sz -= *sect_size + 4;292state->buf = end + 4;293294return sect;295}296297static int298valid_type(uint32_t type_info)299{300switch ((type_info >> 8) & 0xff) {301case 0x8b: /* vector */302case 0x8d: /* GLES3 samplers */303case 0x14: /* float */304return 1;305default:306return 0;307}308}309310#if 0311static int valid_uniformblock(uint32_t type_info)312{313if (type_info == 0x128)314return 1;315return 0;316}317#endif318319static void320dump_attribute(struct attribute *attrib)321{322printf("\tR%d, CONST(%d): %s\n", attrib->reg, attrib->const_idx,323attrib->name);324}325326static inline int327is_uniform_v2(struct uniform *uniform)328{329/* TODO maybe this should be based on revision #? */330if (uniform->v2.unknown10 == 0)331return 1;332return 0;333}334335static void336dump_uniform(struct uniform *uniform)337{338char *name = is_uniform_v2(uniform) ? uniform->v2.name : uniform->v1.name;339if (uniform->const_reg == -1) {340printf("\tC%d+: %s\n", uniform->const_base, name);341} else {342printf("\tC%d: %s\n", uniform->const_reg, name);343}344}345346static void347dump_sampler(struct sampler *sampler)348{349printf("\tCONST(%d): %s\n", sampler->const_idx, sampler->name);350}351352static void353dump_varying(struct varying *varying)354{355printf("\tR%d: %s\n", varying->reg, varying->name);356}357358static void359dump_uniformblock(struct uniformblock *uniformblock)360{361printf("\tUniform Block: %s(%d)\n", uniformblock->name,362uniformblock->num_members);363}364365static void366dump_uniformblockmember(struct uniformblockmember *member)367{368printf("Uniform Block member: %s\n", member->name);369}370371static void372dump_output(struct output *output)373{374printf("\tR?: %s\n", output->name);375}376377static void378dump_constant(struct constant *constant)379{380printf("\tC%d: %f, %f, %f, %f\n", constant->const_idx, constant->val[0],381constant->val[1], constant->val[2], constant->val[3]);382}383384/* dump attr/uniform/sampler/varying/const summary: */385static void386dump_short_summary(struct state *state, int nconsts,387struct constant **constants)388{389int i;390391/* dump attr/uniform/sampler/varying/const summary: */392for (i = 0; i < state->hdr->num_varyings; i++) {393dump_varying(state->varyings[i]);394}395for (i = 0; i < state->hdr->num_attribs; i++) {396dump_attribute(state->attribs[i]);397}398for (i = 0; i < state->hdr->num_uniforms; i++) {399dump_uniform(state->uniforms[i]);400}401for (i = 0; i < state->hdr->num_samplers; i++) {402dump_sampler(state->samplers[i]);403}404for (i = 0; i < nconsts - 1; i++) {405if (constants[i]->unknown2 == 0) {406dump_constant(constants[i]);407}408}409printf("\n");410}411412static void413dump_raw_shader(uint32_t *dwords, uint32_t sizedwords, int n, char *ext)414{415static char filename[256];416int fd;417418if (!dump_shaders)419return;420421sprintf(filename, "%.*s-%d.%s", (int)strlen(infile) - 3, infile, n, ext);422fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644);423if (fd != -1) {424write(fd, dwords, sizedwords * 4);425close(fd);426}427}428429static void430dump_shaders_a2xx(struct state *state)431{432int i, sect_size;433uint8_t *ptr;434435/* dump vertex shaders: */436for (i = 0; i < 3; i++) {437struct vs_header *vs_hdr = next_sect(state, §_size);438struct constant *constants[32];439int j, level = 0;440441printf("\n");442443if (full_dump) {444printf("#######################################################\n");445printf("######## VS%d HEADER: (size %d)\n", i, sect_size);446dump_hex((void *)vs_hdr, sect_size);447}448449for (j = 0; j < (int)vs_hdr->unknown1 - 1; j++) {450constants[j] = next_sect(state, §_size);451if (full_dump) {452printf("######## VS%d CONST: (size=%d)\n", i, sect_size);453dump_constant(constants[j]);454dump_hex((char *)constants[j], sect_size);455}456}457458ptr = next_sect(state, §_size);459printf("######## VS%d SHADER: (size=%d)\n", i, sect_size);460if (full_dump) {461dump_hex(ptr, sect_size);462level = 1;463} else {464dump_short_summary(state, vs_hdr->unknown1 - 1, constants);465}466disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level + 1,467MESA_SHADER_VERTEX);468dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "vo");469free(ptr);470471for (j = 0; j < vs_hdr->unknown9; j++) {472ptr = next_sect(state, §_size);473if (full_dump) {474printf("######## VS%d CONST?: (size=%d)\n", i, sect_size);475dump_hex(ptr, sect_size);476}477free(ptr);478}479480for (j = 0; j < vs_hdr->unknown1 - 1; j++) {481free(constants[j]);482}483484free(vs_hdr);485}486487/* dump fragment shaders: */488for (i = 0; i < 1; i++) {489struct fs_header *fs_hdr = next_sect(state, §_size);490struct constant *constants[32];491int j, level = 0;492493printf("\n");494495if (full_dump) {496printf("#######################################################\n");497printf("######## FS%d HEADER: (size %d)\n", i, sect_size);498dump_hex((void *)fs_hdr, sect_size);499}500501for (j = 0; j < fs_hdr->unknown1 - 1; j++) {502constants[j] = next_sect(state, §_size);503if (full_dump) {504printf("######## FS%d CONST: (size=%d)\n", i, sect_size);505dump_constant(constants[j]);506dump_hex((char *)constants[j], sect_size);507}508}509510ptr = next_sect(state, §_size);511printf("######## FS%d SHADER: (size=%d)\n", i, sect_size);512if (full_dump) {513dump_hex(ptr, sect_size);514level = 1;515} else {516dump_short_summary(state, fs_hdr->unknown1 - 1, constants);517}518disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level + 1,519MESA_SHADER_FRAGMENT);520dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "fo");521free(ptr);522523for (j = 0; j < fs_hdr->unknown1 - 1; j++) {524free(constants[j]);525}526527free(fs_hdr);528}529}530531static void532dump_shaders_a3xx(struct state *state)533{534int i, j;535536/* dump vertex shaders: */537for (i = 0; i < 2; i++) {538int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0;539uint8_t *vs_hdr;540struct constant *constants[32];541uint8_t *instrs = NULL;542543vs_hdr = next_sect(state, &hdr_size);544printf("hdr_size=%d\n", hdr_size);545546/* seems like there are two cases, either:547* 1) 152 byte header,548* 2) zero or more 32 byte compiler const sections549* 3) followed by shader instructions550* or, if there are no compiler consts, this can be551* all smashed in one large section552*/553int n;554if (state->hdr->revision >= 0xb)555n = 160;556else if (state->hdr->revision >= 7)557n = 156;558else559n = 152;560if (hdr_size > n) {561instrs = &vs_hdr[n];562instrs_size = hdr_size - n;563hdr_size = n;564compact = 1;565} else {566while (1) {567void *ptr = next_sect(state, §_size);568569if ((sect_size != 32) && (sect_size != 44)) {570/* end of constants: */571instrs = ptr;572instrs_size = sect_size;573break;574}575dump_hex_ascii(ptr, sect_size, 0);576constants[nconsts++] = ptr;577}578}579580printf("\n");581582if (full_dump) {583printf("#######################################################\n");584printf("######## VS%d HEADER: (size %d)\n", i, hdr_size);585dump_hex((void *)vs_hdr, hdr_size);586for (j = 0; j < nconsts; j++) {587printf("######## VS%d CONST: (size=%d)\n", i,588(int)sizeof(constants[i]));589dump_constant(constants[j]);590dump_hex((char *)constants[j], sizeof(constants[j]));591}592}593594printf("######## VS%d SHADER: (size=%d)\n", i, instrs_size);595if (full_dump) {596dump_hex(instrs, instrs_size);597level = 1;598} else {599dump_short_summary(state, nconsts, constants);600}601602if (!compact) {603if (state->hdr->revision >= 7) {604instrs += ALIGN(instrs_size, 8) - instrs_size;605instrs_size = ALIGN(instrs_size, 8);606}607instrs += 32;608instrs_size -= 32;609}610611disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level + 1, stdout,612gpu_id);613dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "vo3");614free(vs_hdr);615}616617/* dump fragment shaders: */618for (i = 0; i < 1; i++) {619int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0;620uint8_t *fs_hdr;621struct constant *constants[32];622uint8_t *instrs = NULL;623624fs_hdr = next_sect(state, &hdr_size);625626printf("hdr_size=%d\n", hdr_size);627/* two cases, similar to vertex shader, but magic # is 200628* (or 208 for newer?)..629*/630int n;631if (state->hdr->revision >= 0xb)632n = 256;633else if (state->hdr->revision >= 8)634n = 208;635else if (state->hdr->revision == 7)636n = 204;637else638n = 200;639640if (hdr_size > n) {641instrs = &fs_hdr[n];642instrs_size = hdr_size - n;643hdr_size = n;644compact = 1;645} else {646while (1) {647void *ptr = next_sect(state, §_size);648649if ((sect_size != 32) && (sect_size != 44)) {650/* end of constants: */651instrs = ptr;652instrs_size = sect_size;653break;654}655656dump_hex_ascii(ptr, sect_size, 0);657constants[nconsts++] = ptr;658}659}660661printf("\n");662663if (full_dump) {664printf("#######################################################\n");665printf("######## FS%d HEADER: (size %d)\n", i, hdr_size);666dump_hex((void *)fs_hdr, hdr_size);667for (j = 0; j < nconsts; j++) {668printf("######## FS%d CONST: (size=%d)\n", i,669(int)sizeof(constants[i]));670dump_constant(constants[j]);671dump_hex((char *)constants[j], sizeof(constants[j]));672}673}674675printf("######## FS%d SHADER: (size=%d)\n", i, instrs_size);676if (full_dump) {677dump_hex(instrs, instrs_size);678level = 1;679} else {680dump_short_summary(state, nconsts, constants);681}682683if (!compact) {684if (state->hdr->revision >= 7) {685instrs += 44;686instrs_size -= 44;687} else {688instrs += 32;689instrs_size -= 32;690}691}692disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level + 1, stdout,693gpu_id);694dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "fo3");695free(fs_hdr);696}697}698699static void700dump_program(struct state *state)701{702int i, sect_size;703uint8_t *ptr;704705state->hdr = next_sect(state, §_size);706707printf("######## HEADER: (size %d)\n", sect_size);708printf("\tsize: %d\n", state->hdr->size);709printf("\trevision: %d\n", state->hdr->revision);710printf("\tattributes: %d\n", state->hdr->num_attribs);711printf("\tuniforms: %d\n", state->hdr->num_uniforms);712printf("\tsamplers: %d\n", state->hdr->num_samplers);713printf("\tvaryings: %d\n", state->hdr->num_varyings);714printf("\tuniform blocks: %d\n", state->hdr->num_uniformblocks);715if (full_dump)716dump_hex((void *)state->hdr, sect_size);717printf("\n");718719/* there seems to be two 0xba5eba11's at the end of the header, possibly720* with some other stuff between them:721*/722ptr = next_sect(state, §_size);723if (full_dump) {724dump_hex_ascii(ptr, sect_size, 0);725}726727for (i = 0; (i < state->hdr->num_attribs) && (state->sz > 0); i++) {728state->attribs[i] = next_sect(state, §_size);729730/* hmm, for a3xx (or maybe just newer driver version), we have some731* extra sections that don't seem useful, so skip these:732*/733while (!valid_type(state->attribs[i]->type_info)) {734dump_hex_ascii(state->attribs[i], sect_size, 0);735state->attribs[i] = next_sect(state, §_size);736}737738clean_ascii(state->attribs[i]->name, sect_size - 28);739if (full_dump) {740printf("######## ATTRIBUTE: (size %d)\n", sect_size);741dump_attribute(state->attribs[i]);742dump_hex((char *)state->attribs[i], sect_size);743}744}745746for (i = 0; (i < state->hdr->num_uniforms) && (state->sz > 0); i++) {747state->uniforms[i] = next_sect(state, §_size);748749/* hmm, for a3xx (or maybe just newer driver version), we have some750* extra sections that don't seem useful, so skip these:751*/752while (!valid_type(state->uniforms[i]->type_info)) {753dump_hex_ascii(state->uniforms[i], sect_size, 0);754state->uniforms[i] = next_sect(state, §_size);755}756757if (is_uniform_v2(state->uniforms[i])) {758clean_ascii(state->uniforms[i]->v2.name, sect_size - 53);759} else {760clean_ascii(state->uniforms[i]->v1.name, sect_size - 41);761}762763if (full_dump) {764printf("######## UNIFORM: (size %d)\n", sect_size);765dump_uniform(state->uniforms[i]);766dump_hex((char *)state->uniforms[i], sect_size);767}768}769770for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) {771state->samplers[i] = next_sect(state, §_size);772773/* hmm, for a3xx (or maybe just newer driver version), we have some774* extra sections that don't seem useful, so skip these:775*/776while (!valid_type(state->samplers[i]->type_info)) {777dump_hex_ascii(state->samplers[i], sect_size, 0);778state->samplers[i] = next_sect(state, §_size);779}780781clean_ascii(state->samplers[i]->name, sect_size - 33);782if (full_dump) {783printf("######## SAMPLER: (size %d)\n", sect_size);784dump_sampler(state->samplers[i]);785dump_hex((char *)state->samplers[i], sect_size);786}787}788789// These sections show up after all of the other sampler sections790// Loops through them all since we don't deal with them791if (state->hdr->revision >= 7) {792for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) {793ptr = next_sect(state, §_size);794dump_hex_ascii(ptr, sect_size, 0);795}796}797798for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) {799state->varyings[i] = next_sect(state, §_size);800801/* hmm, for a3xx (or maybe just newer driver version), we have some802* extra sections that don't seem useful, so skip these:803*/804while (!valid_type(state->varyings[i]->type_info)) {805dump_hex_ascii(state->varyings[i], sect_size, 0);806state->varyings[i] = next_sect(state, §_size);807}808809clean_ascii(state->varyings[i]->name, sect_size - 16);810if (full_dump) {811printf("######## VARYING: (size %d)\n", sect_size);812dump_varying(state->varyings[i]);813dump_hex((char *)state->varyings[i], sect_size);814}815}816817/* show up again for revision >= 14?? */818if (state->hdr->revision >= 14) {819for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) {820ptr = next_sect(state, §_size);821dump_hex_ascii(ptr, sect_size, 0);822}823}824825/* not sure exactly which revision started this, but seems at least826* rev7 and rev8 implicitly include a new section for gl_FragColor:827*/828if (state->hdr->revision >= 7) {829/* I guess only one? */830state->outputs[0] = next_sect(state, §_size);831832clean_ascii(state->outputs[0]->name, sect_size - 32);833if (full_dump) {834printf("######## OUTPUT: (size %d)\n", sect_size);835dump_output(state->outputs[0]);836dump_hex((char *)state->outputs[0], sect_size);837}838}839840for (i = 0; (i < state->hdr->num_uniformblocks) && (state->sz > 0); i++) {841state->uniformblocks[i].header = next_sect(state, §_size);842843clean_ascii(state->uniformblocks[i].header->name, sect_size - 40);844if (full_dump) {845printf("######## UNIFORM BLOCK: (size %d)\n", sect_size);846dump_uniformblock(state->uniformblocks[i].header);847dump_hex((char *)state->uniformblocks[i].header, sect_size);848}849850/*851* OpenGL ES 3.0 spec mandates a minimum amount of 16K members supported852* a330 supports a minimum of 65K853*/854state->uniformblocks[i].members =855malloc(state->uniformblocks[i].header->num_members * sizeof(void *));856857int member = 0;858for (member = 0; (member < state->uniformblocks[i].header->num_members) &&859(state->sz > 0);860member++) {861state->uniformblocks[i].members[member] = next_sect(state, §_size);862863clean_ascii(state->uniformblocks[i].members[member]->name,864sect_size - 56);865if (full_dump) {866printf("######## UNIFORM BLOCK MEMBER: (size %d)\n", sect_size);867dump_uniformblockmember(state->uniformblocks[i].members[member]);868dump_hex((char *)state->uniformblocks[i].members[member],869sect_size);870}871}872/*873* Qualcomm saves the UBO members twice for each UBO874* Don't ask me why875*/876for (member = 0; (member < state->uniformblocks[i].header->num_members) &&877(state->sz > 0);878member++) {879state->uniformblocks[i].members[member] = next_sect(state, §_size);880881clean_ascii(state->uniformblocks[i].members[member]->name,882sect_size - 56);883if (full_dump) {884printf("######## UNIFORM BLOCK MEMBER2: (size %d)\n", sect_size);885dump_uniformblockmember(state->uniformblocks[i].members[member]);886dump_hex((char *)state->uniformblocks[i].members[member],887sect_size);888}889}890}891892if (gpu_id >= 300) {893dump_shaders_a3xx(state);894} else {895dump_shaders_a2xx(state);896}897898if (!full_dump)899return;900901/* dump ascii version of shader program: */902ptr = next_sect(state, §_size);903printf("\n#######################################################\n");904printf("######## SHADER SRC: (size=%d)\n", sect_size);905dump_ascii(ptr, sect_size);906free(ptr);907908/* dump remaining sections (there shouldn't be any): */909while (state->sz > 0) {910ptr = next_sect(state, §_size);911printf("######## section (size=%d)\n", sect_size);912printf("as hex:\n");913dump_hex(ptr, sect_size);914printf("as float:\n");915dump_float(ptr, sect_size);916printf("as ascii:\n");917dump_ascii(ptr, sect_size);918free(ptr);919}920/* cleanup the uniform buffer members we allocated */921if (state->hdr->num_uniformblocks > 0)922free(state->uniformblocks[i].members);923}924925int926main(int argc, char **argv)927{928enum rd_sect_type type = RD_NONE;929enum debug_t debug = PRINT_RAW | PRINT_STATS;930void *buf = NULL;931int sz;932struct io *io;933int raw_program = 0;934935/* lame argument parsing: */936937while (1) {938if ((argc > 1) && !strcmp(argv[1], "--verbose")) {939debug |= PRINT_RAW | PRINT_VERBOSE;940argv++;941argc--;942continue;943}944if ((argc > 1) && !strcmp(argv[1], "--expand")) {945debug |= EXPAND_REPEAT;946argv++;947argc--;948continue;949}950if ((argc > 1) && !strcmp(argv[1], "--short")) {951/* only short dump, original shader, symbol table, and disassembly */952full_dump = 0;953argv++;954argc--;955continue;956}957if ((argc > 1) && !strcmp(argv[1], "--dump-shaders")) {958dump_shaders = 1;959argv++;960argc--;961continue;962}963if ((argc > 1) && !strcmp(argv[1], "--raw")) {964raw_program = 1;965argv++;966argc--;967continue;968}969if ((argc > 1) && !strcmp(argv[1], "--gpu300")) {970gpu_id = 320;971argv++;972argc--;973continue;974}975break;976}977978if (argc != 2) {979fprintf(980stderr,981"usage: pgmdump [--verbose] [--short] [--dump-shaders] testlog.rd\n");982return -1;983}984985disasm_a2xx_set_debug(debug);986disasm_a3xx_set_debug(debug);987988infile = argv[1];989990io = io_open(infile);991if (!io) {992fprintf(stderr, "could not open: %s\n", infile);993return -1;994}995996if (raw_program) {997io_readn(io, &sz, 4);998free(buf);9991000/* note: allow hex dumps to go a bit past the end of the buffer..1001* might see some garbage, but better than missing the last few bytes..1002*/1003buf = calloc(1, sz + 3);1004io_readn(io, buf + 4, sz);1005(*(int *)buf) = sz;10061007struct state state = {1008.buf = buf,1009.sz = sz,1010};1011printf("############################################################\n");1012printf("program:\n");1013dump_program(&state);1014printf("############################################################\n");1015return 0;1016}10171018/* figure out what sort of input we are dealing with: */1019if (!(check_extension(infile, ".rd") || check_extension(infile, ".rd.gz"))) {1020gl_shader_stage shader = ~0;1021int ret;1022if (check_extension(infile, ".vo")) {1023shader = MESA_SHADER_VERTEX;1024} else if (check_extension(infile, ".fo")) {1025shader = MESA_SHADER_FRAGMENT;1026} else if (check_extension(infile, ".vo3")) {1027} else if (check_extension(infile, ".fo3")) {1028} else if (check_extension(infile, ".co3")) {1029} else {1030fprintf(stderr, "invalid input file: %s\n", infile);1031return -1;1032}1033buf = calloc(1, 100 * 1024);1034ret = io_readn(io, buf, 100 * 1024);1035if (ret < 0) {1036fprintf(stderr, "error: %m");1037return -1;1038}1039if (shader != ~0) {1040return disasm_a2xx(buf, ret / 4, 0, shader);1041} else {1042/* disassembly does not depend on shader stage on a3xx+: */1043return disasm_a3xx(buf, ret / 4, 0, stdout, gpu_id);1044}1045}10461047while ((io_readn(io, &type, sizeof(type)) > 0) &&1048(io_readn(io, &sz, 4) > 0)) {1049free(buf);10501051/* note: allow hex dumps to go a bit past the end of the buffer..1052* might see some garbage, but better than missing the last few bytes..1053*/1054buf = calloc(1, sz + 3);1055io_readn(io, buf, sz);10561057switch (type) {1058case RD_TEST:1059if (full_dump)1060printf("test: %s\n", (char *)buf);1061break;1062case RD_VERT_SHADER:1063printf("vertex shader:\n%s\n", (char *)buf);1064break;1065case RD_FRAG_SHADER:1066printf("fragment shader:\n%s\n", (char *)buf);1067break;1068case RD_PROGRAM: {1069struct state state = {1070.buf = buf,1071.sz = sz,1072};1073printf(1074"############################################################\n");1075printf("program:\n");1076dump_program(&state);1077printf(1078"############################################################\n");1079break;1080}1081case RD_GPU_ID:1082gpu_id = *((unsigned int *)buf);1083printf("gpu_id: %d\n", gpu_id);1084break;1085default:1086break;1087}1088}10891090io_close(io);10911092return 0;1093}109410951096