uint32_t cindices;
uint32_t *indices;
uint32_t *reloc_indices;
- struct offset_modifiers offset_mod;
};
+
static struct radeon_cs * r600_cs_create(struct radeon_cs_manager *csm,
uint32_t ndw)
{
return cs;
}
-int r600_cs_write_reloc(struct radeon_cs *cs,
- struct radeon_bo *bo,
- uint32_t read_domain,
- uint32_t write_domain,
- uint32_t flags,
- offset_modifiers* poffset_mod)
+static int r600_cs_write_reloc(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
{
struct r600_cs_reloc_legacy *relocs;
int i;
}
relocs[i].indices = indices;
relocs[i].reloc_indices = reloc_indices;
- relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1;
- relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->section_cdw;
- cs->section_ndw += 2;
+ relocs[i].indices[relocs[i].cindices - 1] = cs->cdw;
+ relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->cdw;
cs->section_cdw += 2;
-
- relocs[i].offset_mod.shift = poffset_mod->shift;
- relocs[i].offset_mod.shiftbits = poffset_mod->shiftbits;
- relocs[i].offset_mod.mask = poffset_mod->mask;
+ cs->cdw += 2;
return 0;
}
{
return -ENOMEM;
}
- relocs[cs->crelocs].offset_mod.shift = poffset_mod->shift;
- relocs[cs->crelocs].offset_mod.shiftbits = poffset_mod->shiftbits;
- relocs[cs->crelocs].offset_mod.mask = poffset_mod->mask;
- relocs[cs->crelocs].indices[0] = cs->cdw - 1;
- relocs[cs->crelocs].reloc_indices[0] = cs->section_cdw;
- cs->section_ndw += 2;
+ relocs[cs->crelocs].indices[0] = cs->cdw;
+ relocs[cs->crelocs].reloc_indices[0] = cs->cdw;
cs->section_cdw += 2;
+ cs->cdw += 2;
relocs[cs->crelocs].cindices = 1;
cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
cs->crelocs++;
return -EPIPE;
}
- if (cs->cdw + ndw + 32 > cs->ndw) { /* Left 32 DWORD (8 offset+pitch) spare room for reloc indices */
+ cs->section = 1;
+ cs->section_ndw = ndw;
+ cs->section_cdw = 0;
+ cs->section_file = file;
+ cs->section_func = func;
+ cs->section_line = line;
+
+ if (cs->cdw + ndw > cs->ndw) {
uint32_t tmp, *ptr;
- int num = (ndw > 0x3FF) ? ndw : 0x3FF;
+ int num = (ndw > 0x400) ? ndw : 0x400;
- tmp = (cs->cdw + 1 + num) & (~num);
+ tmp = (cs->cdw + num + 0x3FF) & (~0x3FF);
ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
if (ptr == NULL) {
return -ENOMEM;
cs->ndw = tmp;
}
- cs->section = 1;
- cs->section_ndw = 0;
- cs->section_cdw = cs->cdw + ndw; /* start of reloc indices. */
- cs->section_file = file;
- cs->section_func = func;
- cs->section_line = line;
-
return 0;
}
}
cs->section = 0;
- if ( (cs->section_ndw + cs->cdw) != cs->section_cdw )
- {
+ if ( cs->section_ndw != cs->section_cdw ) {
fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
fprintf(stderr, "cs->section_ndw = %d, cs->cdw = %d, cs->section_cdw = %d \n",
return -EPIPE;
}
- cs->cdw = cs->section_cdw;
+ if (cs->cdw > cs->ndw) {
+ fprintf(stderr, "CS section overflow at (%s,%s,%d) cdw %d ndw %d\n",
+ cs->section_file, cs->section_func, cs->section_line,cs->cdw,cs->ndw);
+ fprintf(stderr, "CS section end at (%s,%s,%d)\n",
+ file, func, line);
+ assert(0);
+ }
+
return 0;
}
csm = (struct r600_cs_manager_legacy*)cs->csm;
relocs = (struct r600_cs_reloc_legacy *)cs->relocs;
restart:
- for (i = 0; i < cs->crelocs; i++)
- {
- for (j = 0; j < relocs[i].cindices; j++)
- {
- uint32_t soffset, eoffset, asicoffset;
+ for (i = 0; i < cs->crelocs; i++) {
+ uint32_t soffset, eoffset;
r = radeon_bo_legacy_validate(relocs[i].base.bo,
- &soffset, &eoffset);
- if (r == -EAGAIN)
- {
- goto restart;
- }
- if (r)
- {
- fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
- relocs[i].base.bo, soffset, eoffset);
- return r;
+ &soffset, &eoffset);
+ if (r == -EAGAIN) {
+ goto restart;
}
- asicoffset = soffset;
- if (asicoffset >= eoffset)
- {
- /* radeon_bo_debug(relocs[i].base.bo, 12); */
- fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
- relocs[i].base.bo, soffset, eoffset);
- fprintf(stderr, "above end: %p 0x%08X 0x%08X\n",
- relocs[i].base.bo,
- cs->packets[relocs[i].indices[j]],
- eoffset);
- exit(0);
- return -EINVAL;
+ if (r) {
+ fprintf(stderr, "invalid bo(%p) [0x%08X, 0x%08X]\n",
+ relocs[i].base.bo, soffset, eoffset);
+ return r;
}
- /* apply offset operator */
- switch (relocs[i].offset_mod.shift)
- {
- case NO_SHIFT:
- asicoffset = asicoffset & relocs[i].offset_mod.mask;
- break;
- case LEFT_SHIFT:
- asicoffset = (asicoffset << relocs[i].offset_mod.shiftbits) & relocs[i].offset_mod.mask;
- break;
- case RIGHT_SHIFT:
- asicoffset = (asicoffset >> relocs[i].offset_mod.shiftbits) & relocs[i].offset_mod.mask;
- break;
- default:
- break;
- };
-
- /* pkt3 nop header in ib chunk */
- cs->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
-
- /* reloc index in ib chunk */
- cs->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
-
- /* asic offset in reloc chunk */ /* see alex drm r600_nomm_relocate */
- reloc_chunk[offset_dw] = asicoffset;
- reloc_chunk[offset_dw + 3] = 0;
-
- offset_dw += 4;
- }
+
+ for (j = 0; j < relocs[i].cindices; j++) {
+ /* pkt3 nop header in ib chunk */
+ cs->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
+ /* reloc index in ib chunk */
+ cs->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
+ }
+
+ /* asic offset in reloc chunk */ /* see alex drm r600_nomm_relocate */
+ reloc_chunk[offset_dw] = soffset;
+ reloc_chunk[offset_dw + 3] = 0;
+
+ offset_dw += 4;
}
*length_dw_reloc_chunk = offset_dw;
return 0;
}
+#if 0
static void dump_cmdbuf(struct radeon_cs *cs)
{
int i;
fprintf(stderr,"--end--\n");
}
+#endif
static int r600_cs_emit(struct radeon_cs *cs)
{
struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)cs->csm;
struct drm_radeon_cs cs_cmd;
struct drm_radeon_cs_chunk cs_chunk[2];
- drm_radeon_cmd_buffer_t cmd;
- /* drm_r300_cmd_header_t age; */
uint32_t length_dw_reloc_chunk;
- uint64_t ull;
uint64_t chunk_ptrs[2];
- uint32_t reloc_chunk[128];
+ uint32_t *reloc_chunk;
int r;
int retry = 0;
/* TODO : put chip level things here if need. */
/* csm->ctx->vtbl.emit_cs_header(cs, csm->ctx); */
- BATCH_LOCALS(csm->ctx);
- drm_radeon_getparam_t gp;
- uint32_t current_scratchx_age;
-
- gp.param = RADEON_PARAM_LAST_CLEAR;
- gp.value = (int *)¤t_scratchx_age;
- r = drmCommandWriteRead(cs->csm->fd,
- DRM_RADEON_GETPARAM,
- &gp,
- sizeof(gp));
- if (r)
- {
- fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r);
- exit(1);
- }
-
- csm->pending_age = 0;
csm->pending_count = 1;
- current_scratchx_age++;
- csm->pending_age = current_scratchx_age;
-
- BEGIN_BATCH_NO_AUTOSTATE(3);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
- R600_OUT_BATCH((SCRATCH_REG2 - R600_SET_CONFIG_REG_OFFSET) >> 2);
- R600_OUT_BATCH(current_scratchx_age);
- END_BATCH();
- COMMIT_BATCH();
+ reloc_chunk = (uint32_t*)calloc(1, cs->crelocs * 4 * 4);
- //TODO ioctl to get back cs id assigned in drm
- //csm->pending_age = cs_id_back;
-
- r = r600_cs_process_relocs(cs, &(reloc_chunk[0]), &length_dw_reloc_chunk);
+ r = r600_cs_process_relocs(cs, reloc_chunk, &length_dw_reloc_chunk);
if (r) {
+ free(reloc_chunk);
return 0;
}
-
+
/* raw ib chunk */
cs_chunk[0].chunk_id = RADEON_CHUNK_ID_IB;
cs_chunk[0].length_dw = cs->cdw;
/* reloc chaunk */
cs_chunk[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
cs_chunk[1].length_dw = length_dw_reloc_chunk;
- cs_chunk[1].chunk_data = (unsigned long)&(reloc_chunk[0]);
+ cs_chunk[1].chunk_data = (unsigned long)reloc_chunk;
chunk_ptrs[0] = (uint64_t)(unsigned long)&(cs_chunk[0]);
chunk_ptrs[1] = (uint64_t)(unsigned long)&(cs_chunk[1]);
} while (r == -EAGAIN && retry < 1000);
if (r) {
+ free(reloc_chunk);
return r;
}
+ csm->pending_age = cs_cmd.cs_id;
+
r600_cs_set_age(cs);
cs->csm->read_used = 0;
cs->csm->vram_write_used = 0;
cs->csm->gart_write_used = 0;
+ free(reloc_chunk);
+
return 0;
}
{
}
-static int r600_cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
-{
- struct radeon_cs_manager *csm = cs->csm;
- int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
- uint32_t read_domains, write_domain;
- int i;
- struct radeon_bo *bo;
-
- /* check the totals for this operation */
-
- if (num_bo == 0)
- return 0;
-
- /* prepare */
- for (i = 0; i < num_bo; i++)
- {
- bo = bos[i].bo;
-
- bos[i].new_accounted = 0;
- read_domains = bos[i].read_domains;
- write_domain = bos[i].write_domain;
-
- /* pinned bos don't count */
- if (radeon_legacy_bo_is_static(bo))
- continue;
-
- /* already accounted this bo */
- if (write_domain && (write_domain == bo->space_accounted))
- continue;
-
- if (read_domains && ((read_domains << 16) == bo->space_accounted))
- continue;
-
- if (bo->space_accounted == 0)
- {
- if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- this_op_vram_write += bo->size;
- else if (write_domain == RADEON_GEM_DOMAIN_GTT)
- this_op_gart_write += bo->size;
- else
- this_op_read += bo->size;
- bos[i].new_accounted = (read_domains << 16) | write_domain;
- }
- else
- {
- uint16_t old_read, old_write;
-
- old_read = bo->space_accounted >> 16;
- old_write = bo->space_accounted & 0xffff;
-
- if (write_domain && (old_read & write_domain))
- {
- bos[i].new_accounted = write_domain;
- /* moving from read to a write domain */
- if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- {
- this_op_read -= bo->size;
- this_op_vram_write += bo->size;
- }
- else if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- {
- this_op_read -= bo->size;
- this_op_gart_write += bo->size;
- }
- }
- else if (read_domains & old_write)
- {
- bos[i].new_accounted = bo->space_accounted & 0xffff;
- }
- else
- {
- /* rewrite the domains */
- if (write_domain != old_write)
- fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
- if (read_domains != old_read)
- fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
- return RADEON_CS_SPACE_FLUSH;
- }
- }
- }
-
- if (this_op_read < 0)
- this_op_read = 0;
-
- /* check sizes - operation first */
- if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
- (this_op_vram_write > csm->vram_limit)) {
- return RADEON_CS_SPACE_OP_TO_BIG;
- }
-
- if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
- ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
- return RADEON_CS_SPACE_FLUSH;
- }
-
- csm->gart_write_used += this_op_gart_write;
- csm->vram_write_used += this_op_vram_write;
- csm->read_used += this_op_read;
- /* commit */
- for (i = 0; i < num_bo; i++) {
- bo = bos[i].bo;
- bo->space_accounted = bos[i].new_accounted;
- }
-
- return RADEON_CS_SPACE_OK;
-}
-
static struct radeon_cs_funcs r600_cs_funcs = {
r600_cs_create,
r600_cs_write_reloc,
r600_cs_destroy,
r600_cs_erase,
r600_cs_need_flush,
- r600_cs_print,
- r600_cs_check_space
+ r600_cs_print
};
struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)
void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
{
- radeonContextPtr rmesa = &r600->radeon;
-
- GLuint size;
+ radeonContextPtr rmesa = &r600->radeon;
+ GLuint size;
+
+ r600InitAtoms(r600);
+
/* Initialize command buffer */
size = 256 * driQueryOptioni(&rmesa->optionCache,
"command_buffer_size");
rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
assert(rmesa->cmdbuf.cs != NULL);
rmesa->cmdbuf.size = size;
-
+
+ radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
+ (void (*)(void *))rmesa->glCtx->Driver.Flush, rmesa->glCtx);
+
if (!rmesa->radeonScreen->kernel_mm) {
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);