summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2009-05-01 05:54:53 -0700
committerCorbin Simpson <[email protected]>2009-05-01 05:54:53 -0700
commitc11ad489e7432f3ed2fcaf5b15b8fe3538ae6d30 (patch)
treee2a1bb1fec400d7419a12f0f2532585ae8d61e86
parentd7f4ac9f34a72efe53a1a140557f1822afbadf16 (diff)
r300-gallium, radeon-winsys: Space accounting.
It is no longer optional in current libdrm, so it was time to actually start counting our BOs.
-rw-r--r--src/gallium/drivers/r300/r300_emit.c10
-rw-r--r--src/gallium/drivers/r300/r300_surface.c7
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h16
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c12
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h18
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c4
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c68
7 files changed, 126 insertions, 9 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 74d63ffe417..01bac5f759c 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -424,13 +424,21 @@ void r300_emit_dirty_state(struct r300_context* r300)
int i;
int dirty_tex = 0;
- if (!(r300->dirty_state) && !(r300->dirty_hw)) {
+ if (!(r300->dirty_hw)) {
return;
}
r300_update_derived_state(r300);
/* XXX check size */
+ struct r300_texture* fb_tex =
+ (struct r300_texture*)r300->framebuffer_state.cbufs[0];
+ r300->winsys->add_buffer(r300->winsys, fb_tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ if (r300->winsys->validate(r300->winsys)) {
+ /* XXX */
+ r300->context.flush(&r300->context, 0, NULL);
+ }
if (r300->dirty_state & R300_NEW_BLEND) {
r300_emit_blend_state(r300, r300->blend_state);
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index 79bed032538..4dd5b8af99a 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -34,6 +34,13 @@ static void r300_surface_setup(struct pipe_context* pipe,
unsigned pixpitch = tex->stride / tex->tex.block.size;
CS_LOCALS(r300);
+ /* Make sure our target BO is okay. */
+ r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ }
+
r300_emit_blend_state(r300, &blend_clear_state);
r300_emit_blend_color_state(r300, &blend_color_clear_state);
r300_emit_dsa_state(r300, &dsa_clear_state);
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 393ba07012b..761aedebfcf 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -53,6 +53,22 @@ struct r300_winsys {
/* GB pipe count */
uint32_t gb_pipes;
+ /* GART size. */
+ uint32_t gart_size;
+
+ /* VRAM size. */
+ uint32_t vram_size;
+
+ /* Add a pipe_buffer to the list of buffer objects to validate. */
+ void (*add_buffer)(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd);
+
+ /* Revalidate all currently setup pipe_buffers.
+ * Returns TRUE if a flush is required. */
+ boolean (*validate)(struct r300_winsys* winsys);
+
/* Check to see if there's room for commands. */
boolean (*check_cs)(struct r300_winsys* winsys, int size);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 611ee68da63..6313eb219ec 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -68,8 +68,8 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
domain |= RADEON_GEM_DOMAIN_GTT;
}
- radeon_buffer->bo = radeon_bo_open(radeon_ws->bom, 0, size, alignment,
- domain, 0);
+ radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size,
+ alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
}
@@ -169,8 +169,14 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
return NULL;
}
+ radeon_ws->priv = CALLOC_STRUCT(radeon_winsys_priv);
+ if (radeon_ws->priv == NULL) {
+ FREE(radeon_ws);
+ return NULL;
+ }
+
bom = radeon_bo_manager_gem_ctor(fd);
- radeon_ws->bom = bom;
+ radeon_ws->priv->bom = bom;
radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index 163422f2969..73fa362acab 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -41,6 +41,7 @@
#include "util/u_memory.h"
#include "radeon_bo.h"
+#include "radeon_cs.h"
#include "radeon_drm.h"
@@ -49,13 +50,24 @@ struct radeon_pipe_buffer {
struct radeon_bo *bo;
};
+#define RADEON_MAX_BOS 24
+
+struct radeon_winsys_priv {
+ /* Radeon BO manager. */
+ struct radeon_bo_manager* bom;
+
+ /* Radeon BO space checker. */
+ struct radeon_cs_space_check sc[RADEON_MAX_BOS];
+ /* Current BO count. */
+ unsigned bo_count;
+};
+
struct radeon_winsys {
/* Parent class. */
struct pipe_winsys base;
- /* Radeon BO manager.
- * This corresponds to void* radeon_winsys in r300_winsys. */
- struct radeon_bo_manager* bom;
+ /* This corresponds to void* radeon_winsys in r300_winsys. */
+ struct radeon_winsys_priv* priv;
};
struct radeon_winsys* radeon_pipe_winsys(int fb);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 1f89d1b1d10..428d3f65a16 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -32,7 +32,7 @@
/* Create a pipe_screen. */
struct pipe_screen* radeon_create_screen(int drmFB,
- struct drm_create_screen_arg *arg )
+ struct drm_create_screen_arg *arg)
{
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
@@ -69,7 +69,7 @@ struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
unsigned handle)
{
struct radeon_bo_manager* bom =
- ((struct radeon_winsys*)screen->winsys)->bom;
+ ((struct radeon_winsys*)screen->winsys)->priv->bom;
struct radeon_pipe_buffer* radeon_buffer;
struct radeon_bo* bo = NULL;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 929e4842ccf..b1721074322 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -22,6 +22,54 @@
#include "radeon_r300.h"
+static void radeon_r300_add_buffer(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd)
+{
+ int i;
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+ struct radeon_cs_space_check* sc = priv->sc;
+ struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
+
+ /* Check to see if this BO is already in line for validation;
+ * find a slot for it otherwise. */
+ for (i = 0; i < RADEON_MAX_BOS; i++) {
+ if (sc[i].bo == bo) {
+ return;
+ } else if (sc[i].bo == NULL) {
+ sc[i].bo = bo;
+ sc[i].read_domains = rd;
+ sc[i].write_domain = wd;
+ priv->bo_count = i + 1;
+ return;
+ }
+ }
+
+ assert(FALSE && "Oh God too many BOs!");
+}
+
+static boolean radeon_r300_validate(struct r300_winsys* winsys)
+{
+ int retval;
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+ struct radeon_cs_space_check* sc = priv->sc;
+
+ retval = radeon_cs_space_check(winsys->cs, sc, priv->bo_count);
+
+ if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
+ /* XXX we need to failover here */
+ } else if (retval == RADEON_CS_SPACE_FLUSH) {
+ /* We must flush before more rendering can commence. */
+ return TRUE;
+ }
+
+ /* Things are fine, we can proceed as normal. */
+ return FALSE;
+}
+
static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
{
/* XXX check size here, lazy ass! */
@@ -77,6 +125,7 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
+ struct drm_radeon_gem_info info;
drm_radeon_getparam_t gp;
int target;
int retval;
@@ -102,6 +151,18 @@ static void do_ioctls(struct r300_winsys* winsys, int fd)
exit(1);
}
winsys->pci_id = target;
+
+ /* Finally, retrieve MM info */
+ retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
+ &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
+ __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->gart_size = info.gart_size;
+ /* XXX */
+ winsys->vram_size = info.vram_visible;
}
struct r300_winsys*
@@ -119,6 +180,13 @@ radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys)
csm = radeon_cs_manager_gem_ctor(fd);
winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4);
+ radeon_cs_set_limit(winsys->cs,
+ RADEON_GEM_DOMAIN_GTT, winsys->gart_size);
+ radeon_cs_set_limit(winsys->cs,
+ RADEON_GEM_DOMAIN_VRAM, winsys->vram_size);
+
+ winsys->add_buffer = radeon_r300_add_buffer;
+ winsys->validate = radeon_r300_validate;
winsys->check_cs = radeon_r300_check_cs;
winsys->begin_cs = radeon_r300_begin_cs;