summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-07-14 01:59:57 +0200
committerMarek Olšák <[email protected]>2010-07-16 08:51:16 +0200
commitfe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4 (patch)
treead13a3ebec02d124511d6897402b8b3fdd5835e2 /src/gallium
parent5f9d7bb2425aee65e75667953a6cc304072f2b11 (diff)
r300g: rebuild winsys and command submission to support multiple contexts
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r300/r300_cb.h3
-rw-r--r--src/gallium/drivers/r300/r300_context.c11
-rw-r--r--src/gallium/drivers/r300/r300_context.h3
-rw-r--r--src/gallium/drivers/r300/r300_cs.h73
-rw-r--r--src/gallium/drivers/r300/r300_emit.c97
-rw-r--r--src/gallium/drivers/r300/r300_flush.c2
-rw-r--r--src/gallium/drivers/r300/r300_query.c6
-rw-r--r--src/gallium/drivers/r300/r300_render.c74
-rw-r--r--src/gallium/drivers/r300/r300_screen.c6
-rw-r--r--src/gallium/drivers/r300/r300_screen.h9
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c31
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h19
-rw-r--r--src/gallium/drivers/r300/r300_state.c8
-rw-r--r--src/gallium/drivers/r300/r300_texture.c22
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c15
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h309
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h41
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c149
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c320
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h23
20 files changed, 664 insertions, 557 deletions
diff --git a/src/gallium/drivers/r300/r300_cb.h b/src/gallium/drivers/r300/r300_cb.h
index 61b28330b0b..9d3d4fc1b19 100644
--- a/src/gallium/drivers/r300/r300_cb.h
+++ b/src/gallium/drivers/r300/r300_cb.h
@@ -89,9 +89,6 @@
CB_DEBUG(cs_count = size;) \
} while (0)
-#define BEGIN_CS_AS_CB(r300, size) \
- BEGIN_CB(r300->rws->get_cs_pointer(r300->rws, size), size)
-
#define END_CB do { \
CB_DEBUG(if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 1beab7628a0..0f7deca2826 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -100,6 +100,8 @@ static void r300_destroy_context(struct pipe_context* context)
r300_release_referenced_objects(r300);
+ r300->rws->cs_destroy(r300->cs);
+
FREE(r300->aa_state.state);
FREE(r300->blend_color_state.state);
FREE(r300->clip_state.state);
@@ -354,6 +356,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.destroy = r300_destroy_context;
+ r300->cs = rws->cs_create(rws);
+
if (!r300screen->caps.has_tcl) {
/* Create a Draw. This is used for SW TCL. */
r300->draw = draw_create(&r300->context);
@@ -381,7 +385,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
/* Render functions must be initialized after blitter. */
r300_init_render_functions(r300);
- rws->set_flush_cb(r300->rws, r300_flush_cb, r300);
+ rws->cs_set_flush(r300->cs, r300_flush_cb, r300);
r300->upload_ib = u_upload_create(&r300->context,
32 * 1024, 16,
@@ -433,11 +437,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
return NULL;
}
-boolean r300_check_cs(struct r300_context *r300, unsigned size)
-{
- return size <= r300->rws->get_cs_free_dwords(r300->rws);
-}
-
void r300_finish(struct r300_context *r300)
{
struct pipe_framebuffer_state *fb;
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index df4299b7ea3..55cec881490 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -416,6 +416,8 @@ struct r300_context {
/* The interface to the windowing system, etc. */
struct r300_winsys_screen *rws;
+ /* The command stream. */
+ struct r300_winsys_cs *cs;
/* Screen. */
struct r300_screen *screen;
/* Draw module. Used mostly for SW TCL. */
@@ -570,7 +572,6 @@ static INLINE struct r300_fragment_shader *r300_fs(struct r300_context *r300)
struct pipe_context* r300_create_context(struct pipe_screen* screen,
void *priv);
-boolean r300_check_cs(struct r300_context *r300, unsigned size);
void r300_finish(struct r300_context *r300);
void r300_flush_cb(void *data);
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 1db7da642bd..3beb625d430 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -46,12 +46,12 @@
*/
#define CS_LOCALS(context) \
- struct r300_context* const cs_context_copy = (context); \
- struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \
- CS_DEBUG(int cs_count = 0; (void) cs_count;)
+ struct r300_winsys_cs *cs_copy = (context)->cs; \
+ struct r300_winsys_screen *cs_winsys = (context)->rws; \
+ int cs_count = 0; (void) cs_count; (void) cs_winsys;
#define BEGIN_CS(size) do { \
- assert(r300_check_cs(cs_context_copy, (size))); \
+ assert(size <= (cs_copy->ndw - cs_copy->cdw)); \
CS_DEBUG(cs_count = size;) \
} while (0)
@@ -66,49 +66,39 @@
#define END_CS
#endif
+
/**
* Writing pure DWORDs.
*/
#define OUT_CS(value) do { \
- cs_winsys->write_cs_dword(cs_winsys, (value)); \
+ cs_copy->ptr[cs_copy->cdw++] = (value); \
CS_DEBUG(cs_count--;) \
} while (0)
-#define OUT_CS_32F(value) do { \
- cs_winsys->write_cs_dword(cs_winsys, fui(value)); \
- CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_32F(value) \
+ OUT_CS(fui(value))
#define OUT_CS_REG(register, value) do { \
- assert(register); \
- cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0(register, 0)); \
- cs_winsys->write_cs_dword(cs_winsys, value); \
- CS_DEBUG(cs_count -= 2;) \
+ OUT_CS(CP_PACKET0(register, 0)); \
+ OUT_CS(value); \
} while (0)
/* Note: This expects count to be the number of registers,
* not the actual packet0 count! */
-#define OUT_CS_REG_SEQ(register, count) do { \
- assert(register); \
- cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1))); \
- CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_REG_SEQ(register, count) \
+ OUT_CS(CP_PACKET0((register), ((count) - 1)))
-#define OUT_CS_TABLE(values, count) do { \
- cs_winsys->write_cs_table(cs_winsys, values, count); \
- CS_DEBUG(cs_count -= count;) \
-} while (0)
+#define OUT_CS_ONE_REG(register, count) \
+ OUT_CS(CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR)
-#define OUT_CS_ONE_REG(register, count) do { \
- assert(register); \
- cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR); \
- CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_PKT3(op, count) \
+ OUT_CS(CP_PACKET3(op, count))
-#define OUT_CS_PKT3(op, count) do { \
- cs_winsys->write_cs_dword(cs_winsys, CP_PACKET3(op, count)); \
- CS_DEBUG(cs_count--;) \
+#define OUT_CS_TABLE(values, count) do { \
+ memcpy(cs_copy->ptr + cs_copy->cdw, values, count * 4); \
+ cs_copy->cdw += count; \
+ CS_DEBUG(cs_count -= count;) \
} while (0)
@@ -116,26 +106,26 @@
* Writing relocations.
*/
-#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
+#define OUT_CS_RELOC(bo, offset, rd, wd) do { \
assert(bo); \
- cs_winsys->write_cs_dword(cs_winsys, offset); \
- cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
- CS_DEBUG(cs_count -= 3;) \
+ OUT_CS(offset); \
+ cs_winsys->cs_write_reloc(cs_copy, bo, rd, wd); \
+ CS_DEBUG(cs_count -= 2;) \
} while (0)
-#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \
+#define OUT_CS_BUF_RELOC(bo, offset, rd, wd) do { \
assert(bo); \
- OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd, flags); \
+ OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd); \
} while (0)
-#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \
+#define OUT_CS_TEX_RELOC(tex, offset, rd, wd) do { \
assert(tex); \
- OUT_CS_RELOC(tex->buffer, offset, rd, wd, flags); \
+ OUT_CS_RELOC(tex->buffer, offset, rd, wd); \
} while (0)
-#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
+#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd) do { \
assert(bo); \
- cs_winsys->write_cs_reloc(cs_winsys, r300_buffer(bo)->buf, rd, wd, flags); \
+ cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->buf, rd, wd); \
CS_DEBUG(cs_count -= 2;) \
} while (0)
@@ -146,7 +136,8 @@
#define WRITE_CS_TABLE(values, count) do { \
CS_DEBUG(assert(cs_count == 0);) \
- cs_winsys->write_cs_table(cs_winsys, values, count); \
+ memcpy(cs_copy->ptr + cs_copy->cdw, values, count * 4); \
+ cs_copy->cdw += count; \
} while (0)
#endif /* R300_CS_H */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index daae6dd510c..10d9e675ac0 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -314,10 +314,10 @@ void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state)
if (aa->dest) {
OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1);
- OUT_CS_RELOC(aa->dest->buffer, aa->dest->offset, 0, aa->dest->domain, 0);
+ OUT_CS_RELOC(aa->dest->buffer, aa->dest->offset, 0, aa->dest->domain);
OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1);
- OUT_CS_RELOC(aa->dest->buffer, aa->dest->pitch, 0, aa->dest->domain, 0);
+ OUT_CS_RELOC(aa->dest->buffer, aa->dest->pitch, 0, aa->dest->domain);
}
OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, aa->aaresolve_ctl);
@@ -347,10 +347,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
surf = r300_surface(fb->cbufs[i]);
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
- OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
- OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
}
/* Set up the ZB part of the CBZB clear. */
@@ -360,10 +360,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format);
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(surf->buffer, surf->cbzb_midpoint_offset, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->cbzb_midpoint_offset, 0, surf->domain);
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain);
}
/* Set up a zbuffer. */
else if (fb->zsbuf) {
@@ -372,10 +372,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG(R300_ZB_FORMAT, surf->format);
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
+ OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
/* HiZ RAM. */
if (r300->screen->caps.has_hiz) {
@@ -512,13 +512,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_RELOC(buf, (query->num_results + 3) * 4,
- 0, query->domain, 0);
+ 0, query->domain);
case 3:
/* pipe 2 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_RELOC(buf, (query->num_results + 2) * 4,
- 0, query->domain, 0);
+ 0, query->domain);
case 2:
/* pipe 1 only */
/* As mentioned above, accomodate RV380 and older. */
@@ -526,13 +526,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
1 << (caps->high_second_pipe ? 3 : 1));
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_RELOC(buf, (query->num_results + 1) * 4,
- 0, query->domain, 0);
+ 0, query->domain);
case 1:
/* pipe 0 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_RELOC(buf, (query->num_results + 0) * 4,
- 0, query->domain, 0);
+ 0, query->domain);
break;
default:
fprintf(stderr, "r300: Implementation error: Chipset reports %d"
@@ -554,7 +554,7 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
BEGIN_CS(8);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, query->num_results * 4, 0, query->domain, 0);
+ OUT_CS_RELOC(buf, query->num_results * 4, 0, query->domain);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -568,10 +568,10 @@ static void rv530_emit_query_end_double_z(struct r300_context *r300,
BEGIN_CS(14);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 0) * 4, 0, query->domain, 0);
+ OUT_CS_RELOC(buf, (query->num_results + 0) * 4, 0, query->domain);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(buf, (query->num_results + 1) * 4, 0, query->domain, 0);
+ OUT_CS_RELOC(buf, (query->num_results + 1) * 4, 0, query->domain);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -731,7 +731,7 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
OUT_CS_TEX_RELOC(tex, texstate->format.tile_config, tex->domain,
- 0, 0);
+ 0);
}
}
END_CS;
@@ -774,7 +774,7 @@ void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)
for (i = 0; i < aos_count; i++) {
buf = r300_buffer(vbuf[velem[i].vertex_buffer_index].buffer);
- OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0, 0);
+ OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0);
}
END_CS;
}
@@ -799,7 +799,7 @@ void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed)
OUT_CS(r300->vertex_info.size |
(r300->vertex_info.size << 8));
OUT_CS(r300->vbo_offset);
- OUT_CS_BUF_RELOC(r300->vbo, 0, r300_buffer(r300->vbo)->domain, 0, 0);
+ OUT_CS_BUF_RELOC(r300->vbo, 0, r300_buffer(r300->vbo)->domain, 0);
END_CS;
}
@@ -985,28 +985,22 @@ void r300_emit_buffer_validate(struct r300_context *r300,
}
/* Clean out BOs. */
- r300->rws->reset_bos(r300->rws);
+ r300->rws->cs_reset_buffers(r300->cs);
validate:
/* Color buffers... */
for (i = 0; i < fb->nr_cbufs; i++) {
tex = r300_texture(fb->cbufs[i]->texture);
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- if (!r300_add_texture(r300->rws, tex, 0,
- r300_surface(fb->cbufs[i])->domain)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
+ r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+ r300_surface(fb->cbufs[i])->domain);
}
/* ...depth buffer... */
if (fb->zsbuf) {
tex = r300_texture(fb->zsbuf->texture);
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- if (!r300_add_texture(r300->rws, tex, 0,
- r300_surface(fb->zsbuf)->domain)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
+ r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+ r300_surface(fb->zsbuf)->domain);
}
/* ...textures... */
for (i = 0; i < texstate->count; i++) {
@@ -1015,48 +1009,31 @@ validate:
}
tex = r300_texture(texstate->sampler_views[i]->base.texture);
- if (!r300_add_texture(r300->rws, tex, tex->domain, 0)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
+ r300->rws->cs_add_buffer(r300->cs, tex->buffer, tex->domain, 0);
}
/* ...occlusion query buffer... */
- if (r300->query_current) {
- if (!r300->rws->add_buffer(r300->rws, r300->query_current->buffer,
- 0, r300->query_current->domain)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
- }
+ if (r300->query_current)
+ r300->rws->cs_add_buffer(r300->cs, r300->query_current->buffer,
+ 0, r300->query_current->domain);
/* ...vertex buffer for SWTCL path... */
- if (r300->vbo) {
- if (!r300_add_buffer(r300->rws, r300->vbo,
- r300_buffer(r300->vbo)->domain, 0)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
- }
+ if (r300->vbo)
+ r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->buf,
+ r300_buffer(r300->vbo)->domain, 0);
/* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers) {
for (i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
- if (!r300_add_buffer(r300->rws, pbuf,
- r300_buffer(pbuf)->domain, 0)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
+ r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->buf,
+ r300_buffer(pbuf)->domain, 0);
}
}
/* ...and index buffer for HWTCL path. */
- if (index_buffer) {
- if (!r300_add_buffer(r300->rws, index_buffer,
- r300_buffer(index_buffer)->domain, 0)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
- }
- }
- if (!r300->rws->validate(r300->rws)) {
+ if (index_buffer)
+ r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->buf,
+ r300_buffer(index_buffer)->domain, 0);
+
+ if (!r300->rws->cs_validate(r300->cs)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
/* Well, hell. */
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 6f31ba159ac..9e5bfebe245 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -52,7 +52,7 @@ static void r300_flush(struct pipe_context* pipe,
r300_emit_query_end(r300);
r300->flush_counter++;
- r300->rws->flush_cs(r300->rws);
+ r300->rws->cs_flush(r300->cs);
r300->dirty_hw = 0;
/* New kitchen sink, baby. */
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 10086ee9256..5b0121ce9e1 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -57,7 +57,9 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
insert_at_tail(&r300->query_list, q);
/* Open up the occlusion query buffer. */
- q->buffer = r300->rws->buffer_create(r300->rws, 4096, 0, q->domain, q->buffer_size);
+ q->buffer = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
+ PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM,
+ q->domain);
return (struct pipe_query*)q;
}
@@ -134,7 +136,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
flags = PIPE_TRANSFER_READ | (!wait ? PIPE_TRANSFER_DONTBLOCK : 0);
- map = r300->rws->buffer_map(r300->rws, q->buffer, flags);
+ map = r300->rws->buffer_map(r300->rws, q->buffer, r300->cs, flags);
if (!map)
return FALSE;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 970cb688378..d30de1a4217 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -229,7 +229,7 @@ static void r300_prepare_for_rendering(struct r300_context *r300,
cs_dwords += end_dwords;
/* Reserve requested CS space. */
- if (!r300_check_cs(r300, cs_dwords)) {
+ if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) {
r300->context.flush(&r300->context, 0, NULL);
flushed = TRUE;
}
@@ -331,7 +331,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
uint32_t* mapelem[PIPE_MAX_ATTRIBS];
struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {0};
- CB_LOCALS;
+ CS_LOCALS(r300);
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
@@ -356,24 +356,24 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL);
- BEGIN_CS_AS_CB(r300, dwords);
- OUT_CB_REG(R300_GA_COLOR_CONTROL,
+ BEGIN_CS(dwords);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CB_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CB_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
- OUT_CB(count - 1);
- OUT_CB(0);
- OUT_CB_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
- OUT_CB(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
+ OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode));
/* Emit vertices. */
for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) {
- OUT_CB_TABLE(&mapelem[i][stride[i] * v], size[i]);
+ OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
}
}
- END_CB;
+ END_CS;
/* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) {
@@ -474,7 +474,7 @@ static void r300_emit_draw_elements(struct r300_context *r300,
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
OUT_CS(offset_dwords << 2);
OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
- r300_buffer(indexBuffer)->domain, 0, 0);
+ r300_buffer(indexBuffer)->domain, 0);
END_CS;
}
@@ -929,7 +929,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
NULL, 256, 0, 0, &end_cs_dwords);
while (count) {
- free_dwords = r300->rws->get_cs_free_dwords(r300->rws);
+ free_dwords = r300->cs->ndw - r300->cs->cdw;
short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
@@ -1039,7 +1039,7 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned dwords = 13 + vertex_size +
(type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
const float zeros[4] = {0, 0, 0, 0};
- CB_LOCALS;
+ CS_LOCALS(r300);
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
r300->sprite_coord_enable = 1;
@@ -1054,45 +1054,45 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
- BEGIN_CS_AS_CB(r300, dwords);
+ BEGIN_CS(dwords);
/* Set up GA. */
- OUT_CB_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
+ OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
/* Set up the GA to generate texcoords. */
- OUT_CB_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
+ OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
(R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
- OUT_CB_REG_SEQ(R300_GA_POINT_S0, 4);
- OUT_CB_32F(attrib[0]);
- OUT_CB_32F(attrib[3]);
- OUT_CB_32F(attrib[2]);
- OUT_CB_32F(attrib[1]);
+ OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
+ OUT_CS_32F(attrib[0]);
+ OUT_CS_32F(attrib[3]);
+ OUT_CS_32F(attrib[2]);
+ OUT_CS_32F(attrib[1]);
}
/* Set up VAP controls. */
- OUT_CB_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
- OUT_CB_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
- OUT_CB_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CB_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
- OUT_CB(1);
- OUT_CB(0);
+ OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
+ OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
+ OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(1);
+ OUT_CS(0);
/* Draw. */
- OUT_CB_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
- OUT_CB(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
R300_VAP_VF_CNTL__PRIM_POINTS);
- OUT_CB_32F(x1 + width * 0.5f);
- OUT_CB_32F(y1 + height * 0.5f);
- OUT_CB_32F(depth);
- OUT_CB_32F(1);
+ OUT_CS_32F(x1 + width * 0.5f);
+ OUT_CS_32F(y1 + height * 0.5f);
+ OUT_CS_32F(depth);
+ OUT_CS_32F(1);
if (vertex_size == 8) {
if (!attrib)
attrib = zeros;
- OUT_CB_TABLE(attrib, 4);
+ OUT_CS_TABLE(attrib, 4);
}
- END_CB;
+ END_CS;
/* Restore the state. */
r300->clip_state.dirty = TRUE;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index a3b08555cde..f28b05506e3 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -420,9 +420,3 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
return &r300screen->screen;
}
-
-struct r300_winsys_screen *
-r300_winsys_screen(struct pipe_screen *screen)
-{
- return r300_screen(screen)->rws;
-}
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index c6b4b57c3bd..58270230e1d 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -30,6 +30,8 @@
#include <stdio.h>
+struct r300_winsys_screen;
+
struct r300_screen {
/* Parent class */
struct pipe_screen screen;
@@ -44,11 +46,16 @@ struct r300_screen {
};
-/* Convenience cast wrapper. */
+/* Convenience cast wrappers. */
static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
return (struct r300_screen*)screen;
}
+static INLINE struct r300_winsys_screen *
+r300_winsys_screen(struct pipe_screen *screen) {
+ return r300_screen(screen)->rws;
+}
+
/* Debug functionality. */
/**
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index f49f36b6264..15d3f25c776 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -43,7 +43,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
if (r300_buffer_is_user_buffer(buf))
return PIPE_UNREFERENCED;
- if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf, domain))
+ if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
@@ -144,6 +144,7 @@ static void *
r300_buffer_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
+ struct r300_context *r300 = r300_context(pipe);
struct r300_screen *r300screen = r300_screen(pipe->screen);
struct r300_winsys_screen *rws = r300screen->rws;
struct r300_buffer *rbuf = r300_buffer(transfer->resource);
@@ -170,23 +171,19 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
rws->buffer_reference(rws, &rbuf->buf, NULL);
rbuf->num_ranges = 0;
- rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, 16,
- rbuf->b.b.bind,
- rbuf->domain,
- rbuf->b.b.width0);
+ rbuf->buf =
+ r300screen->rws->buffer_create(r300screen->rws,
+ rbuf->b.b.width0, 16,
+ rbuf->b.b.bind,
+ rbuf->b.b.usage,
+ rbuf->domain);
break;
}
}
}
just_map:
- /* XXX buffer_map might flush.
- * We cannot flush here because there is a buffer manager between
- * the context and winsys, and it does some magic to make the driver
- * fast. This is a workaround for the case of multiple contexts. */
- rws->set_flush_cb(rws, r300_flush_cb, pipe);
-
- map = rws->buffer_map(rws, rbuf->buf, transfer->usage);
+ map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
if (map == NULL)
return NULL;
@@ -273,11 +270,11 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
rbuf->b.b.screen = screen;
rbuf->domain = R300_DOMAIN_GTT;
- rbuf->buf = r300screen->rws->buffer_create(r300screen->rws,
- alignment,
- rbuf->b.b.bind,
- rbuf->domain,
- rbuf->b.b.width0);
+ rbuf->buf =
+ r300screen->rws->buffer_create(r300screen->rws,
+ rbuf->b.b.width0, alignment,
+ rbuf->b.b.bind, rbuf->b.b.usage,
+ rbuf->domain);
if (!rbuf->buf)
goto error2;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index ff355858704..4f7c0ec87e5 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -97,23 +97,4 @@ static INLINE boolean r300_buffer_is_user_buffer(struct pipe_resource *buffer)
return r300_buffer(buffer)->user_buffer ? true : false;
}
-static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws,
- struct pipe_resource *buffer,
- int rd, int wr)
-{
- struct r300_buffer *buf = r300_buffer(buffer);
-
- if (!buf->buf)
- return true;
-
- return rws->add_buffer(rws, buf->buf, rd, wr);
-}
-
-static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws,
- struct r300_texture *tex,
- int rd, int wr)
-{
- return rws->add_buffer(rws, tex->buffer, rd, wr);
-}
-
#endif
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index f4c6a262d4a..8214bcc2464 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -617,13 +617,13 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300,
if (tex->mip_macrotile[tex->surface_level] != tex->mip_macrotile[level]) {
/* Tiling determines how DRM treats the buffer data.
* We must flush CS when changing it if the buffer is referenced. */
- if (r300->rws->is_buffer_referenced(r300->rws, tex->buffer, R300_REF_CS))
+ if (r300->rws->cs_is_buffer_referenced(r300->cs,
+ tex->buffer, R300_REF_CS))
r300->context.flush(&r300->context, 0, NULL);
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
- tex->microtile,
- tex->mip_macrotile[level]);
+ tex->microtile, tex->mip_macrotile[level],
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format));
tex->surface_level = level;
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index e8b1d670070..5750bc4329f 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -908,7 +908,8 @@ static unsigned r300_texture_is_referenced(struct pipe_context *context,
struct r300_context *r300 = r300_context(context);
struct r300_texture *rtex = (struct r300_texture *)texture;
- if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer, R300_REF_CS))
+ if (r300->rws->cs_is_buffer_referenced(r300->cs,
+ rtex->buffer, R300_REF_CS))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
@@ -935,8 +936,9 @@ static boolean r300_texture_get_handle(struct pipe_screen* screen,
return FALSE;
}
- return rws->buffer_get_handle(rws, tex->buffer, whandle,
- r300_texture_get_stride(r300_screen(screen), tex, 0));
+ return rws->buffer_get_handle(rws, tex->buffer,
+ r300_texture_get_stride(r300_screen(screen), tex, 0),
+ whandle);
}
struct u_resource_vtbl r300_texture_vtbl =
@@ -1005,8 +1007,8 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
R300_DOMAIN_GTT :
R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
- tex->buffer = rws->buffer_create(rws, 2048, base->bind, tex->domain,
- tex->size);
+ tex->buffer = rws->buffer_create(rws, tex->size, 2048, base->bind,
+ base->usage, tex->domain);
if (!tex->buffer) {
FREE(tex);
@@ -1014,9 +1016,8 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
}
rws->buffer_set_tiling(rws, tex->buffer,
- tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
- tex->microtile,
- tex->macrotile);
+ tex->microtile, tex->macrotile,
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format));
return (struct pipe_resource*)tex;
}
@@ -1176,9 +1177,8 @@ r300_texture_from_handle(struct pipe_screen* screen,
if (override_zb_flags) {
rws->buffer_set_tiling(rws, tex->buffer,
- tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
- tex->microtile,
- tex->macrotile);
+ tex->microtile, tex->macrotile,
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format));
}
return (struct pipe_resource*)tex;
}
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index 2eb93e19111..3cc4c8c9582 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -91,19 +91,22 @@ r300_texture_get_transfer(struct pipe_context *ctx,
unsigned usage,
const struct pipe_box *box)
{
+ struct r300_context *r300 = r300_context(ctx);
struct r300_texture *tex = r300_texture(texture);
struct r300_screen *r300screen = r300_screen(ctx->screen);
struct r300_transfer *trans;
struct pipe_resource base;
boolean referenced_cs, referenced_hw, blittable;
- referenced_cs = r300screen->rws->is_buffer_referenced(
- r300screen->rws, tex->buffer, R300_REF_CS);
+ referenced_cs =
+ r300->rws->cs_is_buffer_referenced(r300->cs,
+ tex->buffer, R300_REF_CS);
if (referenced_cs) {
referenced_hw = TRUE;
} else {
- referenced_hw = r300screen->rws->is_buffer_referenced(
- r300screen->rws, tex->buffer, R300_REF_HW);
+ referenced_hw =
+ r300->rws->cs_is_buffer_referenced(r300->cs,
+ tex->buffer, R300_REF_HW);
}
blittable = ctx->screen->is_format_supported(
@@ -231,6 +234,7 @@ void r300_texture_transfer_destroy(struct pipe_context *ctx,
void* r300_texture_transfer_map(struct pipe_context *ctx,
struct pipe_transfer *transfer)
{
+ struct r300_context *r300 = r300_context(ctx);
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
struct r300_transfer *r300transfer = r300_transfer(transfer);
struct r300_texture *tex = r300_texture(transfer->resource);
@@ -242,10 +246,11 @@ void* r300_texture_transfer_map(struct pipe_context *ctx,
* (no offset needed). */
return rws->buffer_map(rws,
r300transfer->detiled_texture->buffer,
+ r300->cs,
transfer->usage);
} else {
/* Tiling is disabled. */
- map = rws->buffer_map(rws, tex->buffer,
+ map = rws->buffer_map(rws, tex->buffer, r300->cs,
transfer->usage);
if (!map) {
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 7687eac53eb..7e115c2d624 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <[email protected]>
+ * Copyright 2010 Marek Olšák <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -23,17 +24,25 @@
#ifndef R300_WINSYS_H
#define R300_WINSYS_H
-/* The public interface header for the r300 pipe driver.
- * Any winsys hosting this pipe needs to implement r300_winsys and then
- * call r300_create_screen to start things. */
+/* The public winsys interface header for the r300 pipe driver.
+ * Any winsys hosting this pipe needs to implement r300_winsys_screen and then
+ * call r300_screen_create to start things. */
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "r300_defines.h"
+struct r300_winsys_screen;
+
struct r300_winsys_buffer;
+struct r300_winsys_cs {
+ uint32_t *ptr; /* Pointer to the beginning of the CS. */
+ unsigned cdw; /* Number of used dwords. */
+ unsigned ndw; /* Size of the CS in dwords. */
+};
+
enum r300_value_id {
R300_VID_PCI_ID,
R300_VID_GB_PIPES,
@@ -48,120 +57,250 @@ enum r300_reference_domain { /* bitfield */
};
struct r300_winsys_screen {
+ /**
+ * Destroy this winsys.
+ *
+ * \param ws The winsys this function is called from.
+ */
void (*destroy)(struct r300_winsys_screen *ws);
-
+
/**
+ * Query a system value from a winsys.
+ *
+ * \param ws The winsys this function is called from.
+ * \param vid One of the R300_VID_* enums.
+ */
+ uint32_t (*get_value)(struct r300_winsys_screen *ws,
+ enum r300_value_id vid);
+
+ /**************************************************************************
* Buffer management. Buffer attributes are mostly fixed over its lifetime.
*
* Remember that gallium gets to choose the interface it needs, and the
* window systems must then implement that interface (rather than the
* other way around...).
+ *************************************************************************/
+
+ /**
+ * Create a buffer object.
*
- * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
- * usage argument is only an optimization hint, not a guarantee, therefore
- * proper behavior must be observed in all circumstances.
- *
- * alignment indicates the client's alignment requirements, eg for
- * SSE instructions.
+ * \param ws The winsys this function is called from.
+ * \param size The size to allocate.
+ * \param alignment An alignment of the buffer in memory.
+ * \param bind A bitmask of the PIPE_BIND_* flags.
+ * \param usage A bitmask of the PIPE_USAGE_* flags.
+ * \param domain A bitmask of the R300_DOMAIN_* flags.
+ * \return The created buffer object.
*/
struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
- unsigned alignment,
- unsigned usage,
- enum r300_buffer_domain domain,
- unsigned size);
+ unsigned size,
+ unsigned alignment,
+ unsigned bind,
+ unsigned usage,
+ enum r300_buffer_domain domain);
/**
- * Map the entire data store of a buffer object into the client's address.
- * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags.
+ * Reference a buffer object (assign with reference counting).
+ *
+ * \param ws The winsys this function is called from.
+ * \param pdst A destination pointer to set the source buffer to.
+ * \param src A source buffer object.
*/
- void *(*buffer_map)( struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
- unsigned usage);
+ void (*buffer_reference)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer **pdst,
+ struct r300_winsys_buffer *src);
- void (*buffer_unmap)( struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf );
+ /**
+ * Map the entire data store of a buffer object into the client's address
+ * space.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to map.
+ * \param cs A command stream to flush if the buffer is referenced by it.
+ * \param usage A bitmask of the PIPE_TRANSFER_* flags.
+ * \return The pointer at the beginning of the buffer.
+ */
+ void *(*buffer_map)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ struct r300_winsys_cs *cs,
+ enum pipe_transfer_usage usage);
- void (*buffer_destroy)( struct r300_winsys_buffer *buf );
+ /**
+ * Unmap a buffer object from the client's address space.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to unmap.
+ */
+ void (*buffer_unmap)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf);
+ /**
+ * Wait for a buffer object until it is not used by a GPU. This is
+ * equivalent to a fence placed after the last command using the buffer,
+ * and synchronizing to the fence.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to wait for.
+ */
+ void (*buffer_wait)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf);
- void (*buffer_reference)(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer **pdst,
- struct r300_winsys_buffer *src);
+ /**
+ * Return tiling flags describing a memory layout of a buffer object.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to get the flags from.
+ * \param macrotile A pointer to the return value of the microtile flag.
+ * \param microtile A pointer to the return value of the macrotile flag.
+ *
+ * \note microtile and macrotile are not bitmasks!
+ */
+ void (*buffer_get_tiling)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_tiling *microtile,
+ enum r300_buffer_tiling *macrotile);
- void (*buffer_wait)(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf);
+ /**
+ * Set tiling flags describing a memory layout of a buffer object.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to set the flags for.
+ * \param macrotile A macrotile flag.
+ * \param microtile A microtile flag.
+ * \param stride A stride of the buffer in bytes, for texturing.
+ *
+ * \note microtile and macrotile are not bitmasks!
+ */
+ void (*buffer_set_tiling)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_tiling microtile,
+ enum r300_buffer_tiling macrotile,
+ unsigned stride);
- /* Add a pipe_resource to the list of buffer objects to validate. */
- boolean (*add_buffer)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buf,
- enum r300_buffer_domain rd,
- enum r300_buffer_domain wd);
+ /**
+ * Get a winsys buffer from a winsys handle. The internal structure
+ * of the handle is platform-specific and only a winsys should access it.
+ *
+ * \param ws The winsys this function is called from.
+ * \param whandle A winsys handle pointer as was received from a state
+ * tracker.
+ * \param stride A pointer to the stride return variable.
+ * The stride is in bytes.
+ */
+ struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *ws,
+ struct winsys_handle *whandle,
+ unsigned *stride);
+ /**
+ * Get a winsys handle from a winsys buffer. The internal structure
+ * of the handle is platform-specific and only a winsys should access it.
+ *
+ * \param ws The winsys this function is called from.
+ * \param buf A winsys buffer object to get the handle from.
+ * \param whandle A winsys handle pointer.
+ * \param stride A stride of the buffer in bytes, for texturing.
+ * \return TRUE on success.
+ */
+ boolean (*buffer_get_handle)(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ unsigned stride,
+ struct winsys_handle *whandle);
- /* Revalidate all currently setup pipe_buffers.
- * Returns TRUE if a flush is required. */
- boolean (*validate)(struct r300_winsys_screen* winsys);
+ /**************************************************************************
+ * Command submission.
+ *
+ * Each pipe context should create its own command stream and submit
+ * commands independently of other contexts.
+ *************************************************************************/
- /* Return the number of free dwords in CS. */
- unsigned (*get_cs_free_dwords)(struct r300_winsys_screen *winsys);
+ /**
+ * Create a command stream.
+ *
+ * \param ws The winsys this function is called from.
+ */
+ struct r300_winsys_cs *(*cs_create)(struct r300_winsys_screen *ws);
- /* Return the pointer to the first free dword in CS and assume a pipe
- * driver wants to fill "count" dwords. */
- uint32_t *(*get_cs_pointer)(struct r300_winsys_screen *winsys,
- unsigned count);
+ /**
+ * Destroy a command stream.
+ *
+ * \param cs A command stream to destroy.
+ */
+ void (*cs_destroy)(struct r300_winsys_cs *cs);
- /* Write a dword to the command buffer. */
- void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword);
+ /**
+ * Add a buffer object to the list of buffers to validate.
+ *
+ * \param cs A command stream to add buffer for validation against.
+ * \param buf A winsys buffer to validate.
+ * \param rd A read domain containing a bitmask
+ * of the R300_DOMAIN_* flags.
+ * \param wd A write domain containing a bitmask
+ * of the R300_DOMAIN_* flags.
+ */
+ void (*cs_add_buffer)(struct r300_winsys_cs *cs,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd);
- /* Write a table of dwords to the command buffer. */
- void (*write_cs_table)(struct r300_winsys_screen* winsys,
- const void *dwords, unsigned count);
+ /**
+ * Revalidate all currently set up winsys buffers.
+ * Returns TRUE if a flush is required.
+ *
+ * \param cs A command stream to validate.
+ */
+ boolean (*cs_validate)(struct r300_winsys_cs *cs);
- /* Write a relocated dword to the command buffer. */
- void (*write_cs_reloc)(struct r300_winsys_screen *winsys,
+ /**
+ * Write a relocated dword to a command buffer.
+ *
+ * \param cs A command stream the relocation is written to.
+ * \param buf A winsys buffer to write the relocation for.
+ * \param rd A read domain containing a bitmask of the R300_DOMAIN_* flags.
+ * \param wd A write domain containing a bitmask of the R300_DOMAIN_* flags.
+ */
+ void (*cs_write_reloc)(struct r300_winsys_cs *cs,
struct r300_winsys_buffer *buf,
enum r300_buffer_domain rd,
- enum r300_buffer_domain wd,
- uint32_t flags);
+ enum r300_buffer_domain wd);
- /* Flush the CS. */
- void (*flush_cs)(struct r300_winsys_screen* winsys);
-
- /* winsys flush - callback from winsys when flush required */
- void (*set_flush_cb)(struct r300_winsys_screen *winsys,
- void (*flush_cb)(void *), void *data);
-
- void (*reset_bos)(struct r300_winsys_screen *winsys);
-
- void (*buffer_get_tiling)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buffer,
- enum r300_buffer_tiling *microtiled,
- enum r300_buffer_tiling *macrotiled);
-
- void (*buffer_set_tiling)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buffer,
- uint32_t pitch,
- enum r300_buffer_tiling microtiled,
- enum r300_buffer_tiling macrotiled);
-
- uint32_t (*get_value)(struct r300_winsys_screen *winsys,
- enum r300_value_id vid);
+ /**
+ * Flush a command stream.
+ *
+ * \param cs A command stream to flush.
+ */
+ void (*cs_flush)(struct r300_winsys_cs *cs);
- struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *winsys,
- struct winsys_handle *whandle,
- unsigned *stride);
+ /**
+ * Set a flush callback which is called from winsys when flush is
+ * required.
+ *
+ * \param cs A command stream to set the callback for.
+ * \param flush A flush callback function associated with the command stream.
+ * \param user A user pointer that will be passed to the flush callback.
+ */
+ void (*cs_set_flush)(struct r300_winsys_cs *cs,
+ void (*flush)(void *),
+ void *user);
- boolean (*buffer_get_handle)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buffer,
- struct winsys_handle *whandle,
- unsigned stride);
+ /**
+ * Reset the list of buffer objects to validate, usually called
+ * prior to adding buffer objects for validation.
+ *
+ * \param cs A command stream to reset buffers for.
+ */
+ void (*cs_reset_buffers)(struct r300_winsys_cs *cs);
- boolean (*is_buffer_referenced)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buffer,
- enum r300_reference_domain domain);
+ /**
+ * Return TRUE if a buffer is referenced by a command stream or by hardware
+ * (i.e. is busy), based on the domain parameter.
+ *
+ * \param cs A command stream.
+ * \param buf A winsys buffer.
+ * \param domain A bitmask of the R300_REF_* enums.
+ */
+ boolean (*cs_is_buffer_referenced)(struct r300_winsys_cs *cs,
+ struct r300_winsys_buffer *buf,
+ enum r300_reference_domain domain);
};
-struct r300_winsys_screen *
-r300_winsys_screen(struct pipe_screen *screen);
-
#endif /* R300_WINSYS_H */
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
index 73cb6a579b4..a8137d85e83 100644
--- a/src/gallium/winsys/radeon/drm/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -43,10 +43,9 @@
#include "radeon_winsys.h"
-#define RADEON_USAGE_DOMAIN_GTT (1 << 29)
-#define RADEON_USAGE_DOMAIN_VRAM (1 << 30)
-
-#define RADEON_MAX_BOS 24
+#define RADEON_PB_USAGE_VERTEX (1 << 28)
+#define RADEON_PB_USAGE_DOMAIN_GTT (1 << 29)
+#define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30)
static INLINE struct pb_buffer *
radeon_pb_buffer(struct r300_winsys_buffer *buffer)
@@ -63,24 +62,26 @@ radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
struct pb_manager *
radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
-boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
- enum r300_buffer_domain rd,
- enum r300_buffer_domain wd);
-
+void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *cs,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd);
-void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *cs,
+ struct r300_winsys_buffer *buf,
enum r300_buffer_domain rd,
- enum r300_buffer_domain wd,
- uint32_t flags);
+ enum r300_buffer_domain wd);
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle);
-void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
enum r300_buffer_tiling *microtiled,
enum r300_buffer_tiling *macrotiled);
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
enum r300_buffer_tiling microtiled,
enum r300_buffer_tiling macrotiled,
uint32_t pitch);
@@ -90,9 +91,19 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
struct winsys_handle *whandle);
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *cs,
+ struct r300_winsys_buffer *buf,
enum r300_reference_domain domain);
-void radeon_drm_bufmgr_wait(struct pb_buffer *_buf);
+void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf);
+
+void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ struct r300_winsys_cs *cs,
+ enum pipe_transfer_usage usage);
+
+void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf);
#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index c5f133e7b28..5ea5912089e 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -20,6 +20,9 @@ struct radeon_drm_buffer {
struct radeon_bo *bo;
+ /* The CS associated with the last buffer_map. */
+ struct radeon_libdrm_cs *cs;
+
boolean flinked;
uint32_t flink;
@@ -65,34 +68,53 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf)
FREE(buf);
}
+static unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage)
+{
+ unsigned res = 0;
+
+ if (usage & PIPE_TRANSFER_READ)
+ res |= PB_USAGE_CPU_READ;
+
+ if (usage & PIPE_TRANSFER_WRITE)
+ res |= PB_USAGE_CPU_WRITE;
+
+ if (usage & PIPE_TRANSFER_DONTBLOCK)
+ res |= PB_USAGE_DONTBLOCK;
+
+ if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
+ res |= PB_USAGE_UNSYNCHRONIZED;
+
+ return res;
+}
+
static void *
-radeon_drm_buffer_map(struct pb_buffer *_buf,
+radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
unsigned flags)
{
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = buf->cs;
int write = 0;
- if (flags & PIPE_TRANSFER_DONTBLOCK) {
- if ((_buf->base.usage & PIPE_BIND_VERTEX_BUFFER) ||
- (_buf->base.usage & PIPE_BIND_INDEX_BUFFER))
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+ if (flags & PB_USAGE_DONTBLOCK) {
+ if (_buf->base.usage & RADEON_PB_USAGE_VERTEX)
+ if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs))
return NULL;
}
if (buf->bo->ptr != NULL)
return buf->bo->ptr;
- if (flags & PIPE_TRANSFER_DONTBLOCK) {
+ if (flags & PB_USAGE_DONTBLOCK) {
uint32_t domain;
if (radeon_bo_is_busy(buf->bo, &domain))
return NULL;
}
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
- buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
+ cs->flush_cs(cs->flush_data);
}
- if (flags & PIPE_TRANSFER_WRITE) {
+ if (flags & PB_USAGE_CPU_WRITE) {
write = 1;
}
@@ -104,7 +126,7 @@ radeon_drm_buffer_map(struct pb_buffer *_buf,
}
static void
-radeon_drm_buffer_unmap(struct pb_buffer *_buf)
+radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf)
{
(void)_buf;
}
@@ -136,8 +158,8 @@ radeon_drm_buffer_fence(struct pb_buffer *buf,
const struct pb_vtbl radeon_drm_buffer_vtbl = {
radeon_drm_buffer_destroy,
- radeon_drm_buffer_map,
- radeon_drm_buffer_unmap,
+ radeon_drm_buffer_map_internal,
+ radeon_drm_buffer_unmap_internal,
radeon_drm_buffer_validate,
radeon_drm_buffer_fence,
radeon_drm_buffer_get_base_buffer,
@@ -166,7 +188,7 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
pipe_reference_init(&buf->base.base.reference, 1);
buf->base.base.alignment = 0;
- buf->base.base.usage = PIPE_BIND_SAMPLER_VIEW;
+ buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
buf->base.base.size = 0;
buf->base.vtbl = &radeon_drm_buffer_vtbl;
buf->mgr = mgr;
@@ -200,8 +222,8 @@ radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
make_empty_list(buf);
domain =
- (desc->usage & RADEON_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) |
- (desc->usage & RADEON_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
+ (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) |
+ (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
buf->bo = radeon_bo_open(rws->bom, 0, size,
desc->alignment, domain, 0);
@@ -249,7 +271,8 @@ radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
{
- struct radeon_drm_buffer *buf;
+ struct radeon_drm_buffer *buf = NULL;
+
if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
buf = radeon_drm_buffer(_buf);
} else {
@@ -257,11 +280,35 @@ static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
pb_size offset;
pb_get_base_buffer(_buf, &base_buf, &offset);
- buf = radeon_drm_buffer(base_buf);
+ if (base_buf->vtbl == &radeon_drm_buffer_vtbl)
+ buf = radeon_drm_buffer(base_buf);
}
+
return buf;
}
+void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ struct r300_winsys_cs *cs,
+ enum pipe_transfer_usage usage)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ struct radeon_drm_buffer *rbuf = get_drm_buffer(_buf);
+
+ if (rbuf)
+ rbuf->cs = radeon_libdrm_cs(cs);
+
+ return pb_map(_buf, get_pb_usage_from_transfer_flags(usage));
+}
+
+void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_unmap(_buf);
+}
+
boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
struct winsys_handle *whandle)
{
@@ -286,11 +333,12 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
return TRUE;
}
-void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf,
enum r300_buffer_tiling *microtiled,
enum r300_buffer_tiling *macrotiled)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
uint32_t flags = 0, pitch;
radeon_bo_get_tiling(buf->bo, &flags, &pitch);
@@ -304,12 +352,13 @@ void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
*macrotiled = R300_BUFFER_TILED;
}
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf,
enum r300_buffer_tiling microtiled,
enum r300_buffer_tiling macrotiled,
uint32_t pitch)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
uint32_t flags = 0;
if (microtiled == R300_BUFFER_TILED)
flags |= RADEON_BO_FLAGS_MICRO_TILE;
@@ -324,56 +373,60 @@ void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
radeon_bo_set_tiling(buf->bo, flags, pitch);
}
-static uint32_t gem_domain(enum r300_buffer_domain dom)
+static uint32_t get_gem_domain(enum r300_buffer_domain domain)
{
uint32_t res = 0;
- if (dom & R300_DOMAIN_GTT)
+ if (domain & R300_DOMAIN_GTT)
res |= RADEON_GEM_DOMAIN_GTT;
- if (dom & R300_DOMAIN_VRAM)
+ if (domain & R300_DOMAIN_VRAM)
res |= RADEON_GEM_DOMAIN_VRAM;
return res;
}
-boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
- enum r300_buffer_domain rd,
- enum r300_buffer_domain wd)
+void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
- uint32_t gem_rd = gem_domain(rd);
- uint32_t gem_wd = gem_domain(wd);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+ uint32_t gem_rd = get_gem_domain(rd);
+ uint32_t gem_wd = get_gem_domain(wd);
- radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
- gem_rd, gem_wd);
- return TRUE;
+ radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd);
}
-void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
enum r300_buffer_domain rd,
- enum r300_buffer_domain wd,
- uint32_t flags)
+ enum r300_buffer_domain wd)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
int retval;
- uint32_t gem_rd = gem_domain(rd);
- uint32_t gem_wd = gem_domain(wd);
+ uint32_t gem_rd = get_gem_domain(rd);
+ uint32_t gem_wd = get_gem_domain(wd);
- retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
- buf->bo, gem_rd, gem_wd, flags);
+ cs->cs->cdw = cs->base.cdw;
+ retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0);
+ cs->base.cdw = cs->cs->cdw;
if (retval) {
fprintf(stderr, "radeon: Relocation of %p (%d, %d, %d) failed!\n",
- buf, gem_rd, gem_wd, flags);
+ buf, gem_rd, gem_wd, 0);
}
}
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
enum r300_reference_domain domain)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
uint32_t tmp;
if (domain & R300_REF_CS) {
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
return TRUE;
}
}
@@ -387,7 +440,6 @@ boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
return FALSE;
}
-
void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
{
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
@@ -402,9 +454,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
make_empty_list(&mgr->buffer_map_list);
}
-void radeon_drm_bufmgr_wait(struct pb_buffer *_buf)
+void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
radeon_bo_wait(buf->bo);
}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index af35497fd7c..4e89c070831 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -27,37 +27,69 @@
#include "radeon_cs_gem.h"
#include "state_tracker/drm_driver.h"
+#include "util/u_memory.h"
+
+static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage,
+ enum r300_buffer_domain domain)
+{
+ unsigned res = 0;
+
+ if (bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT))
+ res |= PB_USAGE_GPU_WRITE;
+
+ if (bind & PIPE_BIND_SAMPLER_VIEW)
+ res |= PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE;
+
+ if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
+ res |= PB_USAGE_GPU_READ;
+
+ if (bind & PIPE_BIND_TRANSFER_WRITE)
+ res |= PB_USAGE_CPU_WRITE;
+
+ if (bind & PIPE_BIND_TRANSFER_READ)
+ res |= PB_USAGE_CPU_READ;
+
+ /* Is usage of any use for us? Probably not. */
+
+ /* Now add driver-specific usage flags. */
+ if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
+ res |= RADEON_PB_USAGE_VERTEX;
+
+ if (domain & R300_DOMAIN_GTT)
+ res |= RADEON_PB_USAGE_DOMAIN_GTT;
+
+ if (domain & R300_DOMAIN_VRAM)
+ res |= RADEON_PB_USAGE_DOMAIN_VRAM;
+
+ return res;
+}
+
static struct r300_winsys_buffer *
radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
- unsigned alignment,
- unsigned usage,
- enum r300_buffer_domain domain,
- unsigned size)
+ unsigned size,
+ unsigned alignment,
+ unsigned bind,
+ unsigned usage,
+ enum r300_buffer_domain domain)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
struct pb_desc desc;
struct pb_manager *provider;
struct pb_buffer *buffer;
- /* XXX this is hackish, but it's the only way to pass these flags
- * to the real create function. */
- usage &= ~(RADEON_USAGE_DOMAIN_GTT | RADEON_USAGE_DOMAIN_VRAM);
- if (domain & R300_DOMAIN_GTT)
- usage |= RADEON_USAGE_DOMAIN_GTT;
- if (domain & R300_DOMAIN_VRAM)
- usage |= RADEON_USAGE_DOMAIN_VRAM;
-
memset(&desc, 0, sizeof(desc));
desc.alignment = alignment;
- desc.usage = usage;
+ desc.usage = get_pb_usage_from_create_flags(bind, usage, domain);
- if (usage & PIPE_BIND_CONSTANT_BUFFER)
+ /* Assign a buffer manager. */
+ if (bind & PIPE_BIND_CONSTANT_BUFFER)
provider = ws->mman;
- else if ((usage & PIPE_BIND_VERTEX_BUFFER) ||
- (usage & PIPE_BIND_INDEX_BUFFER))
+ else if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
provider = ws->cman;
else
provider = ws->kman;
+
buffer = provider->create_buffer(provider, size, &desc);
if (!buffer)
return NULL;
@@ -65,55 +97,6 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
return radeon_libdrm_winsys_buffer(buffer);
}
-static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
- pb_destroy(_buf);
-}
-static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- uint32_t pitch,
- enum r300_buffer_tiling microtiled,
- enum r300_buffer_tiling macrotiled)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
- radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
-}
-
-static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- enum r300_buffer_tiling *microtiled,
- enum r300_buffer_tiling *macrotiled)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
- radeon_drm_bufmgr_get_tiling(_buf, microtiled, macrotiled);
-}
-
-static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf,
- unsigned usage)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
- return pb_map(_buf, usage);
-}
-
-static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
- pb_unmap(_buf);
-}
-
-static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws,
- struct r300_winsys_buffer *buf)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
- radeon_drm_bufmgr_wait(_buf);
-}
-
static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
struct r300_winsys_buffer **pdst,
struct r300_winsys_buffer *src)
@@ -126,20 +109,11 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
*pdst = radeon_libdrm_winsys_buffer(_dst);
}
-static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- enum r300_reference_domain domain)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
- return radeon_drm_bufmgr_is_buffer_referenced(_buf, domain);
-}
-
static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
struct winsys_handle *whandle,
unsigned *stride)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
struct pb_buffer *_buf;
*stride = whandle->stride;
@@ -150,111 +124,57 @@ static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r
static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
struct r300_winsys_buffer *buffer,
- struct winsys_handle *whandle,
- unsigned stride)
+ unsigned stride,
+ struct winsys_handle *whandle)
{
struct pb_buffer *_buf = radeon_pb_buffer(buffer);
whandle->stride = stride;
return radeon_drm_bufmgr_get_handle(_buf, whandle);
}
-static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
- void (*flush_cb)(void *),
- void *data)
-{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- ws->flush_cb = flush_cb;
- ws->flush_data = data;
- radeon_cs_space_set_flush(ws->cs, flush_cb, data);
-}
-
-static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- enum r300_buffer_domain rd,
- enum r300_buffer_domain wd)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
- return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
-}
-
-static boolean radeon_validate(struct r300_winsys_screen *rws)
+static void radeon_r300_winsys_cs_set_flush(struct r300_winsys_cs *rcs,
+ void (*flush)(void *),
+ void *user)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- if (radeon_cs_space_check(ws->cs) < 0) {
- return FALSE;
- }
-
- /* Things are fine, we can proceed as normal. */
- return TRUE;
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ cs->flush_cs = flush;
+ cs->flush_data = user;
+ radeon_cs_space_set_flush(cs->cs, flush, user);
}
-static unsigned radeon_get_cs_free_dwords(struct r300_winsys_screen *rws)
+static boolean radeon_r300_winsys_cs_validate(struct r300_winsys_cs *rcs)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- struct radeon_cs *cs = ws->cs;
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
- return cs->ndw - cs->cdw;
+ return radeon_cs_space_check(cs->cs) >= 0;
}
-static uint32_t *radeon_get_cs_pointer(struct r300_winsys_screen *rws,
- unsigned count)
+static void radeon_r300_winsys_cs_reset_buffers(struct r300_winsys_cs *rcs)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- struct radeon_cs *cs = ws->cs;
- uint32_t *ptr = cs->packets + cs->cdw;
-
- cs->cdw += count;
- return ptr;
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ radeon_cs_space_reset_bos(cs->cs);
}
-static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
- uint32_t dword)
+static void radeon_r300_winsys_cs_flush(struct r300_winsys_cs *rcs)
{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- radeon_cs_write_dword(ws->cs, dword);
-}
-
-static void radeon_write_cs_table(struct r300_winsys_screen *rws,
- const void *table, unsigned count)
-{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- radeon_cs_write_table(ws->cs, table, count);
-}
-
-static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf,
- enum r300_buffer_domain rd,
- enum r300_buffer_domain wd,
- uint32_t flags)
-{
- struct pb_buffer *_buf = radeon_pb_buffer(buf);
- radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
-}
-
-static void radeon_reset_bos(struct r300_winsys_screen *rws)
-{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
- radeon_cs_space_reset_bos(ws->cs);
-}
-
-static void radeon_flush_cs(struct r300_winsys_screen *rws)
-{
- struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
int retval;
/* Don't flush a zero-sized CS. */
- if (!ws->cs->cdw) {
+ if (!cs->base.cdw) {
return;
}
- radeon_drm_bufmgr_flush_maps(ws->kman);
+ cs->cs->cdw = cs->base.cdw;
+
+ radeon_drm_bufmgr_flush_maps(cs->ws->kman);
+
/* Emit the CS. */
- retval = radeon_cs_emit(ws->cs);
+ retval = radeon_cs_emit(cs->cs);
if (retval) {
if (debug_get_bool_option("RADEON_DUMP_CS", FALSE)) {
fprintf(stderr, "radeon: The kernel rejected CS, dumping...\n");
- radeon_cs_print(ws->cs, stderr);
+ radeon_cs_print(cs->cs, stderr);
} else {
fprintf(stderr, "radeon: The kernel rejected CS, "
"see dmesg for more information.\n");
@@ -265,11 +185,15 @@ static void radeon_flush_cs(struct r300_winsys_screen *rws)
* Someday, when we care about performance, we should really find a way
* to rotate between two or three CS objects so that the GPU can be
* spinning through one CS while another one is being filled. */
- radeon_cs_erase(ws->cs);
+ radeon_cs_erase(cs->cs);
+
+ cs->base.ptr = cs->cs->packets;
+ cs->base.cdw = cs->cs->cdw;
+ cs->base.ndw = cs->cs->ndw;
}
static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
- enum r300_value_id id)
+ enum r300_value_id id)
{
struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
@@ -288,11 +212,42 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
return 0;
}
-static void
-radeon_winsys_destroy(struct r300_winsys_screen *rws)
+static struct r300_winsys_cs *radeon_r300_winsys_cs_create(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
+ struct radeon_libdrm_cs *cs = CALLOC_STRUCT(radeon_libdrm_cs);
+
+ if (!cs)
+ return NULL;
+
+ /* Size limit on IBs is 64 kibibytes. */
+ cs->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
+ if (!cs->cs) {
+ FREE(cs);
+ return NULL;
+ }
+
+ radeon_cs_set_limit(cs->cs,
+ RADEON_GEM_DOMAIN_GTT, ws->gart_size);
+ radeon_cs_set_limit(cs->cs,
+ RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
+
+ cs->ws = ws;
+ cs->base.ptr = cs->cs->packets;
+ cs->base.cdw = cs->cs->cdw;
+ cs->base.ndw = cs->cs->ndw;
+ return &cs->base;
+}
+
+static void radeon_r300_winsys_cs_destroy(struct r300_winsys_cs *rcs)
+{
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ radeon_cs_destroy(cs->cs);
+}
+
+static void radeon_winsys_destroy(struct r300_winsys_screen *rws)
{
struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
- radeon_cs_destroy(ws->cs);
ws->cman->destroy(ws->cman);
ws->kman->destroy(ws->kman);
@@ -302,10 +257,8 @@ radeon_winsys_destroy(struct r300_winsys_screen *rws)
radeon_cs_manager_gem_dtor(ws->csm);
}
-boolean
-radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
+boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
{
-
ws->csm = radeon_cs_manager_gem_ctor(fd);
if (!ws->csm)
goto fail;
@@ -324,39 +277,28 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
if (!ws->mman)
goto fail;
- /* Size limit on IBs is 64 kibibytes. */
- ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
- if (!ws->cs)
- goto fail;
- radeon_cs_set_limit(ws->cs,
- RADEON_GEM_DOMAIN_GTT, ws->gart_size);
- radeon_cs_set_limit(ws->cs,
- RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
-
- ws->base.add_buffer = radeon_add_buffer;
- ws->base.validate = radeon_validate;
ws->base.destroy = radeon_winsys_destroy;
- ws->base.get_cs_free_dwords = radeon_get_cs_free_dwords;
- ws->base.get_cs_pointer = radeon_get_cs_pointer;
- ws->base.write_cs_dword = radeon_write_cs_dword;
- ws->base.write_cs_table = radeon_write_cs_table;
- ws->base.write_cs_reloc = radeon_write_cs_reloc;
- ws->base.flush_cs = radeon_flush_cs;
- ws->base.reset_bos = radeon_reset_bos;
- ws->base.set_flush_cb = radeon_set_flush_cb;
ws->base.get_value = radeon_get_value;
ws->base.buffer_create = radeon_r300_winsys_buffer_create;
- ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy;
- ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling;
- ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling;
- ws->base.buffer_map = radeon_r300_winsys_buffer_map;
- ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
- ws->base.buffer_wait = radeon_r300_winsys_buffer_wait;
+ ws->base.buffer_set_tiling = radeon_drm_bufmgr_set_tiling;
+ ws->base.buffer_get_tiling = radeon_drm_bufmgr_get_tiling;
+ ws->base.buffer_map = radeon_drm_buffer_map;
+ ws->base.buffer_unmap = radeon_drm_buffer_unmap;
+ ws->base.buffer_wait = radeon_drm_bufmgr_wait;
ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
- ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced;
+
+ ws->base.cs_create = radeon_r300_winsys_cs_create;
+ ws->base.cs_destroy = radeon_r300_winsys_cs_destroy;
+ ws->base.cs_add_buffer = radeon_drm_bufmgr_add_buffer;
+ ws->base.cs_validate = radeon_r300_winsys_cs_validate;
+ ws->base.cs_write_reloc = radeon_drm_bufmgr_write_reloc;
+ ws->base.cs_flush = radeon_r300_winsys_cs_flush;
+ ws->base.cs_reset_buffers = radeon_r300_winsys_cs_reset_buffers;
+ ws->base.cs_set_flush = radeon_r300_winsys_cs_set_flush;
+ ws->base.cs_is_buffer_referenced = radeon_drm_bufmgr_is_buffer_referenced;
return TRUE;
fail:
@@ -373,7 +315,5 @@ fail:
if (ws->mman)
ws->mman->destroy(ws->mman);
- if (ws->cs)
- radeon_cs_destroy(ws->cs);
return FALSE;
}
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index ca789be8e93..9a25e7679c9 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -75,19 +75,32 @@ struct radeon_libdrm_winsys {
/* Radeon CS manager. */
struct radeon_cs_manager *csm;
+};
+
+struct radeon_libdrm_cs {
+ struct r300_winsys_cs base;
+
+ /* The winsys. */
+ struct radeon_libdrm_winsys *ws;
- /* Current CS. */
+ /* The libdrm command stream. */
struct radeon_cs *cs;
- /* Flush CB */
- void (*flush_cb)(void *);
+ /* Flush CS. */
+ void (*flush_cs)(void *);
void *flush_data;
};
+static INLINE struct radeon_libdrm_cs *
+radeon_libdrm_cs(struct r300_winsys_cs *base)
+{
+ return (struct radeon_libdrm_cs*)base;
+}
+
static INLINE struct radeon_libdrm_winsys *
-radeon_winsys_screen(struct r300_winsys_screen *base)
+radeon_libdrm_winsys(struct r300_winsys_screen *base)
{
- return (struct radeon_libdrm_winsys *)base;
+ return (struct radeon_libdrm_winsys*)base;
}
#endif