+
+ /* Some states must be marked as dirty here to properly set up
+ * hardware in the first command stream. */
+ r300_mark_atom_dirty(r300, &r300->invariant_state);
+ r300_mark_atom_dirty(r300, &r300->pvs_flush);
+ r300_mark_atom_dirty(r300, &r300->vap_invariant_state);
+ r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
+ r300_mark_atom_dirty(r300, &r300->textures_state);
+
+ return TRUE;
+}
+
+/* Not every gallium frontend calls every driver function before the first draw
+ * call and we must initialize the command buffers somehow. */
+static void r300_init_states(struct pipe_context *pipe)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct pipe_blend_color bc = {{0}};
+ struct pipe_clip_state cs = {{{0}}};
+ struct pipe_scissor_state ss = {0};
+ struct r300_gpu_flush *gpuflush =
+ (struct r300_gpu_flush*)r300->gpu_flush.state;
+ struct r300_vap_invariant_state *vap_invariant =
+ (struct r300_vap_invariant_state*)r300->vap_invariant_state.state;
+ struct r300_invariant_state *invariant =
+ (struct r300_invariant_state*)r300->invariant_state.state;
+
+ CB_LOCALS;
+
+ pipe->set_blend_color(pipe, &bc);
+ pipe->set_clip_state(pipe, &cs);
+ pipe->set_scissor_states(pipe, 0, 1, &ss);
+ pipe->set_sample_mask(pipe, ~0);
+
+ /* Initialize the GPU flush. */
+ {
+ BEGIN_CB(gpuflush->cb_flush_clean, 6);
+
+ /* Flush and free renderbuffer caches. */
+ OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT,
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
+ OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT,
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+
+ /* Wait until the GPU is idle.
+ * This fixes random pixels sometimes appearing probably caused
+ * by incomplete rendering. */
+ OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+ END_CB;
+ }
+
+ /* Initialize the VAP invariant state. */
+ {
+ BEGIN_CB(vap_invariant->cb, r300->vap_invariant_state.size);
+ OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
+ OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
+ OUT_CB_32F(1.0);
+ OUT_CB_32F(1.0);
+ OUT_CB_32F(1.0);
+ OUT_CB_32F(1.0);
+ OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
+
+ if (r300->screen->caps.is_r500) {
+ OUT_CB_REG(R500_VAP_TEX_TO_COLOR_CNTL, 0);
+ } else if (!r300->screen->caps.has_tcl) {
+ /* RSxxx:
+ * Static VAP setup since r300_emit_vs_state() is never called.
+ */
+ OUT_CB_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |
+ R300_PVS_NUM_CNTLRS(5) |
+ R300_PVS_NUM_FPUS(2) |
+ R300_PVS_VF_MAX_VTX_NUM(5));
+ }
+ END_CB;
+ }
+
+ /* Initialize the invariant state. */
+ {
+ BEGIN_CB(invariant->cb, r300->invariant_state.size);
+ OUT_CB_REG(R300_GB_SELECT, 0);
+ OUT_CB_REG(R300_FG_FOG_BLEND, 0);
+ OUT_CB_REG(R300_GA_OFFSET, 0);
+ OUT_CB_REG(R300_SU_TEX_WRAP, 0);
+ OUT_CB_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF);
+ OUT_CB_REG(R300_SU_DEPTH_OFFSET, 0);
+ OUT_CB_REG(R300_SC_EDGERULE, 0x2DA49525);
+
+ if (r300->screen->caps.is_rv350) {
+ OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
+ OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
+ }
+
+ if (r300->screen->caps.is_r500) {
+ OUT_CB_REG(R500_GA_COLOR_CONTROL_PS3, 0);
+ OUT_CB_REG(R500_SU_TEX_WRAP_PS3, 0);
+ }
+ END_CB;
+ }
+
+ /* Initialize the hyperz state. */
+ {
+ struct r300_hyperz_state *hyperz =
+ (struct r300_hyperz_state*)r300->hyperz_state.state;
+ BEGIN_CB(&hyperz->cb_flush_begin, r300->hyperz_state.size);
+ OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT,
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE);
+ OUT_CB_REG(R300_ZB_BW_CNTL, 0);
+ OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0);
+ OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2);
+
+ if (r300->screen->caps.is_r500 || r300->screen->caps.is_rv350) {
+ OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0);
+ }
+ END_CB;
+ }