static void r700SendFSState(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context); struct radeon_bo * pbo; BATCH_LOCALS(&context->radeon); radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__); /* XXX fixme * R6xx chips require a FS be emitted, even if it's not used. * since we aren't using FS yet, just send the VS address to make * the kernel command checker happy */ pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context)); r700->fs.SQ_PGM_START_FS.u32All = r700->vs.SQ_PGM_START_VS.u32All; r700->fs.SQ_PGM_RESOURCES_FS.u32All = 0; r700->fs.SQ_PGM_CF_OFFSET_FS.u32All = 0; /* XXX */ if (!pbo) return; r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit); BEGIN_BATCH_NO_AUTOSTATE(3 + 2); R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1); R600_OUT_BATCH(r700->fs.SQ_PGM_START_FS.u32All); R600_OUT_BATCH_RELOC(r700->fs.SQ_PGM_START_FS.u32All, pbo, r700->fs.SQ_PGM_START_FS.u32All, RADEON_GEM_DOMAIN_GTT, 0, 0); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(6); R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_FS, r700->fs.SQ_PGM_RESOURCES_FS.u32All); R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_FS, r700->fs.SQ_PGM_CF_OFFSET_FS.u32All); END_BATCH(); COMMIT_BATCH(); }
static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context); struct radeon_bo * pbo; BATCH_LOCALS(&context->radeon); radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__); pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(GL_CONTEXT(context)); if (!pbo) return; r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit); BEGIN_BATCH_NO_AUTOSTATE(3 + 2); R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1); R600_OUT_BATCH(r700->ps.SQ_PGM_START_PS.u32All); R600_OUT_BATCH_RELOC(r700->ps.SQ_PGM_START_PS.u32All, pbo, r700->ps.SQ_PGM_START_PS.u32All, RADEON_GEM_DOMAIN_GTT, 0, 0); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(9); R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, r700->ps.SQ_PGM_RESOURCES_PS.u32All); R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, r700->ps.SQ_PGM_EXPORTS_PS.u32All); R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, r700->ps.SQ_PGM_CF_OFFSET_PS.u32All); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(3); R600_OUT_BATCH_REGVAL(SQ_LOOP_CONST_0, 0x01000FFF); END_BATCH(); COMMIT_BATCH(); }
static void r700SetupVTXConstants(GLcontext * ctx, void * pAos, StreamDesc * pStreamDesc) { context_t *context = R700_CONTEXT(ctx); struct radeon_aos * paos = (struct radeon_aos *)pAos; unsigned int nVBsize; BATCH_LOCALS(&context->radeon); unsigned int uSQ_VTX_CONSTANT_WORD0_0; unsigned int uSQ_VTX_CONSTANT_WORD1_0; unsigned int uSQ_VTX_CONSTANT_WORD2_0 = 0; unsigned int uSQ_VTX_CONSTANT_WORD3_0 = 0; unsigned int uSQ_VTX_CONSTANT_WORD6_0 = 0; if (!paos->bo) return; if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) || (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) || (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) || (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) || (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710)) r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit); else r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit); if(0 == pStreamDesc->stride) { nVBsize = paos->count * pStreamDesc->size * getTypeSize(pStreamDesc->type); } else { nVBsize = (paos->count - 1) * pStreamDesc->stride + pStreamDesc->size * getTypeSize(pStreamDesc->type); } uSQ_VTX_CONSTANT_WORD0_0 = paos->offset; uSQ_VTX_CONSTANT_WORD1_0 = nVBsize - 1; SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); /* TODO */ SETfield(uSQ_VTX_CONSTANT_WORD2_0, pStreamDesc->stride, SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift, SQ_VTX_CONSTANT_WORD2_0__STRIDE_mask); SETfield(uSQ_VTX_CONSTANT_WORD2_0, GetSurfaceFormat(pStreamDesc->type, pStreamDesc->size, NULL), SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_shift, SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_mask); /* TODO : trace back api for initial data type, not only GL_FLOAT */ if(GL_TRUE == pStreamDesc->normalize) { SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_NORM, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask); } else { SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask); } if(1 == pStreamDesc->_signed) { SETbit(uSQ_VTX_CONSTANT_WORD2_0, SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit); } SETfield(uSQ_VTX_CONSTANT_WORD3_0, 1, MEM_REQUEST_SIZE_shift, MEM_REQUEST_SIZE_mask); SETfield(uSQ_VTX_CONSTANT_WORD6_0, SQ_TEX_VTX_VALID_BUFFER, SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask); BEGIN_BATCH_NO_AUTOSTATE(9 + 2); R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); R600_OUT_BATCH((pStreamDesc->element + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE); R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD0_0); R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD1_0); R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD2_0); R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD3_0); R600_OUT_BATCH(0); R600_OUT_BATCH(0); R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD6_0); R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0, paos->bo, uSQ_VTX_CONSTANT_WORD0_0, RADEON_GEM_DOMAIN_GTT, 0, 0); END_BATCH(); COMMIT_BATCH(); }
static void r700SendTexState(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); struct r700_vertex_program *vp = context->selected_vp; struct radeon_bo *bo = NULL; unsigned int i; BATCH_LOCALS(&context->radeon); radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__); for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { radeonTexObj *t = r700->textures[i]; if (t) { if (!t->image_override) { bo = t->mt->bo; } else { bo = t->bo; } if (bo) { r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, TC_ACTION_ENA_bit); BEGIN_BATCH_NO_AUTOSTATE(9 + 4); R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); if( (1<<i) & vp->r700AsmCode.unVetTexBits ) { /* vs texture */ R600_OUT_BATCH((i + VERT_ATTRIB_MAX + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE); } else { R600_OUT_BATCH(i * 7); } R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE2); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE3); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5); R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6); R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2, bo, r700->textures[i]->SQ_TEX_RESOURCE2, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3, bo, r700->textures[i]->SQ_TEX_RESOURCE3, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); END_BATCH(); COMMIT_BATCH(); } } } } }
static GLboolean evergreenTryDrawPrims(GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, GLuint max_index ) { context_t *context = EVERGREEN_CONTEXT(ctx); radeonContextPtr radeon = &context->radeon; GLuint i, id = 0; struct radeon_renderbuffer *rrb; if (ctx->NewState) _mesa_update_state( ctx ); if (evergreen_check_fallbacks(ctx)) return GL_FALSE; _tnl_UpdateFixedFunctionProgram(ctx); evergreenSetVertexFormat(ctx, arrays, max_index + 1); /* shaders need to be updated before buffers are validated */ evergreenUpdateShaders(ctx); if (!evergreenValidateBuffers(ctx)) return GL_FALSE; /* always emit CB base to prevent * lock ups on some chips. */ EVERGREEN_STATECHANGE(context, cb); /* mark vtx as dirty since it changes per-draw */ EVERGREEN_STATECHANGE(context, vtx); evergreenSetScissor(context); evergreenSetupVertexProgram(ctx); evergreenSetupFragmentProgram(ctx); evergreenUpdateShaderStates(ctx); GLuint emit_end = evergreenPredictRenderSize(ctx, prim, ib, nr_prims) + context->radeon.cmdbuf.cs->cdw; /* evergreenPredictRenderSize will call radeonReleaseDmaRegions, so update VP/FP const buf after it. */ evergreenSetupVPconstants(ctx); evergreenSetupFPconstants(ctx); evergreenSetupIndexBuffer(ctx, ib); evergreenSetupStreams(ctx, arrays, max_index + 1); radeonEmitState(radeon); radeon_debug_add_indent(); for (i = 0; i < nr_prims; ++i) { if (context->ind_buf.bo) evergreenRunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode, prim[i].basevertex); else evergreenRunRenderPrimitiveImmediate(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode); } radeon_debug_remove_indent(); /* Flush render op cached for last several quads. */ /* XXX drm should handle this in fence submit */ //evergreeWaitForIdleClean(context); rrb = radeon_get_colorbuffer(&context->radeon); if (rrb && rrb->bo) r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM, CB_ACTION_ENA_bit | (1 << (id + 6))); rrb = radeon_get_depthbuffer(&context->radeon); if (rrb && rrb->bo) r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM, DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit); evergreenFreeData(ctx); if (emit_end < context->radeon.cmdbuf.cs->cdw) { WARN_ONCE("Rendering was %d commands larger than predicted size." " We might overflow command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end); } return GL_TRUE; }