void dump_program(struct state *state) { int i, sect_size; uint8_t *ptr; state->hdr = next_sect(state, §_size); printf("######## HEADER: (size %d)\n", sect_size); printf("\tsize: %d\n", state->hdr->size); printf("\tattributes: %d\n", state->hdr->num_attribs); printf("\tuniforms: %d\n", state->hdr->num_uniforms); printf("\tsamplers: %d\n", state->hdr->num_samplers); printf("\tvaryings: %d\n", state->hdr->num_varyings); if (full_dump) dump_hex((void *)state->hdr, sect_size); printf("\n"); /* there seems to be two 0xba5eba11's at the end of the header, possibly * with some other stuff between them: */ next_sect(state, §_size); for (i = 0; (i < state->hdr->num_attribs) && (state->sz > 0); i++) { state->attribs[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->attribs[i]->type_info)) state->attribs[i] = next_sect(state, §_size); clean_ascii(state->attribs[i]->name, sect_size - 28); if (full_dump) { printf("######## ATTRIBUTE: (size %d)\n", sect_size); dump_attribute(state->attribs[i]); dump_hex((char *)state->attribs[i], sect_size); } } for (i = 0; (i < state->hdr->num_uniforms) && (state->sz > 0); i++) { state->uniforms[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->uniforms[i]->type_info)) state->uniforms[i] = next_sect(state, §_size); clean_ascii(state->uniforms[i]->name, sect_size - 41); if (full_dump) { printf("######## UNIFORM: (size %d)\n", sect_size); dump_uniform(state->uniforms[i]); dump_hex((char *)state->uniforms[i], sect_size); } } for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) { state->samplers[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->samplers[i]->type_info)) state->samplers[i] = next_sect(state, §_size); clean_ascii(state->samplers[i]->name, sect_size - 33); if (full_dump) { printf("######## SAMPLER: (size %d)\n", sect_size); dump_sampler(state->samplers[i]); dump_hex((char *)state->samplers[i], sect_size); } } for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) { state->varyings[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->varyings[i]->type_info)) state->varyings[i] = next_sect(state, §_size); clean_ascii(state->varyings[i]->name, sect_size - 16); if (full_dump) { printf("######## VARYING: (size %d)\n", sect_size); dump_varying(state->varyings[i]); dump_hex((char *)state->varyings[i], sect_size); } } if (gpu_id >= 300) { dump_shaders_a3xx(state); } else { dump_shaders_a2xx(state); } if (!full_dump) return; /* dump ascii version of shader program: */ ptr = next_sect(state, §_size); printf("\n#######################################################\n"); printf("######## SHADER SRC: (size=%d)\n", sect_size); dump_ascii(ptr, sect_size); free(ptr); /* dump remaining sections (there shouldn't be any): */ while (state->sz > 0) { ptr = next_sect(state, §_size); printf("######## section (size=%d)\n", sect_size); printf("as hex:\n"); dump_hex(ptr, sect_size); printf("as float:\n"); dump_float(ptr, sect_size); printf("as ascii:\n"); dump_ascii(ptr, sect_size); free(ptr); } }
static void dump_shaders_a2xx(struct state *state) { int i, sect_size; uint8_t *ptr; /* dump vertex shaders: */ for (i = 0; i < 3; i++) { struct vs_header *vs_hdr = next_sect(state, §_size); struct constant *constants[32]; int j, level = 0; printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## VS%d HEADER: (size %d)\n", i, sect_size); dump_hex((void *)vs_hdr, sect_size); } for (j = 0; j < (int)vs_hdr->unknown1 - 1; j++) { constants[j] = next_sect(state, §_size); if (full_dump) { printf("######## VS%d CONST: (size=%d)\n", i, sect_size); dump_constant(constants[j]); dump_hex((char *)constants[j], sect_size); } } ptr = next_sect(state, §_size); printf("######## VS%d SHADER: (size=%d)\n", i, sect_size); if (full_dump) { dump_hex(ptr, sect_size); level = 1; } else { dump_short_summary(state, vs_hdr->unknown1 - 1, constants); } disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level+1, SHADER_VERTEX); dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "vo"); free(ptr); for (j = 0; j < vs_hdr->unknown9; j++) { ptr = next_sect(state, §_size); if (full_dump) { printf("######## VS%d CONST?: (size=%d)\n", i, sect_size); dump_hex(ptr, sect_size); } free(ptr); } for (j = 0; j < vs_hdr->unknown1 - 1; j++) { free(constants[j]); } free(vs_hdr); } /* dump fragment shaders: */ for (i = 0; i < 1; i++) { struct fs_header *fs_hdr = next_sect(state, §_size); struct constant *constants[32]; int j, level = 0; printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## FS%d HEADER: (size %d)\n", i, sect_size); dump_hex((void *)fs_hdr, sect_size); } for (j = 0; j < fs_hdr->unknown1 - 1; j++) { constants[j] = next_sect(state, §_size); if (full_dump) { printf("######## FS%d CONST: (size=%d)\n", i, sect_size); dump_constant(constants[j]); dump_hex((char *)constants[j], sect_size); } } ptr = next_sect(state, §_size); printf("######## FS%d SHADER: (size=%d)\n", i, sect_size); if (full_dump) { dump_hex(ptr, sect_size); level = 1; } else { dump_short_summary(state, fs_hdr->unknown1 - 1, constants); } disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level+1, SHADER_FRAGMENT); dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "fo"); free(ptr); for (j = 0; j < fs_hdr->unknown1 - 1; j++) { free(constants[j]); } free(fs_hdr); } }
static void dump_shaders_a3xx(struct state *state) { int i, j; /* dump vertex shaders: */ for (i = 0; i < 2; i++) { int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; uint8_t *vs_hdr; struct constant *constants[32]; uint8_t *instrs = NULL; vs_hdr = next_sect(state, &hdr_size); /* seems like there are two cases, either: * 1) 152 byte header, * 2) zero or more 32 byte compiler const sections * 3) followed by shader instructions * or, if there are no compiler consts, this can be * all smashed in one large section */ if (hdr_size > 152) { instrs = &vs_hdr[152]; instrs_size = hdr_size - 152; hdr_size = 152; compact = 1; } else { while (1) { void *ptr = next_sect(state, §_size); if (sect_size != 32) { /* end of constants: */ instrs = ptr; instrs_size = sect_size; break; } constants[nconsts++] = ptr; } } printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## VS%d HEADER: (size %d)\n", i, hdr_size); dump_hex((void *)vs_hdr, hdr_size); for (j = 0; j < nconsts; j++) { printf("######## VS%d CONST: (size=%d)\n", i, sizeof(constants[i])); dump_constant(constants[j]); dump_hex((char *)constants[j], sizeof(constants[j])); } } printf("######## VS%d SHADER: (size=%d)\n", i, instrs_size); if (full_dump) { dump_hex(instrs, instrs_size); level = 1; } else { dump_short_summary(state, nconsts, constants); } if (!compact) { instrs += 32; instrs_size -= 32; } disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, SHADER_VERTEX); dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "vo3"); free(vs_hdr); } /* dump fragment shaders: */ for (i = 0; i < 1; i++) { int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; uint8_t *fs_hdr; struct constant *constants[32]; uint8_t *instrs = NULL; fs_hdr = next_sect(state, &hdr_size); /* two cases, similar to vertex shader, but magic # is 200.. */ if (hdr_size > 200) { instrs = &fs_hdr[200]; instrs_size = hdr_size - 200; hdr_size = 200; compact = 1; } else { while (1) { void *ptr = next_sect(state, §_size); if (sect_size != 32) { /* end of constants: */ instrs = ptr; instrs_size = sect_size; break; } constants[nconsts++] = ptr; } } printf("\n"); if (full_dump) { printf("#######################################################\n"); printf("######## FS%d HEADER: (size %d)\n", i, hdr_size); dump_hex((void *)fs_hdr, hdr_size); for (j = 0; j < nconsts; j++) { printf("######## FS%d CONST: (size=%d)\n", i, sizeof(constants[i])); dump_constant(constants[j]); dump_hex((char *)constants[j], sizeof(constants[j])); } } printf("######## FS%d SHADER: (size=%d)\n", i, instrs_size); if (full_dump) { dump_hex(instrs, instrs_size); level = 1; } else { dump_short_summary(state, nconsts, constants); } if (!compact) { instrs += 32; instrs_size -= 32; } disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, SHADER_FRAGMENT); dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "fo3"); free(fs_hdr); } }
void dump_program(struct state *state) { int i, sect_size; uint8_t *ptr; state->hdr = next_sect(state, §_size); printf("######## HEADER: (size %d)\n", sect_size); printf("\tsize: %d\n", state->hdr->size); printf("\trevision: %d\n", state->hdr->revision); printf("\tattributes: %d\n", state->hdr->num_attribs); printf("\tuniforms: %d\n", state->hdr->num_uniforms); printf("\tsamplers: %d\n", state->hdr->num_samplers); printf("\tvaryings: %d\n", state->hdr->num_varyings); printf("\tuniform blocks: %d\n", state->hdr->num_uniformblocks); if (full_dump) dump_hex((void *)state->hdr, sect_size); printf("\n"); /* there seems to be two 0xba5eba11's at the end of the header, possibly * with some other stuff between them: */ ptr = next_sect(state, §_size); if (full_dump) { dump_hex_ascii(ptr, sect_size); } for (i = 0; (i < state->hdr->num_attribs) && (state->sz > 0); i++) { state->attribs[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->attribs[i]->type_info)) { dump_hex_ascii(state->attribs[i], sect_size); state->attribs[i] = next_sect(state, §_size); } clean_ascii(state->attribs[i]->name, sect_size - 28); if (full_dump) { printf("######## ATTRIBUTE: (size %d)\n", sect_size); dump_attribute(state->attribs[i]); dump_hex((char *)state->attribs[i], sect_size); } } for (i = 0; (i < state->hdr->num_uniforms) && (state->sz > 0); i++) { state->uniforms[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->uniforms[i]->type_info)) { dump_hex_ascii(state->uniforms[i], sect_size); state->uniforms[i] = next_sect(state, §_size); } if (is_uniform_v2(state->uniforms[i])) { clean_ascii(state->uniforms[i]->v2.name, sect_size - 53); } else { clean_ascii(state->uniforms[i]->v1.name, sect_size - 41); } if (full_dump) { printf("######## UNIFORM: (size %d)\n", sect_size); dump_uniform(state->uniforms[i]); dump_hex((char *)state->uniforms[i], sect_size); } } for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) { state->samplers[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->samplers[i]->type_info)) { dump_hex_ascii(state->samplers[i], sect_size); state->samplers[i] = next_sect(state, §_size); } clean_ascii(state->samplers[i]->name, sect_size - 33); if (full_dump) { printf("######## SAMPLER: (size %d)\n", sect_size); dump_sampler(state->samplers[i]); dump_hex((char *)state->samplers[i], sect_size); } } // These sections show up after all of the other sampler sections // Loops through them all since we don't deal with them if (state->hdr->revision >= 7) { for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) { ptr = next_sect(state, §_size); dump_hex_ascii(ptr, sect_size); } } for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) { state->varyings[i] = next_sect(state, §_size); /* hmm, for a3xx (or maybe just newer driver version), we have some * extra sections that don't seem useful, so skip these: */ while (!valid_type(state->varyings[i]->type_info)) { dump_hex_ascii(state->varyings[i], sect_size); state->varyings[i] = next_sect(state, §_size); } clean_ascii(state->varyings[i]->name, sect_size - 16); if (full_dump) { printf("######## VARYING: (size %d)\n", sect_size); dump_varying(state->varyings[i]); dump_hex((char *)state->varyings[i], sect_size); } } /* not sure exactly which revision started this, but seems at least * rev7 and rev8 implicitly include a new section for gl_FragColor: */ if (state->hdr->revision >= 7) { /* I guess only one? */ state->outputs[0] = next_sect(state, §_size); clean_ascii(state->outputs[0]->name, sect_size - 32); if (full_dump) { printf("######## OUTPUT: (size %d)\n", sect_size); dump_output(state->outputs[0]); dump_hex((char *)state->outputs[0], sect_size); } } for (i = 0; (i < state->hdr->num_uniformblocks) && (state->sz > 0); i++) { state->uniformblocks[i].header = next_sect(state, §_size); clean_ascii(state->uniformblocks[i].header->name, sect_size - 40); if (full_dump) { printf("######## UNIFORM BLOCK: (size %d)\n", sect_size); dump_uniformblock(state->uniformblocks[i].header); dump_hex((char *)state->uniformblocks[i].header, sect_size); } /* * OpenGL ES 3.0 spec mandates a minimum amount of 16K members supported * a330 supports a minimum of 65K */ state->uniformblocks[i].members = malloc(state->uniformblocks[i].header->num_members * sizeof(void*)); int member = 0; for (member = 0; (member < state->uniformblocks[i].header->num_members) && (state->sz > 0); member++) { state->uniformblocks[i].members[member] = next_sect(state, §_size); clean_ascii(state->uniformblocks[i].members[member]->name, sect_size - 56); if (full_dump) { printf("######## UNIFORM BLOCK MEMBER: (size %d)\n", sect_size); dump_uniformblockmember(state->uniformblocks[i].members[member]); dump_hex((char *)state->uniformblocks[i].members[member], sect_size); } } /* * Qualcomm saves the UBO members twice for each UBO * Don't ask me why */ for (member = 0; (member < state->uniformblocks[i].header->num_members) && (state->sz > 0); member++) { state->uniformblocks[i].members[member] = next_sect(state, §_size); clean_ascii(state->uniformblocks[i].members[member]->name, sect_size - 56); if (full_dump) { printf("######## UNIFORM BLOCK MEMBER2: (size %d)\n", sect_size); dump_uniformblockmember(state->uniformblocks[i].members[member]); dump_hex((char *)state->uniformblocks[i].members[member], sect_size); } } } if (gpu_id >= 300) { dump_shaders_a3xx(state); } else { dump_shaders_a2xx(state); } if (!full_dump) return; /* dump ascii version of shader program: */ ptr = next_sect(state, §_size); printf("\n#######################################################\n"); printf("######## SHADER SRC: (size=%d)\n", sect_size); dump_ascii(ptr, sect_size); free(ptr); /* dump remaining sections (there shouldn't be any): */ while (state->sz > 0) { ptr = next_sect(state, §_size); printf("######## section (size=%d)\n", sect_size); printf("as hex:\n"); dump_hex(ptr, sect_size); printf("as float:\n"); dump_float(ptr, sect_size); printf("as ascii:\n"); dump_ascii(ptr, sect_size); free(ptr); } /* cleanup the uniform buffer members we allocated */ if (state->hdr->num_uniformblocks > 0) free (state->uniformblocks[i].members); }