r300-gallium, radeon-winsys: Space accounting.

It is no longer optional in current libdrm, so it was time to actually
start counting our BOs.
This commit is contained in:
Corbin Simpson 2009-05-01 05:54:53 -07:00
parent d7f4ac9f34
commit c11ad489e7
7 changed files with 126 additions and 9 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;