summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600/drm/r600_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600/drm/r600_state.c')
-rw-r--r--src/gallium/winsys/r600/drm/r600_state.c198
1 files changed, 181 insertions, 17 deletions
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;
}