int gen_dump_float(struct parse_string *p, const char *ptr, unsigned indent) { return addshort(p, "%g", *(float *)(ptr)); }
int gen_dump_double(struct parse_string *p, const char *ptr, unsigned indent) { return addshort(p, "%lg", *(double *)(ptr)); }
/* handle dumping of an array of arbitrary type */ static int gen_dump_array(struct parse_string *p, const struct parse_struct *pinfo, const char *ptr, int array_len, int indent) { int i, count=0; /* special handling of fixed length strings */ if (array_len != 0 && pinfo->ptr_count == 0 && pinfo->dump_fn == gen_dump_char) { char *s = encode_bytes(ptr, array_len); if (!s) return -1; if (addtabbed(p, pinfo->name, indent) || addstr(p, " = {") || addstr(p, s) || addstr(p, "}\n")) { free(s); return -1; } free(s); return 0; } for (i=0;i<array_len;i++) { const char *p2 = ptr; unsigned size = pinfo->size; /* generic pointer dereference */ if (pinfo->ptr_count) { p2 = *(const char **)ptr; size = sizeof(void *); } if ((count || pinfo->ptr_count) && !(pinfo->flags & FLAG_ALWAYS) && all_zero(ptr, size)) { ptr += size; continue; } if (count == 0) { if (addtabbed(p, pinfo->name, indent) || addshort(p, " = %u:", i)) { return -1; } } else { if (addshort(p, ", %u:", i) != 0) { return -1; } } if (gen_dump_one(p, pinfo, p2, indent) != 0) { return -1; } ptr += size; count++; } if (count) { return addstr(p, "\n"); } return 0; }
int gen_dump_time_t(struct parse_string *p, const char *ptr, unsigned indent) { return addshort(p, "%u", *(time_t *)(ptr)); }
// Render a single triangle to memory. void testTriangle() { // Like above, we allocate/lock/map some videocore memory // I'm just shoving everything in a single buffer because I'm lazy // 8Mb, 4k alignment unsigned int handle = mem_alloc(mbox, 0x800000, 0x1000, MEM_FLAG_COHERENT | MEM_FLAG_ZERO); if (!handle) { printf("Error: Unable to allocate memory"); return; } uint32_t bus_addr = mem_lock(mbox, handle); uint8_t *list = (uint8_t*) mapmem(bus_addr, 0x800000); uint8_t *p = list; // Configuration stuff // Tile Binning Configuration. // Tile state data is 48 bytes per tile, I think it can be thrown away // as soon as binning is finished. addbyte(&p, 112); addword(&p, bus_addr + 0x6200); // tile allocation memory address addword(&p, 0x8000); // tile allocation memory size addword(&p, bus_addr + 0x100); // Tile state data address addbyte(&p, 30); // 1920/64 addbyte(&p, 17); // 1080/64 (16.875) addbyte(&p, 0x04); // config // Start tile binning. addbyte(&p, 6); // Primitive type addbyte(&p, 56); addbyte(&p, 0x32); // 16 bit triangle // Clip Window addbyte(&p, 102); addshort(&p, 0); addshort(&p, 0); addshort(&p, 1920); // width addshort(&p, 1080); // height // State addbyte(&p, 96); addbyte(&p, 0x03); // enable both foward and back facing polygons addbyte(&p, 0x00); // depth testing disabled addbyte(&p, 0x02); // enable early depth write // Viewport offset addbyte(&p, 103); addshort(&p, 0); addshort(&p, 0); // The triangle // No Vertex Shader state (takes pre-transformed vertexes, // so we don't have to supply a working coordinate shader to test the binner. addbyte(&p, 65); addword(&p, bus_addr + 0x80); // Shader Record // primitive index list addbyte(&p, 32); addbyte(&p, 0x04); // 8bit index, trinagles addword(&p, 3); // Length addword(&p, bus_addr + 0x70); // address addword(&p, 2); // Maximum index // End of bin list // Flush addbyte(&p, 5); // Nop addbyte(&p, 1); // Halt addbyte(&p, 0); int length = p - list; assert(length < 0x80); // Shader Record p = list + 0x80; addbyte(&p, 0x01); // flags addbyte(&p, 6*4); // stride addbyte(&p, 0xcc); // num uniforms (not used) addbyte(&p, 3); // num varyings addword(&p, bus_addr + 0xfe00); // Fragment shader code addword(&p, bus_addr + 0xff00); // Fragment shader uniforms addword(&p, bus_addr + 0xa0); // Vertex Data // Vertex Data p = list + 0xa0; // Vertex: Top, red addshort(&p, (1920/2) << 4); // X in 12.4 fixed point addshort(&p, 200 << 4); // Y in 12.4 fixed point addfloat(&p, 1.0f); // Z addfloat(&p, 1.0f); // 1/W addfloat(&p, 1.0f); // Varying 0 (Red) addfloat(&p, 0.0f); // Varying 1 (Green) addfloat(&p, 0.0f); // Varying 2 (Blue) // Vertex: bottom left, Green addshort(&p, 560 << 4); // X in 12.4 fixed point addshort(&p, 800 << 4); // Y in 12.4 fixed point addfloat(&p, 1.0f); // Z addfloat(&p, 1.0f); // 1/W addfloat(&p, 0.0f); // Varying 0 (Red) addfloat(&p, 1.0f); // Varying 1 (Green) addfloat(&p, 0.0f); // Varying 2 (Blue) // Vertex: bottom right, Blue addshort(&p, 1360 << 4); // X in 12.4 fixed point addshort(&p, 800 << 4); // Y in 12.4 fixed point addfloat(&p, 1.0f); // Z addfloat(&p, 1.0f); // 1/W addfloat(&p, 0.0f); // Varying 0 (Red) addfloat(&p, 0.0f); // Varying 1 (Green) addfloat(&p, 1.0f); // Varying 2 (Blue) // Vertex list p = list + 0x70; addbyte(&p, 0); // top addbyte(&p, 1); // bottom left addbyte(&p, 2); // bottom right // fragment shader p = list + 0xfe00; addword(&p, 0x958e0dbf); addword(&p, 0xd1724823); /* mov r0, vary; mov r3.8d, 1.0 */ addword(&p, 0x818e7176); addword(&p, 0x40024821); /* fadd r0, r0, r5; mov r1, vary */ addword(&p, 0x818e7376); addword(&p, 0x10024862); /* fadd r1, r1, r5; mov r2, vary */ addword(&p, 0x819e7540); addword(&p, 0x114248a3); /* fadd r2, r2, r5; mov r3.8a, r0 */ addword(&p, 0x809e7009); addword(&p, 0x115049e3); /* nop; mov r3.8b, r1 */ addword(&p, 0x809e7012); addword(&p, 0x116049e3); /* nop; mov r3.8c, r2 */ addword(&p, 0x159e76c0); addword(&p, 0x30020ba7); /* mov tlbc, r3; nop; thrend */ addword(&p, 0x009e7000); addword(&p, 0x100009e7); /* nop; nop; nop */ addword(&p, 0x009e7000); addword(&p, 0x500009e7); /* nop; nop; sbdone */ // Render control list p = list + 0xe200; // Clear color addbyte(&p, 114); addword(&p, 0xff000000); // Opaque Black addword(&p, 0xff000000); // 32 bit clear colours need to be repeated twice addword(&p, 0); addbyte(&p, 0); // Tile Rendering Mode Configuration addbyte(&p, 113); addword(&p, bus_addr + 0x10000); // framebuffer addresss addshort(&p, 1920); // width addshort(&p, 1080); // height addbyte(&p, 0x04); // framebuffer mode (linear rgba8888) addbyte(&p, 0x00); // Do a store of the first tile to force the tile buffer to be cleared // Tile Coordinates addbyte(&p, 115); addbyte(&p, 0); addbyte(&p, 0); // Store Tile Buffer General addbyte(&p, 28); addshort(&p, 0); // Store nothing (just clear) addword(&p, 0); // no address is needed // Link all binned lists together for(int x = 0; x < 30; x++) { for(int y = 0; y < 17; y++) { // Tile Coordinates addbyte(&p, 115); addbyte(&p, x); addbyte(&p, y); // Call Tile sublist addbyte(&p, 17); addword(&p, bus_addr + 0x6200 + (y * 30 + x) * 32); // Last tile needs a special store instruction if(x == 29 && y == 16) { // Store resolved tile color buffer and signal end of frame addbyte(&p, 25); } else { // Store resolved tile color buffer addbyte(&p, 24); } } } int render_length = p - (list + 0xe200); // Run our control list printf("Binner control list constructed\n"); printf("Start Address: 0x%08x, length: 0x%x\n", bus_addr, length); v3d[V3D_CT0CA] = bus_addr; v3d[V3D_CT0EA] = bus_addr + length; printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); // Wait for control list to execute while(v3d[V3D_CT0CS] & 0x20); printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]); printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); v3d[V3D_CT1CA] = bus_addr + 0xe200; v3d[V3D_CT1EA] = bus_addr + 0xe200 + render_length; while(v3d[V3D_CT1CS] & 0x20); printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]); v3d[V3D_CT1CS] = 0x20; // just dump the frame to a file FILE *f = fopen("frame.data", "w"); fwrite(list + 0x10000, (1920*1080*4), 1, f); fclose(f); printf("frame buffer memory dumpped to frame.data\n"); // Release resources unmapmem((void *) list, 0x800000); mem_unlock(mbox, handle); mem_free(mbox, handle); }