void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state) { struct r300_vertex_stream_state *streams = (struct r300_vertex_stream_state*)state; unsigned i; CS_LOCALS(r300); if (DBG_ON(r300, DBG_PSC)) { fprintf(stderr, "r300: PSC emit:\n"); for (i = 0; i < streams->count; i++) { fprintf(stderr, " : prog_stream_cntl%d: 0x%08x\n", i, streams->vap_prog_stream_cntl[i]); } for (i = 0; i < streams->count; i++) { fprintf(stderr, " : prog_stream_cntl_ext%d: 0x%08x\n", i, streams->vap_prog_stream_cntl_ext[i]); } } BEGIN_CS(size); OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count); OUT_CS_TABLE(streams->vap_prog_stream_cntl, streams->count); OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count); OUT_CS_TABLE(streams->vap_prog_stream_cntl_ext, streams->count); END_CS; }
void ping_me(uint8_t c) { asm("eor r1,r1"); // we don't know where we came from cli(); DBG_OFF();DBG_ON();DBG_OFF();DBG_ON();DBG_OFF(); DBG(c); DBG_ON();DBG_OFF(); DBG_ON();DBG_OFF(); #if defined(HAVE_WATCHDOG) wdt_reset(); #endif #ifdef HAVE_UART_SYNC uart_puts_P("\nDEAD x"); uart_puthex_byte(c); uart_putc('\n'); uart_putc(' '); #endif wdt_enable(0); // (almost) immediate do {} while(1); }
void r300_emit_rs_block_state(struct r300_context* r300, unsigned size, void* state) { struct r300_rs_block* rs = (struct r300_rs_block*)state; unsigned i; /* It's the same for both INST and IP tables */ unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1; CS_LOCALS(r300); if (DBG_ON(r300, DBG_RS_BLOCK)) { r500_dump_rs_block(rs); fprintf(stderr, "r300: RS emit:\n"); for (i = 0; i < count; i++) fprintf(stderr, " : ip %d: 0x%08x\n", i, rs->ip[i]); for (i = 0; i < count; i++) fprintf(stderr, " : inst %d: 0x%08x\n", i, rs->inst[i]); fprintf(stderr, " : count: 0x%08x inst_count: 0x%08x\n", rs->count, rs->inst_count); } BEGIN_CS(size); OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); OUT_CS(rs->vap_vtx_state_cntl); OUT_CS(rs->vap_vsm_vtx_assm); OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); OUT_CS(rs->vap_out_vtx_fmt[0]); OUT_CS(rs->vap_out_vtx_fmt[1]); OUT_CS_REG_SEQ(R300_GB_ENABLE, 1); OUT_CS(rs->gb_enable); if (r300->screen->caps.is_r500) { OUT_CS_REG_SEQ(R500_RS_IP_0, count); } else { OUT_CS_REG_SEQ(R300_RS_IP_0, count); } OUT_CS_TABLE(rs->ip, count); OUT_CS_REG_SEQ(R300_RS_COUNT, 2); OUT_CS(rs->count); OUT_CS(rs->inst_count); if (r300->screen->caps.is_r500) { OUT_CS_REG_SEQ(R500_RS_INST_0, count); } else { OUT_CS_REG_SEQ(R300_RS_INST_0, count); } OUT_CS_TABLE(rs->inst, count); END_CS; }
void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs) { struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; /* Initialize. */ r300_shader_read_vs_outputs(&vs->info, &vs->outputs); /* Setup the compiler */ rc_init(&compiler.Base); compiler.Base.Debug = DBG_ON(r300, DBG_VP); compiler.code = &vs->code; compiler.UserData = vs; if (compiler.Base.Debug) { debug_printf("r300: Initial vertex program\n"); tgsi_dump(vs->state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &vs->info; ttr.use_half_swizzles = FALSE; r300_tgsi_to_rc(&ttr, vs->state.tokens); compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+1)); compiler.SetHwInputOutput = &set_vertex_inputs_outputs; /* Insert the WPOS output. */ r300_insert_wpos(&compiler, &vs->outputs); r300_shader_vap_output_fmt(vs); r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl); /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { /* XXX We should fallback using Draw. */ fprintf(stderr, "r300 VP: Compiler error\n"); abort(); } /* And, finally... */ rc_destroy(&compiler.Base); vs->translated = TRUE; }
static boolean immd_is_good_idea(struct r300_context *r300, unsigned count) { if (DBG_ON(r300, DBG_NO_IMMD)) { return FALSE; } if (count * r300->velems->vertex_size_dwords > IMMD_DWORDS) { return FALSE; } /* Buffers can only be used for read by r300 (except query buffers, but * those can't be bound by a state tracker as vertex buffers). */ return TRUE; }
void r300_translate_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs) { struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); compiler.Base.Debug = DBG_ON(r300, DBG_FP); compiler.code = &fs->code; compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; compiler.AllocateHwInputs = &allocate_hardware_inputs; compiler.UserData = fs; /* TODO: Program compilation depends on texture compare modes, * which are sampler state. Therefore, programs need to be recompiled * depending on this state as in the classic Mesa driver. * * This is not yet handled correctly. */ find_output_registers(&compiler, fs); if (compiler.Base.Debug) { debug_printf("r300: Initial fragment program\n"); tgsi_dump(fs->state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &fs->info; r300_tgsi_to_rc(&ttr, fs->state.tokens); /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); if (compiler.Base.Error) { /* XXX failover maybe? */ DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n", compiler.Base.ErrorMsg); } /* And, finally... */ rc_destroy(&compiler.Base); fs->translated = TRUE; }
static boolean immd_is_good_idea(struct r300_context *r300, unsigned count) { struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; boolean checked[PIPE_MAX_ATTRIBS] = {0}; unsigned vertex_element_count = r300->velems->count; unsigned i, vbi; if (DBG_ON(r300, DBG_NO_IMMD)) { return FALSE; } if (r300->draw) { return FALSE; } if (count * r300->velems->vertex_size_dwords > IMMD_DWORDS) { return FALSE; } /* We shouldn't map buffers referenced by CS, busy buffers, * and ones placed in VRAM. */ for (i = 0; i < vertex_element_count; i++) { velem = &r300->velems->velem[i]; vbi = velem->vertex_buffer_index; if (!checked[vbi]) { vbuf = &r300->vertex_buffer[vbi]; if (!(r300_buffer(vbuf->buffer)->domain & R300_DOMAIN_GTT)) { return FALSE; } if (r300_buffer_is_referenced(&r300->context, vbuf->buffer, R300_REF_CS | R300_REF_HW)) { /* It's a very bad idea to map it... */ return FALSE; } checked[vbi] = TRUE; } } return TRUE; }
void r300_translate_vertex_shader(struct r300_context *r300, struct r300_vertex_shader *vs) { struct r300_vertex_program_compiler compiler; struct tgsi_to_rc ttr; unsigned i; /* Setup the compiler */ memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base, NULL); DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; compiler.code = &vs->code; compiler.UserData = vs; compiler.Base.is_r500 = r300->screen->caps.is_r500; compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT); compiler.Base.has_half_swizzles = FALSE; compiler.Base.has_presub = FALSE; compiler.Base.has_omod = FALSE; compiler.Base.max_temp_regs = 32; compiler.Base.max_constants = 256; compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256; if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_VP, "r300: Initial vertex program\n"); tgsi_dump(vs->state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &vs->info; ttr.use_half_swizzles = FALSE; r300_tgsi_to_rc(&ttr, vs->state.tokens); if (ttr.error) { fprintf(stderr, "r300 VP: Cannot translate a shader. " "Using a dummy shader instead.\n"); r300_dummy_vertex_shader(r300, vs); return; } if (compiler.Base.Program.Constants.Count > 200) { compiler.Base.remove_unused_constants = TRUE; } compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1)); compiler.SetHwInputOutput = &set_vertex_inputs_outputs; /* Insert the WPOS output. */ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader" " instead.\n", compiler.Base.ErrorMsg); if (vs->dummy) { fprintf(stderr, "r300 VP: Cannot compile the dummy shader! " "Giving up...\n"); abort(); } rc_destroy(&compiler.Base); r300_dummy_vertex_shader(r300, vs); return; } /* Initialize numbers of constants for each type. */ vs->externals_count = 0; for (i = 0; i < vs->code.constants.Count && vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) { vs->externals_count = i+1; } for (; i < vs->code.constants.Count; i++) { assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE); } vs->immediates_count = vs->code.constants.Count - vs->externals_count; /* And, finally... */ rc_destroy(&compiler.Base); }
static void r300_translate_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader, const struct tgsi_token *tokens) { struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; int wpos, face; unsigned i; tgsi_scan_shader(tokens, &shader->info); r300_shader_read_fs_inputs(&shader->info, &shader->inputs); wpos = shader->inputs.wpos; face = shader->inputs.face; /* Setup the compiler. */ memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); DBG_ON(r300, DBG_FP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; compiler.code = &shader->code; compiler.state = shader->compare_state; compiler.Base.is_r500 = r300->screen->caps.is_r500; compiler.Base.is_r400 = r300->screen->caps.is_r400; compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT); compiler.Base.has_half_swizzles = TRUE; compiler.Base.has_presub = TRUE; compiler.Base.max_temp_regs = compiler.Base.is_r500 ? 128 : (compiler.Base.is_r400 ? 64 : 32); compiler.Base.max_constants = compiler.Base.is_r500 ? 256 : 32; compiler.Base.max_alu_insts = (compiler.Base.is_r500 || compiler.Base.is_r400) ? 512 : 64; compiler.Base.max_tex_insts = (compiler.Base.is_r500 || compiler.Base.is_r400) ? 512 : 32; compiler.AllocateHwInputs = &allocate_hardware_inputs; compiler.UserData = &shader->inputs; find_output_registers(&compiler, shader); shader->write_all = FALSE; for (i = 0; i < shader->info.num_properties; i++) { if (shader->info.properties[i].name == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) { shader->write_all = TRUE; } } if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_FP, "r300: Initial fragment program\n"); tgsi_dump(tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &shader->info; ttr.use_half_swizzles = TRUE; r300_tgsi_to_rc(&ttr, tokens); if (ttr.error) { fprintf(stderr, "r300 FP: Cannot translate a shader. " "Using a dummy shader instead.\n"); r300_dummy_fragment_shader(r300, shader); return; } if (!r300->screen->caps.is_r500 || compiler.Base.Program.Constants.Count > 200) { compiler.Base.remove_unused_constants = TRUE; } /** * Transform the program to support WPOS. * * Introduce a small fragment at the start of the program that will be * the only code that directly reads the WPOS input. * All other code pieces that reference that input will be rewritten * to read from a newly allocated temporary. */ if (wpos != ATTR_UNUSED) { /* Moving the input to some other reg is not really necessary. */ rc_transform_fragment_wpos(&compiler.Base, wpos, wpos, TRUE); } if (face != ATTR_UNUSED) { rc_transform_fragment_face(&compiler.Base, face); } /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); if (compiler.Base.Error) { fprintf(stderr, "r300 FP: Compiler Error:\n%sUsing a dummy shader" " instead.\n", compiler.Base.ErrorMsg); if (shader->dummy) { fprintf(stderr, "r300 FP: Cannot compile the dummy shader! " "Giving up...\n"); abort(); } rc_destroy(&compiler.Base); r300_dummy_fragment_shader(r300, shader); return; } /* Shaders with zero instructions are invalid, * use the dummy shader instead. */ if (shader->code.code.r500.inst_end == -1) { rc_destroy(&compiler.Base); r300_dummy_fragment_shader(r300, shader); return; } /* Initialize numbers of constants for each type. */ shader->externals_count = 0; for (i = 0; i < shader->code.constants.Count && shader->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) { shader->externals_count = i+1; } shader->immediates_count = 0; shader->rc_state_count = 0; for (i = shader->externals_count; i < shader->code.constants.Count; i++) { switch (shader->code.constants.Constants[i].Type) { case RC_CONSTANT_IMMEDIATE: ++shader->immediates_count; break; case RC_CONSTANT_STATE: ++shader->rc_state_count; break; default: assert(0); } } /* Setup shader depth output. */ if (shader->code.writes_depth) { shader->fg_depth_src = R300_FG_DEPTH_SRC_SHADER; shader->us_out_w = R300_W_FMT_W24 | R300_W_SRC_US; } else { shader->fg_depth_src = R300_FG_DEPTH_SRC_SCAN; shader->us_out_w = R300_W_FMT_W0 | R300_W_SRC_US; } /* And, finally... */ rc_destroy(&compiler.Base); /* Build the command buffer. */ r300_emit_fs_code_to_buffer(r300, shader); }