};
/* SHADER RESOURCE R600/R700 */
-static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset)
+static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride)
{
struct r600_reg r600_shader_resource[] = {
{R_030000_RESOURCE0_WORD0, 0, 0, 0},
};
unsigned nreg = Elements(r600_shader_resource);
- for (int i = 0; i < nreg; i++) {
- r600_shader_resource[i].offset += offset;
- }
- return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET);
+ return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, EVERGREEN_RESOURCE_OFFSET);
}
/* SHADER SAMPLER R600/R700 */
if (r)
goto out_err;
}
- /* PS RESOURCE */
- for (int j = 0, offset = 0; j < 176; j++, offset += 0x20) {
- r = evergreen_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
- /* VS RESOURCE */
- for (int j = 0, offset = 0x1600; j < 160; j++, offset += 0x20) {
- r = evergreen_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
- /* FS RESOURCE */
- for (int j = 0, offset = 0x7C00; j < 16; j++, offset += 0x20) {
- r = evergreen_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
+
+ ctx->num_ps_resources = 176;
+ ctx->num_vs_resources = 160;
+ ctx->num_fs_resources = 16;
+ r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 176, 0x20);
+ if (r)
+ goto out_err;
+ r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1600, 160, 0x20);
+ if (r)
+ goto out_err;
+ r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x7C00, 16, 0x20);
+ if (r)
+ goto out_err;
/* PS loop const */
evergreen_loop_const_init(ctx, 0);
void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x20 * rid;
+ struct r600_block *block = ctx->ps_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x1600 + 0x20 * rid;
+ struct r600_block *block = ctx->vs_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x7C00 + 0x20 * rid;
+ struct r600_block *block = ctx->fs_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
static inline void evergreen_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)
};
/* SHADER RESOURCE R600/R700 */
-static int r600_state_resource_init(struct r600_context *ctx, u32 offset)
+int r600_resource_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride, struct r600_reg *reg, int nreg, unsigned offset_base)
+{
+ int i;
+ struct r600_block *block;
+ range->blocks = calloc(nblocks, sizeof(struct r600_block *));
+ if (range->blocks == NULL)
+ return -ENOMEM;
+
+ reg[0].offset += offset;
+ for (i = 0; i < nblocks; i++) {
+ block = calloc(1, sizeof(struct r600_block));
+ if (block == NULL) {
+ return -ENOMEM;
+ }
+ ctx->nblocks++;
+ range->blocks[i] = block;
+ r600_init_block(ctx, block, reg, 0, nreg, PKT3_SET_RESOURCE, offset_base);
+
+ reg[0].offset += stride;
+ }
+ return 0;
+}
+
+
+static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride)
{
struct r600_reg r600_shader_resource[] = {
{R_038000_RESOURCE0_WORD0, 0, 0, 0},
};
unsigned nreg = Elements(r600_shader_resource);
- for (int i = 0; i < nreg; i++) {
- r600_shader_resource[i].offset += offset;
- }
- return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET);
+ return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, R600_RESOURCE_OFFSET);
}
/* SHADER SAMPLER R600/R700 */
}
}
+static void r600_free_resource_range(struct r600_context *ctx, struct r600_range *range, int nblocks)
+{
+ struct r600_block *block;
+ int i;
+ for (i = 0; i < nblocks; i++) {
+ block = range->blocks[i];
+ if (block) {
+ for (int k = 1; k <= block->nbo; k++)
+ r600_bo_reference(ctx->radeon, &block->reloc[k].bo, NULL);
+ free(block);
+ }
+ }
+ free(range->blocks);
+
+}
+
/* initialize */
void r600_context_fini(struct r600_context *ctx)
{
}
free(ctx->range[i].blocks);
}
+ r600_free_resource_range(ctx, &ctx->ps_resources, ctx->num_ps_resources);
+ r600_free_resource_range(ctx, &ctx->vs_resources, ctx->num_vs_resources);
+ r600_free_resource_range(ctx, &ctx->fs_resources, ctx->num_fs_resources);
free(ctx->range);
free(ctx->blocks);
free(ctx->reloc);
memset(ctx, 0, sizeof(struct r600_context));
}
+static void r600_add_resource_block(struct r600_context *ctx, struct r600_range *range, int num_blocks, int *index)
+{
+ int c = *index;
+ for (int j = 0; j < num_blocks; j++) {
+ if (!range->blocks[j])
+ continue;
+
+ ctx->blocks[c++] = range->blocks[j];
+ }
+ *index = c;
+}
+
int r600_setup_block_table(struct r600_context *ctx)
{
/* setup block table */
+ int c = 0;
ctx->blocks = calloc(ctx->nblocks, sizeof(void*));
if (!ctx->blocks)
return -ENOMEM;
- for (int i = 0, c = 0; i < NUM_RANGES; i++) {
+ for (int i = 0; i < NUM_RANGES; i++) {
if (!ctx->range[i].blocks)
continue;
for (int j = 0, add; j < (1 << HASH_SHIFT); j++) {
}
}
}
+
+ r600_add_resource_block(ctx, &ctx->ps_resources, ctx->num_ps_resources, &c);
+ r600_add_resource_block(ctx, &ctx->vs_resources, ctx->num_vs_resources, &c);
+ r600_add_resource_block(ctx, &ctx->fs_resources, ctx->num_fs_resources, &c);
return 0;
}
if (r)
goto out_err;
}
- /* PS RESOURCE */
- for (int j = 0, offset = 0; j < 160; j++, offset += 0x1C) {
- r = r600_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
- /* VS RESOURCE */
- for (int j = 0, offset = 0x1180; j < 160; j++, offset += 0x1C) {
- r = r600_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
- /* FS RESOURCE */
- for (int j = 0, offset = 0x2300; j < 16; j++, offset += 0x1C) {
- r = r600_state_resource_init(ctx, offset);
- if (r)
- goto out_err;
- }
+
+ ctx->num_ps_resources = 160;
+ ctx->num_vs_resources = 160;
+ ctx->num_fs_resources = 16;
+ r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 160, 0x1c);
+ if (r)
+ goto out_err;
+ r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1180, 160, 0x1c);
+ if (r)
+ goto out_err;
+ r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x2300, 16, 0x1c);
+ if (r)
+ goto out_err;
/* PS loop const */
r600_loop_const_init(ctx, 0);
}
}
-void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned offset)
+void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, struct r600_block *block)
{
- struct r600_range *range;
- struct r600_block *block;
int i;
int dirty;
int num_regs = ctx->radeon->chip_class >= EVERGREEN ? 8 : 7;
boolean is_vertex;
- range = &ctx->range[CTX_RANGE_ID(offset)];
- block = range->blocks[CTX_BLOCK_ID(offset)];
if (state == NULL) {
block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
if (block->reloc[1].bo)
void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1C * rid;
+ struct r600_block *block = ctx->ps_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1180 + 0x1C * rid;
+ struct r600_block *block = ctx->vs_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
{
- unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x2300 + 0x1C * rid;
+ struct r600_block *block = ctx->fs_resources.blocks[rid];
- r600_context_pipe_state_set_resource(ctx, state, offset);
+ r600_context_pipe_state_set_resource(ctx, state, block);
}
static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)