summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-01-31 01:59:57 +1000
committerDave Airlie <airlied@redhat.com>2009-01-31 01:59:57 +1000
commite45213d89bf26c68c9f4c9074eaec9ab3311de7d (patch)
treef4ca6a1fdec732dc2d5faba6d700ea54b14ff995 /src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
parent08bb7eedfbba839676ab63fb20dd22e4f27722cb (diff)
r200/r300: add aperture space checks
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.c')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c104
1 files changed, 102 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index 8997187d62b..171818db37c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -315,7 +315,7 @@ static int cs_emit(struct radeon_cs *cs)
cmd.boxes = (drm_clip_rect_t *) csm->ctx->pClipRects;
}
- dump_cmdbuf(cs);
+ // dump_cmdbuf(cs);
r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
if (r) {
@@ -330,6 +330,10 @@ static int cs_emit(struct radeon_cs *cs)
}
}
cs_set_age(cs);
+
+ cs->csm->read_used = 0;
+ cs->csm->vram_write_used = 0;
+ cs->csm->gart_write_used = 0;
return 0;
}
@@ -374,6 +378,101 @@ static void cs_print(struct radeon_cs *cs, FILE *file)
{
}
+static int 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 radeon_cs_legacy_funcs = {
cs_create,
cs_write_dword,
@@ -384,7 +483,8 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
cs_destroy,
cs_erase,
cs_need_flush,
- cs_print
+ cs_print,
+ cs_check_space
};
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)