From 50526e094f4c66957c7f74c190c35903bc82fb62 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 3 Sep 2010 14:38:41 +1000 Subject: r600g: add initial evergreen support adds shader opcodes + assembler support (except ARL) uses constant buffers add interp instructions in fragment shader adds all evergreen hw states adds evergreen pm4 support. this runs gears for me on my evergreen --- src/gallium/winsys/r600/drm/r600_state.c | 198 ++++++++++++++++++++++++++++--- 1 file changed, 181 insertions(+), 17 deletions(-) (limited to 'src/gallium/winsys/r600/drm/r600_state.c') diff --git a/src/gallium/winsys/r600/drm/r600_state.c b/src/gallium/winsys/r600/drm/r600_state.c index 3160beace7..3570ee1485 100644 --- a/src/gallium/winsys/r600/drm/r600_state.c +++ b/src/gallium/winsys/r600/drm/r600_state.c @@ -46,7 +46,10 @@ static int r700_state_pm4_config(struct radeon_state *state); static int r600_state_pm4_db_flush(struct radeon_state *state); static int r600_state_pm4_cb_flush(struct radeon_state *state); +static int eg_state_pm4_vgt(struct radeon_state *state); + #include "r600_states.h" +#include "eg_states.h" #define SUB_NONE(param) { { 0, R600_names_##param, (sizeof(R600_names_##param)/sizeof(struct radeon_register)) } } @@ -55,6 +58,12 @@ static int r600_state_pm4_cb_flush(struct radeon_state *state); #define SUB_GS(param) { R600_SHADER_GS, R600_names_##param, (sizeof(R600_names_##param)/sizeof(struct radeon_register)) } #define SUB_FS(param) { R600_SHADER_FS, R600_names_##param, (sizeof(R600_names_##param)/sizeof(struct radeon_register)) } +#define EG_SUB_NONE(param) { { 0, EG_names_##param, (sizeof(EG_names_##param)/sizeof(struct radeon_register)) } } +#define EG_SUB_PS(param) { R600_SHADER_PS, EG_names_##param, (sizeof(EG_names_##param)/sizeof(struct radeon_register)) } +#define EG_SUB_VS(param) { R600_SHADER_VS, EG_names_##param, (sizeof(EG_names_##param)/sizeof(struct radeon_register)) } +#define EG_SUB_GS(param) { R600_SHADER_GS, EG_names_##param, (sizeof(EG_names_##param)/sizeof(struct radeon_register)) } +#define EG_SUB_FS(param) { R600_SHADER_FS, EG_names_##param, (sizeof(EG_names_##param)/sizeof(struct radeon_register)) } + /* some of these are overriden at runtime for R700 */ struct radeon_stype_info r600_stypes[] = { { R600_STATE_CONFIG, 1, 0, r600_state_pm4_config, SUB_NONE(CONFIG), }, @@ -89,6 +98,39 @@ struct radeon_stype_info r600_stypes[] = { }; #define STYPES_SIZE Elements(r600_stypes) +struct radeon_stype_info eg_stypes[] = { + { R600_STATE_CONFIG, 1, 0, r700_state_pm4_config, EG_SUB_NONE(CONFIG), }, + { R600_STATE_CB_CNTL, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB_CNTL) }, + { R600_STATE_RASTERIZER, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(RASTERIZER) }, + { R600_STATE_VIEWPORT, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(VIEWPORT) }, + { R600_STATE_SCISSOR, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(SCISSOR) }, + { R600_STATE_BLEND, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(BLEND), }, + { R600_STATE_DSA, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(DSA), }, + { R600_STATE_SHADER, 1, 0, r600_state_pm4_shader, { EG_SUB_PS(PS_SHADER), EG_SUB_VS(VS_SHADER) } }, + { R600_STATE_CBUF, 1, 0, r600_state_pm4_shader, { EG_SUB_PS(PS_CBUF), EG_SUB_VS(VS_CBUF) } }, + { R600_STATE_RESOURCE, 176, 0x20, r600_state_pm4_resource, { EG_SUB_PS(PS_RESOURCE), EG_SUB_VS(VS_RESOURCE), EG_SUB_GS(GS_RESOURCE), EG_SUB_FS(FS_RESOURCE)} }, + { R600_STATE_SAMPLER, 18, 0xc, r600_state_pm4_generic, { EG_SUB_PS(PS_SAMPLER), EG_SUB_VS(VS_SAMPLER), EG_SUB_GS(GS_SAMPLER) } }, + { R600_STATE_SAMPLER_BORDER, 18, 0x10, r600_state_pm4_generic, { EG_SUB_PS(PS_SAMPLER_BORDER), EG_SUB_VS(VS_SAMPLER_BORDER), EG_SUB_GS(GS_SAMPLER_BORDER) } }, + { R600_STATE_CB0, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB0) }, + { R600_STATE_CB1, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB1) }, + { R600_STATE_CB2, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB2) }, + { R600_STATE_CB3, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB3) }, + { R600_STATE_CB4, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB4) }, + { R600_STATE_CB5, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB5) }, + { R600_STATE_CB6, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB6) }, + { R600_STATE_CB7, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(CB7) }, + { R600_STATE_QUERY_BEGIN, 1, 0, r600_state_pm4_query_begin, EG_SUB_NONE(VGT_EVENT) }, + { R600_STATE_QUERY_END, 1, 0, r600_state_pm4_query_end, EG_SUB_NONE(VGT_EVENT) }, + { R600_STATE_DB, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(DB) }, + { R600_STATE_UCP, 1, 0, r600_state_pm4_generic, EG_SUB_NONE(UCP) }, + { R600_STATE_VGT, 1, 0, eg_state_pm4_vgt, EG_SUB_NONE(VGT) }, + { R600_STATE_DRAW, 1, 0, r600_state_pm4_draw, EG_SUB_NONE(DRAW) }, + { R600_STATE_CB_FLUSH, 1, 0, r600_state_pm4_cb_flush, EG_SUB_NONE(CB_FLUSH) }, + { R600_STATE_DB_FLUSH, 1, 0, r600_state_pm4_db_flush, EG_SUB_NONE(DB_FLUSH) }, + +}; +#define EG_STYPES_SIZE Elements(eg_stypes) + static const struct radeon_register *get_regs(struct radeon_state *state) { return state->stype->reginfo[state->shader_index].regs; @@ -162,6 +204,72 @@ static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, return -EINVAL; } +static int eg_state_pm4_bytecode(struct radeon_state *state, unsigned offset, unsigned id, unsigned nreg) +{ + const struct radeon_register *regs = get_regs(state); + unsigned i; + int r; + + if (!offset) { + fprintf(stderr, "%s invalid register for state %d %d\n", + __func__, state->stype->stype, id); + return -EINVAL; + } + if (offset >= R600_CONFIG_REG_OFFSET && offset < R600_CONFIG_REG_END) { + state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, nreg); + state->pm4[state->cpm4++] = (offset - R600_CONFIG_REG_OFFSET) >> 2; + for (i = 0; i < nreg; i++) { + state->pm4[state->cpm4++] = state->states[id + i]; + } + for (i = 0; i < nreg; i++) { + if (regs[id + i].need_reloc) { + state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0); + r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); + if (r) + return r; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + } + } + return 0; + } + if (offset >= R600_CONTEXT_REG_OFFSET && offset < R600_CONTEXT_REG_END) { + state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONTEXT_REG, nreg); + state->pm4[state->cpm4++] = (offset - R600_CONTEXT_REG_OFFSET) >> 2; + for (i = 0; i < nreg; i++) { + state->pm4[state->cpm4++] = state->states[id + i]; + } + for (i = 0; i < nreg; i++) { + if (regs[id + i].need_reloc) { + state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0); + r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id); + if (r) + return r; + state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle; + } + } + return 0; + } + if (offset >= EG_RESOURCE_OFFSET && offset < EG_RESOURCE_END) { + state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, nreg); + state->pm4[state->cpm4++] = (offset - EG_RESOURCE_OFFSET) >> 2; + for (i = 0; i < nreg; i++) { + state->pm4[state->cpm4++] = state->states[id + i]; + } + return 0; + } + if (offset >= R600_SAMPLER_OFFSET && offset < R600_SAMPLER_END) { + state->pm4[state->cpm4++] = PKT3(PKT3_SET_SAMPLER, nreg); + state->pm4[state->cpm4++] = (offset - R600_SAMPLER_OFFSET) >> 2; + for (i = 0; i < nreg; i++) { + state->pm4[state->cpm4++] = state->states[id + i]; + } + return 0; + } + fprintf(stderr, "%s unsupported offset 0x%08X\n", __func__, offset); + return -EINVAL; +} + + static int r600_state_pm4_generic(struct radeon_state *state) { const struct radeon_register *regs = get_regs(state); @@ -180,7 +288,10 @@ static int r600_state_pm4_generic(struct radeon_state *state) nreg++; loffset = coffset; } else { - r = r600_state_pm4_bytecode(state, offset, start, nreg); + if (state->radeon->family >= CHIP_CEDAR) + r = eg_state_pm4_bytecode(state, offset, start, nreg); + else + r = r600_state_pm4_bytecode(state, offset, start, nreg); if (r) { fprintf(stderr, "%s invalid 0x%08X %d\n", __func__, start, nreg); return r; @@ -190,7 +301,11 @@ static int r600_state_pm4_generic(struct radeon_state *state) start = i; } } - return r600_state_pm4_bytecode(state, offset, start, nreg); + if (state->radeon->family >= CHIP_CEDAR) + r = eg_state_pm4_bytecode(state, offset, start, nreg); + else + r = r600_state_pm4_bytecode(state, offset, start, nreg); + return r; } static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags) @@ -314,6 +429,28 @@ static int r600_state_pm4_shader(struct radeon_state *state) return r600_state_pm4_generic(state); } +static int eg_state_pm4_vgt(struct radeon_state *state) +{ + int r; + r = eg_state_pm4_bytecode(state, R_028400_VGT_MAX_VTX_INDX, EG_VGT__VGT_MAX_VTX_INDX, 1); + if (r) + return r; + r = eg_state_pm4_bytecode(state, R_028404_VGT_MIN_VTX_INDX, EG_VGT__VGT_MIN_VTX_INDX, 1); + if (r) + return r; + r = eg_state_pm4_bytecode(state, R_028408_VGT_INDX_OFFSET, EG_VGT__VGT_INDX_OFFSET, 1); + if (r) + return r; + r = eg_state_pm4_bytecode(state, R_008958_VGT_PRIMITIVE_TYPE, EG_VGT__VGT_PRIMITIVE_TYPE, 1); + if (r) + return r; + state->pm4[state->cpm4++] = PKT3(PKT3_INDEX_TYPE, 0); + state->pm4[state->cpm4++] = state->states[EG_VGT__VGT_DMA_INDEX_TYPE]; + state->pm4[state->cpm4++] = PKT3(PKT3_NUM_INSTANCES, 0); + state->pm4[state->cpm4++] = state->states[EG_VGT__VGT_DMA_NUM_INSTANCES]; + return 0; +} + static int r600_state_pm4_vgt(struct radeon_state *state) { int r; @@ -362,6 +499,7 @@ static int r600_state_pm4_draw(struct radeon_state *state) } state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0); state->pm4[state->cpm4++] = EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT; + return 0; } @@ -390,11 +528,15 @@ static int r600_state_pm4_db_flush(struct radeon_state *state) static int r600_state_pm4_resource(struct radeon_state *state) { u32 flags, type, nbo, offset, soffset; - int r; + int r, nres; const struct radeon_register *regs = get_regs(state); soffset = state->id * state->stype->stride; - type = G_038018_TYPE(state->states[6]); + if (state->radeon->family >= CHIP_CEDAR) + type = G_038018_TYPE(state->states[7]); + else + type = G_038018_TYPE(state->states[6]); + switch (type) { case 2: flags = S_0085F0_TC_ACTION_ENA(1); @@ -413,8 +555,15 @@ static int r600_state_pm4_resource(struct radeon_state *state) } r600_state_pm4_with_flush(state, flags); offset = regs[0].offset + soffset; - state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, 7); - state->pm4[state->cpm4++] = (offset - R_038000_SQ_TEX_RESOURCE_WORD0_0) >> 2; + if (state->radeon->family >= CHIP_CEDAR) + nres = 8; + else + nres = 7; + state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, nres); + if (state->radeon->family >= CHIP_CEDAR) + state->pm4[state->cpm4++] = (offset - EG_RESOURCE_OFFSET) >> 2; + else + state->pm4[state->cpm4++] = (offset - R_038000_SQ_TEX_RESOURCE_WORD0_0) >> 2; state->pm4[state->cpm4++] = state->states[0]; state->pm4[state->cpm4++] = state->states[1]; state->pm4[state->cpm4++] = state->states[2]; @@ -422,6 +571,9 @@ static int r600_state_pm4_resource(struct radeon_state *state) state->pm4[state->cpm4++] = state->states[4]; state->pm4[state->cpm4++] = state->states[5]; state->pm4[state->cpm4++] = state->states[6]; + if (state->radeon->family >= CHIP_CEDAR) + state->pm4[state->cpm4++] = state->states[7]; + state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0); r = radeon_state_reloc(state, state->cpm4, 0); if (r) @@ -469,31 +621,43 @@ static void r600_modify_type_array(struct radeon *radeon) } } -static void r600_build_types_array(struct radeon *radeon) +static void build_types_array(struct radeon *radeon, struct radeon_stype_info *types, int size) { int i, j; int id = 0; - for (i = 0; i < STYPES_SIZE; i++) { - r600_stypes[i].base_id = id; - r600_stypes[i].npm4 = 128; - if (r600_stypes[i].reginfo[0].shader_type == 0) { - id += r600_stypes[i].num; + for (i = 0; i < size; i++) { + types[i].base_id = id; + types[i].npm4 = 128; + if (types[i].reginfo[0].shader_type == 0) { + id += types[i].num; } else { for (j = 0; j < R600_SHADER_MAX; j++) { - if (r600_stypes[i].reginfo[j].shader_type) - id += r600_stypes[i].num; + if (types[i].reginfo[j].shader_type) + id += types[i].num; } } } - radeon->stype = r600_stypes; - radeon->nstype = STYPES_SIZE; + radeon->stype = types; + radeon->nstype = size; +} +static void r600_build_types_array(struct radeon *radeon) +{ + build_types_array(radeon, r600_stypes, STYPES_SIZE); r600_modify_type_array(radeon); } +static void eg_build_types_array(struct radeon *radeon) +{ + build_types_array(radeon, eg_stypes, EG_STYPES_SIZE); +} + int r600_init(struct radeon *radeon) { - r600_build_types_array(radeon); + if (radeon->family >= CHIP_CEDAR) + eg_build_types_array(radeon); + else + r600_build_types_array(radeon); return 0; } -- cgit v1.2.3