r300g: rebuild winsys/pipe buffer handling and add buffer map
This creates a cleaner winsys and drop the simple screen stuff. It makes r300g use pb_bufmgr structs and adds usage of the cached bufmgr for vertex/index buffers. It also avoids mapping too often. I'm not 100% sure this is perfect but it won't find its own bugs. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
233290f203
commit
fff5be8e7b
|
@ -14,6 +14,7 @@ C_SOURCES = \
|
|||
r300_query.c \
|
||||
r300_render.c \
|
||||
r300_screen.c \
|
||||
r300_screen_buffer.c \
|
||||
r300_state.c \
|
||||
r300_state_derived.c \
|
||||
r300_state_invariant.c \
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_list.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "r300_blit.h"
|
||||
#include "r300_context.h"
|
||||
|
@ -54,6 +55,9 @@ static void r300_destroy_context(struct pipe_context* context)
|
|||
FREE(query);
|
||||
}
|
||||
|
||||
u_upload_destroy(r300->upload_vb);
|
||||
u_upload_destroy(r300->upload_ib);
|
||||
|
||||
FREE(r300->blend_color_state.state);
|
||||
FREE(r300->clip_state.state);
|
||||
FREE(r300->fb_state.state);
|
||||
|
@ -70,11 +74,7 @@ r300_is_texture_referenced(struct pipe_context *pipe,
|
|||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level)
|
||||
{
|
||||
struct pipe_buffer* buf = 0;
|
||||
|
||||
r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
|
||||
|
||||
return pipe->is_buffer_referenced(pipe, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
@ -136,14 +136,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
{
|
||||
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
|
||||
struct r300_screen* r300screen = r300_screen(screen);
|
||||
struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys;
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
|
||||
if (!r300)
|
||||
return NULL;
|
||||
|
||||
r300->winsys = radeon_winsys;
|
||||
r300->rws = rws;
|
||||
|
||||
r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
|
||||
r300->context.winsys = (struct pipe_winsys*)rws;
|
||||
r300->context.screen = screen;
|
||||
r300->context.priv = priv;
|
||||
|
||||
|
@ -201,11 +201,31 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
|
||||
r300->invariant_state.dirty = TRUE;
|
||||
|
||||
r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
|
||||
rws->set_flush_cb(r300->rws, r300_flush_cb, r300);
|
||||
r300->dirty_state = R300_NEW_KITCHEN_SINK;
|
||||
r300->dirty_hw++;
|
||||
|
||||
r300->blitter = util_blitter_create(&r300->context);
|
||||
|
||||
r300->upload_ib = u_upload_create(screen,
|
||||
32 * 1024, 16,
|
||||
PIPE_BUFFER_USAGE_INDEX);
|
||||
|
||||
if (r300->upload_ib == NULL)
|
||||
goto no_upload_ib;
|
||||
|
||||
r300->upload_vb = u_upload_create(screen,
|
||||
128 * 1024, 16,
|
||||
PIPE_BUFFER_USAGE_VERTEX);
|
||||
if (r300->upload_vb == NULL)
|
||||
goto no_upload_vb;
|
||||
|
||||
return &r300->context;
|
||||
|
||||
// u_upload_destroy(r300->upload_vb);
|
||||
no_upload_ib:
|
||||
u_upload_destroy(r300->upload_ib);
|
||||
no_upload_vb:
|
||||
FREE(r300);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "r300_screen.h"
|
||||
|
||||
struct u_upload_mgr;
|
||||
struct r300_context;
|
||||
|
||||
struct r300_fragment_shader;
|
||||
|
@ -238,7 +239,7 @@ struct r300_texture {
|
|||
boolean is_npot;
|
||||
|
||||
/* Pipe buffer backing this texture. */
|
||||
struct pipe_buffer* buffer;
|
||||
struct r300_winsys_buffer *buffer;
|
||||
|
||||
/* Registers carrying texture format data. */
|
||||
struct r300_texture_state state;
|
||||
|
@ -265,7 +266,7 @@ struct r300_context {
|
|||
struct pipe_context context;
|
||||
|
||||
/* The interface to the windowing system, etc. */
|
||||
struct radeon_winsys* winsys;
|
||||
struct r300_winsys_screen *rws;
|
||||
/* Draw module. Used mostly for SW TCL. */
|
||||
struct draw_context* draw;
|
||||
/* Accelerated blit support. */
|
||||
|
@ -330,6 +331,7 @@ struct r300_context {
|
|||
/* Vertex elements for Gallium. */
|
||||
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
||||
int vertex_element_count;
|
||||
bool any_user_vbs;
|
||||
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
|
||||
|
@ -343,6 +345,9 @@ struct r300_context {
|
|||
boolean polygon_offset_enabled;
|
||||
/* Z buffer bit depth. */
|
||||
uint32_t zbuffer_bpp;
|
||||
|
||||
struct u_upload_mgr *upload_vb;
|
||||
struct u_upload_mgr *upload_ib;
|
||||
};
|
||||
|
||||
/* Convenience cast wrapper. */
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
#define CS_LOCALS(context) \
|
||||
struct r300_context* const cs_context_copy = (context); \
|
||||
struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \
|
||||
struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \
|
||||
int cs_count = 0; (void) cs_count;
|
||||
|
||||
#define CHECK_CS(size) \
|
||||
|
@ -105,22 +105,34 @@
|
|||
cs_count--; \
|
||||
} while (0)
|
||||
|
||||
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
|
||||
#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \
|
||||
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \
|
||||
"domains (%d, %d, %d)\n", \
|
||||
bo, offset, rd, wd, flags); \
|
||||
assert(bo); \
|
||||
cs_winsys->write_cs_dword(cs_winsys, offset); \
|
||||
cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
|
||||
r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \
|
||||
cs_count -= 3; \
|
||||
} while (0)
|
||||
|
||||
#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
|
||||
|
||||
#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \
|
||||
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \
|
||||
"domains (%d, %d, %d)\n", \
|
||||
tex, offset, rd, wd, flags); \
|
||||
assert(tex); \
|
||||
cs_winsys->write_cs_dword(cs_winsys, offset); \
|
||||
r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \
|
||||
cs_count -= 3; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
|
||||
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \
|
||||
"domains (%d, %d, %d)\n", \
|
||||
bo, rd, wd, flags); \
|
||||
assert(bo); \
|
||||
cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
|
||||
r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \
|
||||
cs_count -= 2; \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "r300_emit.h"
|
||||
#include "r300_fs.h"
|
||||
#include "r300_screen.h"
|
||||
#include "r300_screen_buffer.h"
|
||||
#include "r300_state_inlines.h"
|
||||
#include "r300_vs.h"
|
||||
|
||||
void r300_emit_blend_state(struct r300_context* r300, void* state)
|
||||
|
@ -418,10 +420,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state)
|
|||
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
|
||||
|
||||
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
|
||||
OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
|
||||
OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level],
|
||||
OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level],
|
||||
0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt);
|
||||
|
@ -434,12 +436,12 @@ void r300_emit_fb_state(struct r300_context* r300, void* state)
|
|||
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
|
||||
|
||||
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
|
||||
OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format);
|
||||
|
||||
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
|
||||
OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level],
|
||||
OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level],
|
||||
0, RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
}
|
||||
|
||||
|
@ -489,13 +491,13 @@ static void r300_emit_query_finish(struct r300_context *r300,
|
|||
/* pipe 3 only */
|
||||
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
|
||||
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
|
||||
OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
|
||||
0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
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(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
|
||||
0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
case 2:
|
||||
/* pipe 1 only */
|
||||
|
@ -503,13 +505,13 @@ static void r300_emit_query_finish(struct r300_context *r300,
|
|||
OUT_CS_REG(R300_SU_REG_DEST,
|
||||
1 << (caps->high_second_pipe ? 3 : 1));
|
||||
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
|
||||
OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
|
||||
0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
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(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
|
||||
0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
break;
|
||||
default:
|
||||
|
@ -531,7 +533,7 @@ static void rv530_emit_query_single(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(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
|
||||
END_CS;
|
||||
}
|
||||
|
@ -544,10 +546,10 @@ static void rv530_emit_query_double(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(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
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(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
|
||||
END_CS;
|
||||
}
|
||||
|
@ -759,7 +761,7 @@ void r300_emit_texture(struct r300_context* r300,
|
|||
OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);
|
||||
OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2);
|
||||
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1);
|
||||
OUT_CS_RELOC(tex->buffer,
|
||||
OUT_CS_TEX_RELOC(tex,
|
||||
R300_TXO_MACRO_TILE(tex->macrotile) |
|
||||
R300_TXO_MICRO_TILE(tex->microtile),
|
||||
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
||||
|
@ -800,7 +802,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
|
|||
}
|
||||
|
||||
for (i = 0; i < aos_count; i++) {
|
||||
OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
|
||||
OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
|
||||
RADEON_GEM_DOMAIN_GTT, 0, 0);
|
||||
}
|
||||
END_CS;
|
||||
|
@ -1012,15 +1014,15 @@ void r300_emit_buffer_validate(struct r300_context *r300)
|
|||
boolean invalid = FALSE;
|
||||
|
||||
/* Clean out BOs. */
|
||||
r300->winsys->reset_bos(r300->winsys);
|
||||
r300->rws->reset_bos(r300->rws);
|
||||
|
||||
validate:
|
||||
/* Color buffers... */
|
||||
for (i = 0; i < fb->nr_cbufs; i++) {
|
||||
tex = (struct r300_texture*)fb->cbufs[i]->texture;
|
||||
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
|
||||
if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
|
||||
0, RADEON_GEM_DOMAIN_VRAM)) {
|
||||
if (!r300_add_texture(r300->rws, tex,
|
||||
0, RADEON_GEM_DOMAIN_VRAM)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
|
@ -1029,8 +1031,8 @@ validate:
|
|||
if (fb->zsbuf) {
|
||||
tex = (struct r300_texture*)fb->zsbuf->texture;
|
||||
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
|
||||
if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
|
||||
0, RADEON_GEM_DOMAIN_VRAM)) {
|
||||
if (!r300_add_texture(r300->rws, tex,
|
||||
0, RADEON_GEM_DOMAIN_VRAM)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
|
@ -1040,31 +1042,31 @@ validate:
|
|||
tex = r300->textures[i];
|
||||
if (!tex)
|
||||
continue;
|
||||
if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
|
||||
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
|
||||
if (!r300_add_texture(r300->rws, tex,
|
||||
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
}
|
||||
/* ...occlusion query buffer... */
|
||||
if (r300->dirty_state & R300_NEW_QUERY) {
|
||||
if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
|
||||
0, RADEON_GEM_DOMAIN_GTT)) {
|
||||
if (!r300_add_buffer(r300->rws, r300->oqbo,
|
||||
0, RADEON_GEM_DOMAIN_GTT)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
}
|
||||
/* ...and vertex buffer. */
|
||||
if (r300->vbo) {
|
||||
if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
if (!r300_add_buffer(r300->rws, r300->vbo,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
} else {
|
||||
/* debug_printf("No VBO while emitting dirty state!\n"); */
|
||||
}
|
||||
if (!r300->winsys->validate(r300->winsys)) {
|
||||
if (!r300->rws->validate(r300->rws)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
if (invalid) {
|
||||
/* Well, hell. */
|
||||
|
@ -1096,7 +1098,7 @@ void r300_emit_dirty_state(struct r300_context* r300)
|
|||
/* Make sure we have at least 2*1024 spare dwords. */
|
||||
/* XXX It would be nice to know the number of dwords we really need to
|
||||
* XXX emit. */
|
||||
while (!r300->winsys->check_cs(r300->winsys, dwords)) {
|
||||
while (!r300->rws->check_cs(r300->rws, dwords)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "util/u_prim.h"
|
||||
|
||||
#include "r300_cs.h"
|
||||
#include "r300_context.h"
|
||||
#include "r300_screen_buffer.h"
|
||||
#include "r300_emit.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_render.h"
|
||||
|
@ -297,7 +299,7 @@ static void r300_emit_draw_elements(struct r300_context *r300,
|
|||
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
|
||||
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
|
||||
OUT_CS(offset_dwords << 2);
|
||||
OUT_CS_RELOC(indexBuffer, count_dwords,
|
||||
OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
|
||||
RADEON_GEM_DOMAIN_GTT, 0, 0);
|
||||
|
||||
END_CS;
|
||||
|
@ -308,21 +310,28 @@ static boolean r300_setup_vertex_buffers(struct r300_context *r300)
|
|||
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
|
||||
struct pipe_vertex_element *velem = r300->vertex_element;
|
||||
struct pipe_buffer *pbuf;
|
||||
int ret;
|
||||
|
||||
/* upload buffers first */
|
||||
if (r300->any_user_vbs) {
|
||||
ret = r300_upload_user_buffers(r300);
|
||||
r300->any_user_vbs = false;
|
||||
}
|
||||
|
||||
validate:
|
||||
for (int i = 0; i < r300->vertex_element_count; i++) {
|
||||
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
|
||||
|
||||
if (!r300->winsys->add_buffer(r300->winsys, pbuf,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
if (!r300_add_buffer(r300->rws, pbuf,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
goto validate;
|
||||
}
|
||||
}
|
||||
|
||||
if (!r300->winsys->validate(r300->winsys)) {
|
||||
if (!r300->rws->validate(r300->rws)) {
|
||||
r300->context.flush(&r300->context, 0, NULL);
|
||||
return r300->winsys->validate(r300->winsys);
|
||||
return r300->rws->validate(r300->rws);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -396,15 +405,20 @@ void r300_draw_range_elements(struct pipe_context* pipe,
|
|||
indexSize = 2;
|
||||
}
|
||||
|
||||
if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
r300_upload_index_buffer(r300, &indexBuffer,
|
||||
indexSize, start, count);
|
||||
|
||||
if (!r300_add_buffer(r300->rws, indexBuffer,
|
||||
RADEON_GEM_DOMAIN_GTT, 0)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!r300->winsys->validate(r300->winsys)) {
|
||||
if (!r300->rws->validate(r300->rws)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
u_upload_flush(r300->upload_vb);
|
||||
u_upload_flush(r300->upload_ib);
|
||||
r300_emit_dirty_state(r300);
|
||||
|
||||
r300_emit_aos(r300, 0);
|
||||
|
@ -425,7 +439,7 @@ void r300_draw_range_elements(struct pipe_context* pipe,
|
|||
|
||||
cleanup:
|
||||
if (indexBuffer != orgIndexBuffer) {
|
||||
pipe->screen->buffer_destroy(indexBuffer);
|
||||
pipe_buffer_reference( &indexBuffer, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,6 +480,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
|
|||
return;
|
||||
}
|
||||
|
||||
u_upload_flush(r300->upload_vb);
|
||||
r300_emit_dirty_state(r300);
|
||||
|
||||
if (alt_num_verts || count <= 65535) {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_screen.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "r300_screen.h"
|
||||
|
@ -32,6 +31,8 @@
|
|||
#include "radeon_winsys.h"
|
||||
#include "r300_winsys.h"
|
||||
|
||||
#include "r300_screen_buffer.h"
|
||||
|
||||
/* Return the identifier behind whom the brave coders responsible for this
|
||||
* amalgamation of code, sweat, and duct tape, routinely obscure their names.
|
||||
*
|
||||
|
@ -292,10 +293,11 @@ static void* r300_transfer_map(struct pipe_screen* screen,
|
|||
struct pipe_transfer* transfer)
|
||||
{
|
||||
struct r300_texture* tex = (struct r300_texture*)transfer->texture;
|
||||
struct r300_winsys_screen *rws = r300_winsys_screen(screen);
|
||||
char* map;
|
||||
enum pipe_format format = tex->tex.format;
|
||||
|
||||
map = pipe_buffer_map(screen, tex->buffer,
|
||||
map = rws->buffer_map(rws, tex->buffer,
|
||||
pipe_transfer_buffer_flags(transfer));
|
||||
|
||||
if (!map) {
|
||||
|
@ -311,21 +313,26 @@ static void r300_transfer_unmap(struct pipe_screen* screen,
|
|||
struct pipe_transfer* transfer)
|
||||
{
|
||||
struct r300_texture* tex = (struct r300_texture*)transfer->texture;
|
||||
pipe_buffer_unmap(screen, tex->buffer);
|
||||
struct r300_winsys_screen *rws = r300_winsys_screen(screen);
|
||||
rws->buffer_unmap(rws, tex->buffer);
|
||||
}
|
||||
|
||||
static void r300_destroy_screen(struct pipe_screen* pscreen)
|
||||
{
|
||||
struct r300_screen* r300screen = r300_screen(pscreen);
|
||||
struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
|
||||
|
||||
if (rws)
|
||||
rws->destroy(rws);
|
||||
|
||||
FREE(r300screen->caps);
|
||||
FREE(r300screen);
|
||||
}
|
||||
|
||||
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
|
||||
struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
|
||||
{
|
||||
struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
|
||||
struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
|
||||
struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
|
||||
struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities);
|
||||
|
||||
if (!r300screen || !caps) {
|
||||
FREE(r300screen);
|
||||
|
@ -333,16 +340,16 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
caps->pci_id = radeon_winsys->pci_id;
|
||||
caps->num_frag_pipes = radeon_winsys->gb_pipes;
|
||||
caps->num_z_pipes = radeon_winsys->z_pipes;
|
||||
caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID);
|
||||
caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES);
|
||||
caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES);
|
||||
|
||||
r300_init_debug(r300screen);
|
||||
r300_parse_chipset(caps);
|
||||
|
||||
r300screen->caps = caps;
|
||||
r300screen->radeon_winsys = radeon_winsys;
|
||||
r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys;
|
||||
r300screen->rws = rws;
|
||||
r300screen->screen.winsys = (struct pipe_winsys*)rws;
|
||||
r300screen->screen.destroy = r300_destroy_screen;
|
||||
r300screen->screen.get_name = r300_get_name;
|
||||
r300screen->screen.get_vendor = r300_get_vendor;
|
||||
|
@ -356,7 +363,12 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
|
|||
r300screen->screen.transfer_unmap = r300_transfer_unmap;
|
||||
|
||||
r300_init_screen_texture_functions(&r300screen->screen);
|
||||
u_simple_screen_init(&r300screen->screen);
|
||||
|
||||
r300_screen_init_buffer_functions(r300screen);
|
||||
return &r300screen->screen;
|
||||
}
|
||||
|
||||
struct r300_winsys_screen *
|
||||
r300_winsys_screen(struct pipe_screen *screen)
|
||||
{
|
||||
return r300_screen(screen)->rws;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ struct r300_screen {
|
|||
/* Parent class */
|
||||
struct pipe_screen screen;
|
||||
|
||||
struct radeon_winsys* radeon_winsys;
|
||||
struct r300_winsys_screen *rws;
|
||||
|
||||
/* Chipset capabilities */
|
||||
struct r300_capabilities* caps;
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "r300_screen_buffer.h"
|
||||
|
||||
#include "r300_winsys.h"
|
||||
|
||||
int r300_upload_index_buffer(struct r300_context *r300,
|
||||
struct pipe_buffer **index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
struct pipe_buffer *upload_buffer = NULL;
|
||||
unsigned index_offset = start * index_size;
|
||||
int ret = 0;
|
||||
|
||||
if (r300_buffer_is_user_buffer(*index_buffer)) {
|
||||
ret = u_upload_buffer(r300->upload_ib,
|
||||
index_offset,
|
||||
count * index_size,
|
||||
*index_buffer,
|
||||
&index_offset,
|
||||
&upload_buffer);
|
||||
if (ret) {
|
||||
goto done;
|
||||
}
|
||||
*index_buffer = upload_buffer;
|
||||
}
|
||||
done:
|
||||
// if (upload_buffer)
|
||||
// pipe_buffer_reference(&upload_buffer, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int r300_upload_user_buffers(struct r300_context *r300)
|
||||
{
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
int i, nr;
|
||||
|
||||
nr = r300->vertex_buffer_count;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
|
||||
if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) {
|
||||
struct pipe_buffer *upload_buffer = NULL;
|
||||
unsigned offset = 0;
|
||||
unsigned size = r300->vertex_buffer[i].buffer->size;
|
||||
unsigned upload_offset;
|
||||
|
||||
ret = u_upload_buffer(r300->upload_vb,
|
||||
offset, size,
|
||||
r300->vertex_buffer[i].buffer,
|
||||
&upload_offset, &upload_buffer);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
|
||||
r300->vertex_buffer[i].buffer = upload_buffer;
|
||||
r300->vertex_buffer[i].buffer_offset = upload_offset;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct r300_winsys_buffer *
|
||||
r300_winsys_buffer_create(struct r300_screen *r300screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
struct r300_winsys_buffer *buf;
|
||||
|
||||
buf = rws->buffer_create(rws, alignment, usage, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
|
||||
struct r300_buffer *rbuf)
|
||||
{
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
|
||||
if (rbuf->buf) {
|
||||
rws->buffer_destroy(rbuf->buf);
|
||||
rbuf->buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(screen);
|
||||
struct r300_buffer *rbuf;
|
||||
|
||||
rbuf = CALLOC_STRUCT(r300_buffer);
|
||||
if (!rbuf)
|
||||
goto error1;
|
||||
|
||||
rbuf->magic = R300_BUFFER_MAGIC;
|
||||
|
||||
pipe_reference_init(&rbuf->base.reference, 1);
|
||||
rbuf->base.screen = screen;
|
||||
rbuf->base.alignment = alignment;
|
||||
rbuf->base.usage = usage;
|
||||
rbuf->base.size = size;
|
||||
|
||||
rbuf->buf = r300_winsys_buffer_create(r300screen,
|
||||
alignment,
|
||||
usage,
|
||||
size);
|
||||
|
||||
if (!rbuf->buf)
|
||||
goto error2;
|
||||
|
||||
return &rbuf->base;
|
||||
error2:
|
||||
FREE(rbuf);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct r300_buffer *rbuf;
|
||||
|
||||
rbuf = CALLOC_STRUCT(r300_buffer);
|
||||
if (!rbuf)
|
||||
goto no_rbuf;
|
||||
|
||||
rbuf->magic = R300_BUFFER_MAGIC;
|
||||
|
||||
pipe_reference_init(&rbuf->base.reference, 1);
|
||||
rbuf->base.screen = screen;
|
||||
rbuf->base.alignment = 1;
|
||||
rbuf->base.usage = 0;
|
||||
rbuf->base.size = bytes;
|
||||
|
||||
rbuf->user_buffer = ptr;
|
||||
return &rbuf->base;
|
||||
|
||||
no_rbuf:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void r300_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(buf->screen);
|
||||
struct r300_buffer *rbuf = r300_buffer(buf);
|
||||
|
||||
r300_winsys_buffer_destroy(r300screen, rbuf);
|
||||
FREE(rbuf);
|
||||
}
|
||||
|
||||
static void *
|
||||
r300_buffer_map_range(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned offset, unsigned length,
|
||||
unsigned usage )
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(screen);
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
struct r300_buffer *rbuf = r300_buffer(buf);
|
||||
void *map;
|
||||
|
||||
if (rbuf->user_buffer)
|
||||
return rbuf->user_buffer;
|
||||
|
||||
map = rws->buffer_map(rws, rbuf->buf, usage);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static void *
|
||||
r300_buffer_map(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned usage)
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(screen);
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
struct r300_buffer *rbuf = r300_buffer(buf);
|
||||
void *map;
|
||||
|
||||
if (rbuf->user_buffer)
|
||||
return rbuf->user_buffer;
|
||||
|
||||
map = rws->buffer_map(rws, rbuf->buf, usage);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static void
|
||||
r300_buffer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct r300_screen *r300screen = r300_screen(screen);
|
||||
struct r300_winsys_screen *rws = r300screen->rws;
|
||||
struct r300_buffer *rbuf = r300_buffer(buf);
|
||||
|
||||
if (rbuf->buf)
|
||||
rws->buffer_unmap(rws, rbuf->buf);
|
||||
}
|
||||
|
||||
void r300_screen_init_buffer_functions(struct r300_screen *r300screen)
|
||||
{
|
||||
r300screen->screen.buffer_create = r300_buffer_create;
|
||||
r300screen->screen.user_buffer_create = r300_user_buffer_create;
|
||||
r300screen->screen.buffer_map = r300_buffer_map;
|
||||
r300screen->screen.buffer_map_range = r300_buffer_map_range;
|
||||
// r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range;
|
||||
r300screen->screen.buffer_unmap = r300_buffer_unmap;
|
||||
r300screen->screen.buffer_destroy = r300_buffer_destroy;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef R300_SCREEN_BUFFER_H
|
||||
#define R300_SCREEN_BUFFER_H
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "r300_screen.h"
|
||||
|
||||
#include "r300_winsys.h"
|
||||
#include "r300_context.h"
|
||||
|
||||
#define R300_BUFFER_MAGIC 0xabcd1234
|
||||
|
||||
struct r300_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
|
||||
uint32_t magic;
|
||||
|
||||
struct r300_winsys_buffer *buf;
|
||||
|
||||
void *user_buffer;
|
||||
};
|
||||
|
||||
static INLINE struct r300_buffer *
|
||||
r300_buffer(struct pipe_buffer *buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC);
|
||||
return (struct r300_buffer *)buffer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
r300_buffer_is_user_buffer(struct pipe_buffer *buffer)
|
||||
{
|
||||
return r300_buffer(buffer)->user_buffer ? true : false;
|
||||
}
|
||||
|
||||
static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws,
|
||||
struct pipe_buffer *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);
|
||||
}
|
||||
|
||||
void r300_screen_init_buffer_functions(struct r300_screen *r300screen);
|
||||
|
||||
static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws,
|
||||
struct r300_buffer *buf,
|
||||
uint32_t rd, uint32_t wd, uint32_t flags)
|
||||
{
|
||||
if (!buf->buf)
|
||||
return;
|
||||
|
||||
rws->write_cs_reloc(rws, buf->buf, rd, wd, flags);
|
||||
}
|
||||
|
||||
static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws,
|
||||
struct r300_texture *texture,
|
||||
uint32_t rd, uint32_t wd, uint32_t flags)
|
||||
{
|
||||
rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags);
|
||||
}
|
||||
|
||||
int r300_upload_user_buffers(struct r300_context *r300);
|
||||
|
||||
int r300_upload_index_buffer(struct r300_context *r300,
|
||||
struct pipe_buffer **index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned start,
|
||||
unsigned count);
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include "r300_context.h"
|
||||
#include "r300_reg.h"
|
||||
#include "r300_screen.h"
|
||||
#include "r300_screen_buffer.h"
|
||||
#include "r300_state_inlines.h"
|
||||
#include "r300_fs.h"
|
||||
#include "r300_vs.h"
|
||||
|
@ -521,7 +522,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
|
|||
tex = (struct r300_texture*)old_state->cbufs[i]->texture;
|
||||
|
||||
if (tex) {
|
||||
r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
|
||||
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
|
||||
tex->pitch[0],
|
||||
tex->microtile != 0,
|
||||
tex->macrotile != 0);
|
||||
|
@ -533,7 +534,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
|
|||
tex = (struct r300_texture*)old_state->zsbuf->texture;
|
||||
|
||||
if (tex) {
|
||||
r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
|
||||
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
|
||||
tex->pitch[0],
|
||||
tex->microtile != 0,
|
||||
tex->macrotile != 0);
|
||||
|
@ -545,7 +546,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
|
|||
tex = (struct r300_texture*)new_state->cbufs[i]->texture;
|
||||
level = new_state->cbufs[i]->level;
|
||||
|
||||
r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
|
||||
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
|
||||
tex->pitch[level],
|
||||
tex->microtile != 0,
|
||||
tex->mip_macrotile[level] != 0);
|
||||
|
@ -554,7 +555,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
|
|||
tex = (struct r300_texture*)new_state->zsbuf->texture;
|
||||
level = new_state->zsbuf->level;
|
||||
|
||||
r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
|
||||
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
|
||||
tex->pitch[level],
|
||||
tex->microtile != 0,
|
||||
tex->mip_macrotile[level] != 0);
|
||||
|
@ -1028,10 +1029,26 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
|
|||
const struct pipe_vertex_buffer* buffers)
|
||||
{
|
||||
struct r300_context* r300 = r300_context(pipe);
|
||||
boolean any_user_buffer = false;
|
||||
int i;
|
||||
|
||||
if (count == r300->vertex_buffer_count &&
|
||||
memcmp(r300->vertex_buffer, buffers, count * sizeof(buffers[0])) == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pipe_buffer_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer);
|
||||
if (r300_buffer_is_user_buffer(buffers[i].buffer))
|
||||
any_user_buffer = true;
|
||||
}
|
||||
|
||||
for ( ; i < r300->vertex_buffer_count; i++)
|
||||
pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
|
||||
|
||||
memcpy(r300->vertex_buffer, buffers,
|
||||
sizeof(struct pipe_vertex_buffer) * count);
|
||||
r300->vertex_buffer_count = count;
|
||||
r300->any_user_vbs = any_user_buffer;
|
||||
|
||||
if (r300->draw) {
|
||||
draw_flush(r300->draw);
|
||||
|
|
|
@ -731,7 +731,7 @@ static struct pipe_texture*
|
|||
{
|
||||
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
|
||||
struct r300_screen* rscreen = r300_screen(screen);
|
||||
struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
|
||||
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
|
||||
|
||||
if (!tex) {
|
||||
return NULL;
|
||||
|
@ -745,13 +745,13 @@ static struct pipe_texture*
|
|||
r300_setup_miptree(rscreen, tex);
|
||||
r300_setup_texture_state(rscreen, tex);
|
||||
|
||||
tex->buffer = screen->buffer_create(screen, 2048,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
tex->size);
|
||||
winsys->buffer_set_tiling(winsys, tex->buffer,
|
||||
tex->pitch[0],
|
||||
tex->microtile != R300_BUFFER_LINEAR,
|
||||
tex->macrotile != R300_BUFFER_LINEAR);
|
||||
tex->buffer = rws->buffer_create(rws, 2048,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
tex->size);
|
||||
rws->buffer_set_tiling(rws, tex->buffer,
|
||||
tex->pitch[0],
|
||||
tex->microtile != R300_BUFFER_LINEAR,
|
||||
tex->macrotile != R300_BUFFER_LINEAR);
|
||||
|
||||
if (!tex->buffer) {
|
||||
FREE(tex);
|
||||
|
@ -764,9 +764,9 @@ static struct pipe_texture*
|
|||
static void r300_texture_destroy(struct pipe_texture* texture)
|
||||
{
|
||||
struct r300_texture* tex = (struct r300_texture*)texture;
|
||||
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
|
||||
|
||||
pipe_buffer_reference(&tex->buffer, NULL);
|
||||
|
||||
rws->buffer_reference(rws, &tex->buffer, NULL);
|
||||
FREE(tex);
|
||||
}
|
||||
|
||||
|
@ -806,14 +806,14 @@ static void r300_tex_surface_destroy(struct pipe_surface* s)
|
|||
FREE(s);
|
||||
}
|
||||
|
||||
static struct pipe_texture*
|
||||
r300_texture_blanket(struct pipe_screen* screen,
|
||||
const struct pipe_texture* base,
|
||||
const unsigned* stride,
|
||||
struct pipe_buffer* buffer)
|
||||
struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen,
|
||||
const struct pipe_texture *base,
|
||||
const unsigned *stride,
|
||||
struct r300_winsys_buffer *buffer)
|
||||
{
|
||||
struct r300_texture* tex;
|
||||
struct r300_screen* rscreen = r300_screen(screen);
|
||||
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
|
||||
|
||||
/* Support only 2D textures without mipmaps */
|
||||
if (base->target != PIPE_TEXTURE_2D ||
|
||||
|
@ -837,7 +837,7 @@ static struct pipe_texture*
|
|||
r300_setup_flags(tex);
|
||||
r300_setup_texture_state(rscreen, tex);
|
||||
|
||||
pipe_buffer_reference(&tex->buffer, buffer);
|
||||
rws->buffer_reference(rws, &tex->buffer, buffer);
|
||||
|
||||
return (struct pipe_texture*)tex;
|
||||
}
|
||||
|
@ -896,7 +896,6 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen)
|
|||
screen->texture_destroy = r300_texture_destroy;
|
||||
screen->get_tex_surface = r300_get_tex_surface;
|
||||
screen->tex_surface_destroy = r300_tex_surface_destroy;
|
||||
screen->texture_blanket = r300_texture_blanket;
|
||||
|
||||
screen->video_surface_create = r300_video_surface_create;
|
||||
screen->video_surface_destroy= r300_video_surface_destroy;
|
||||
|
@ -904,19 +903,23 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen)
|
|||
|
||||
boolean r300_get_texture_buffer(struct pipe_screen* screen,
|
||||
struct pipe_texture* texture,
|
||||
struct pipe_buffer** buffer,
|
||||
struct r300_winsys_buffer** buffer,
|
||||
unsigned* stride)
|
||||
{
|
||||
struct r300_texture* tex = (struct r300_texture*)texture;
|
||||
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
|
||||
struct r300_winsys_buffer *buf;
|
||||
|
||||
if (!tex) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pipe_buffer_reference(buffer, tex->buffer);
|
||||
rws->buffer_reference(rws, &buf, tex->buffer);
|
||||
|
||||
if (stride) {
|
||||
*stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
|
||||
}
|
||||
|
||||
*buffer = buf;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ r300_video_surface(struct pipe_video_surface *pvs)
|
|||
#ifndef R300_WINSYS_H
|
||||
|
||||
boolean r300_get_texture_buffer(struct pipe_screen* screen,
|
||||
struct pipe_texture* texture,
|
||||
struct pipe_buffer** buffer,
|
||||
struct pipe_texture *texture,
|
||||
struct r300_winsys_buffer** buffer,
|
||||
unsigned* stride);
|
||||
|
||||
#endif /* R300_WINSYS_H */
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
#ifndef R300_WINSYS_H
|
||||
#define R300_WINSYS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
@ -34,19 +30,128 @@ extern "C" {
|
|||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
struct radeon_winsys;
|
||||
struct r300_winsys_screen;
|
||||
|
||||
/* Creates a new r300 screen. */
|
||||
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
|
||||
struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws);
|
||||
|
||||
struct r300_winsys_buffer;
|
||||
|
||||
|
||||
boolean r300_get_texture_buffer(struct pipe_screen* screen,
|
||||
struct pipe_texture* texture,
|
||||
struct pipe_buffer** buffer,
|
||||
unsigned* stride);
|
||||
struct r300_winsys_buffer** buffer,
|
||||
unsigned *stride);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
enum r300_value_id {
|
||||
R300_VID_PCI_ID,
|
||||
R300_VID_GB_PIPES,
|
||||
R300_VID_Z_PIPES,
|
||||
};
|
||||
|
||||
struct r300_winsys_screen {
|
||||
void (*destroy)(struct r300_winsys_screen *ws);
|
||||
|
||||
/**
|
||||
* 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...).
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void *(*buffer_map)( struct r300_winsys_screen *ws,
|
||||
struct r300_winsys_buffer *buf,
|
||||
unsigned usage );
|
||||
|
||||
void (*buffer_unmap)( struct r300_winsys_screen *ws,
|
||||
struct r300_winsys_buffer *buf );
|
||||
|
||||
void (*buffer_destroy)( struct r300_winsys_buffer *buf );
|
||||
|
||||
|
||||
void (*buffer_reference)(struct r300_winsys_screen *rws,
|
||||
struct r300_winsys_buffer **pdst,
|
||||
struct r300_winsys_buffer *src);
|
||||
|
||||
boolean (*buffer_references)(struct r300_winsys_buffer *a,
|
||||
struct r300_winsys_buffer *b);
|
||||
|
||||
/* Add a pipe_buffer to the list of buffer objects to validate. */
|
||||
boolean (*add_buffer)(struct r300_winsys_screen *winsys,
|
||||
struct r300_winsys_buffer *buf,
|
||||
uint32_t rd,
|
||||
uint32_t wd);
|
||||
|
||||
/* Revalidate all currently setup pipe_buffers.
|
||||
* Returns TRUE if a flush is required. */
|
||||
boolean (*validate)(struct r300_winsys_screen* winsys);
|
||||
|
||||
/* Check to see if there's room for commands. */
|
||||
boolean (*check_cs)(struct r300_winsys_screen* winsys, int size);
|
||||
|
||||
/* Start a command emit. */
|
||||
void (*begin_cs)(struct r300_winsys_screen* winsys,
|
||||
int size,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line);
|
||||
|
||||
/* Write a dword to the command buffer. */
|
||||
void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword);
|
||||
|
||||
/* Write a relocated dword to the command buffer. */
|
||||
void (*write_cs_reloc)(struct r300_winsys_screen *winsys,
|
||||
struct r300_winsys_buffer *buf,
|
||||
uint32_t rd,
|
||||
uint32_t wd,
|
||||
uint32_t flags);
|
||||
|
||||
/* Finish a command emit. */
|
||||
void (*end_cs)(struct r300_winsys_screen* winsys,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line);
|
||||
|
||||
/* 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_set_tiling)(struct r300_winsys_screen *winsys,
|
||||
struct r300_winsys_buffer *buffer,
|
||||
uint32_t pitch,
|
||||
boolean microtiled,
|
||||
boolean macrotiled);
|
||||
|
||||
uint32_t (*get_value)(struct r300_winsys_screen *winsys,
|
||||
enum r300_value_id vid);
|
||||
};
|
||||
|
||||
struct r300_winsys_screen *
|
||||
r300_winsys_screen(struct pipe_screen *screen);
|
||||
|
||||
struct pipe_texture *r300_texture_blanket_winsys_buffer(struct pipe_screen *screen,
|
||||
const struct pipe_texture *base,
|
||||
const unsigned *stride,
|
||||
struct r300_winsys_buffer *buffer);
|
||||
#endif /* R300_WINSYS_H */
|
||||
|
|
|
@ -32,8 +32,6 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws)
|
|||
return (struct i965_libdrm_winsys *)iws;
|
||||
}
|
||||
|
||||
struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
|
||||
|
||||
void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ include $(TOP)/configs/current
|
|||
LIBNAME = radeonwinsys
|
||||
|
||||
C_SOURCES = \
|
||||
radeon_buffer.c \
|
||||
radeon_drm_buffer.c \
|
||||
radeon_drm.c \
|
||||
radeon_r300.c
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_inlines.h"
|
||||
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
@ -47,41 +47,41 @@
|
|||
|
||||
#include "radeon_winsys.h"
|
||||
|
||||
struct radeon_pipe_buffer {
|
||||
struct pipe_buffer base;
|
||||
/* Pointer to GPU-backed BO. */
|
||||
struct radeon_bo *bo;
|
||||
/* Pointer to fallback PB buffer. */
|
||||
struct pb_buffer *pb;
|
||||
boolean flinked;
|
||||
uint32_t flink;
|
||||
};
|
||||
|
||||
#define RADEON_MAX_BOS 24
|
||||
|
||||
struct radeon_winsys_priv {
|
||||
/* DRM FD */
|
||||
int fd;
|
||||
static INLINE struct pb_buffer *
|
||||
radeon_pb_buffer(struct r300_winsys_buffer *buffer)
|
||||
{
|
||||
return (struct pb_buffer *)buffer;
|
||||
}
|
||||
|
||||
/* Radeon BO manager. */
|
||||
struct radeon_bo_manager* bom;
|
||||
static INLINE struct r300_winsys_buffer *
|
||||
radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
|
||||
{
|
||||
return (struct r300_winsys_buffer *)buffer;
|
||||
}
|
||||
|
||||
/* Radeon CS manager. */
|
||||
struct radeon_cs_manager* csm;
|
||||
struct pb_manager *
|
||||
radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
|
||||
|
||||
/* Current CS. */
|
||||
struct radeon_cs* cs;
|
||||
boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
|
||||
uint32_t rd, uint32_t wd);
|
||||
|
||||
/* Flush CB */
|
||||
void (*flush_cb)(void *);
|
||||
void *flush_data;
|
||||
};
|
||||
|
||||
struct radeon_winsys* radeon_pipe_winsys(int fb);
|
||||
#if 0
|
||||
struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context,
|
||||
uint32_t handle,
|
||||
enum pipe_format format,
|
||||
int w, int h, int pitch);
|
||||
#endif
|
||||
void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
|
||||
uint32_t rd, uint32_t wd,
|
||||
uint32_t flags);
|
||||
|
||||
struct radeon_libdrm_winsys* radeon_pipe_winsys(int fd);
|
||||
|
||||
boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf,
|
||||
uint32_t *handle);
|
||||
uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf);
|
||||
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
|
||||
uint32_t handle);
|
||||
|
||||
void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch);
|
||||
|
||||
void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
|
||||
#endif
|
||||
|
|
|
@ -31,8 +31,22 @@
|
|||
|
||||
#include "radeon_drm.h"
|
||||
|
||||
static struct radeon_libdrm_winsys *
|
||||
radeon_winsys_create(int fd)
|
||||
{
|
||||
struct radeon_libdrm_winsys *rws;
|
||||
|
||||
rws = CALLOC_STRUCT(radeon_libdrm_winsys);
|
||||
if (rws == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rws->fd = fd;
|
||||
return rws;
|
||||
}
|
||||
|
||||
/* Helper function to do the ioctls needed for setup and init. */
|
||||
static void do_ioctls(int fd, struct radeon_winsys* winsys)
|
||||
static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
|
||||
{
|
||||
struct drm_radeon_gem_info gem_info = {0};
|
||||
struct drm_radeon_info info = {0};
|
||||
|
@ -123,62 +137,26 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
|
|||
int drmFB,
|
||||
struct drm_create_screen_arg *arg)
|
||||
{
|
||||
struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB);
|
||||
do_ioctls(drmFB, rwinsys);
|
||||
struct radeon_libdrm_winsys* rws;
|
||||
|
||||
rws = radeon_winsys_create(drmFB);
|
||||
if (!rws)
|
||||
return NULL;
|
||||
|
||||
do_ioctls(drmFB, rws);
|
||||
|
||||
/* The state tracker can organize a softpipe fallback if no hw
|
||||
* driver is found.
|
||||
*/
|
||||
if (is_r3xx(rwinsys->pci_id)) {
|
||||
radeon_setup_winsys(drmFB, rwinsys);
|
||||
return r300_create_screen(rwinsys);
|
||||
if (is_r3xx(rws->pci_id)) {
|
||||
radeon_setup_winsys(drmFB, rws);
|
||||
return r300_create_screen(&rws->base);
|
||||
} else {
|
||||
FREE(rwinsys);
|
||||
FREE(rws);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean radeon_buffer_from_texture(struct drm_api* api,
|
||||
struct pipe_screen* screen,
|
||||
struct pipe_texture* texture,
|
||||
struct pipe_buffer** buffer,
|
||||
unsigned* stride)
|
||||
{
|
||||
/* XXX fix this */
|
||||
return r300_get_texture_buffer(screen, texture, buffer, stride);
|
||||
}
|
||||
|
||||
/* Create a buffer from a handle. */
|
||||
/* XXX what's up with name? */
|
||||
struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
|
||||
struct pipe_screen* screen,
|
||||
const char* name,
|
||||
unsigned handle)
|
||||
{
|
||||
struct radeon_bo_manager* bom =
|
||||
((struct radeon_winsys*)screen->winsys)->priv->bom;
|
||||
struct radeon_pipe_buffer* radeon_buffer;
|
||||
struct radeon_bo* bo = NULL;
|
||||
|
||||
bo = radeon_bo_open(bom, handle, 0, 0, 0, 0);
|
||||
if (bo == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
|
||||
if (radeon_buffer == NULL) {
|
||||
radeon_bo_unref(bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pipe_reference_init(&radeon_buffer->base.reference, 1);
|
||||
radeon_buffer->base.screen = screen;
|
||||
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
|
||||
radeon_buffer->bo = bo;
|
||||
return &radeon_buffer->base;
|
||||
}
|
||||
|
||||
static struct pipe_texture*
|
||||
radeon_texture_from_shared_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
|
@ -187,18 +165,20 @@ radeon_texture_from_shared_handle(struct drm_api *api,
|
|||
unsigned stride,
|
||||
unsigned handle)
|
||||
{
|
||||
struct pipe_buffer *buffer;
|
||||
struct pb_buffer *_buf;
|
||||
struct r300_winsys_buffer *buf;
|
||||
struct pipe_texture *blanket;
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen));
|
||||
|
||||
buffer = radeon_buffer_from_handle(api, screen, name, handle);
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
_buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle);
|
||||
if (!_buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
blanket = screen->texture_blanket(screen, templ, &stride, buffer);
|
||||
|
||||
pipe_buffer_reference(&buffer, NULL);
|
||||
buf = radeon_libdrm_winsys_buffer(_buf);
|
||||
blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf);
|
||||
|
||||
pb_reference(&_buf, NULL);
|
||||
return blanket;
|
||||
}
|
||||
|
||||
|
@ -208,34 +188,14 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api,
|
|||
unsigned *stride,
|
||||
unsigned *handle)
|
||||
{
|
||||
int retval, fd;
|
||||
struct drm_gem_flink flink;
|
||||
struct radeon_pipe_buffer* radeon_buffer;
|
||||
struct pipe_buffer *buffer = NULL;
|
||||
|
||||
if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
|
||||
struct r300_winsys_buffer *radeon_buffer;
|
||||
struct pb_buffer *_buf;
|
||||
if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
radeon_buffer = (struct radeon_pipe_buffer*)buffer;
|
||||
if (!radeon_buffer->flinked) {
|
||||
fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
|
||||
|
||||
flink.handle = radeon_buffer->bo->handle;
|
||||
|
||||
retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||
if (retval) {
|
||||
debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
|
||||
retval);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
radeon_buffer->flink = flink.name;
|
||||
radeon_buffer->flinked = TRUE;
|
||||
}
|
||||
|
||||
*handle = radeon_buffer->flink;
|
||||
return TRUE;
|
||||
_buf = radeon_pb_buffer(radeon_buffer);
|
||||
return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle);
|
||||
}
|
||||
|
||||
static boolean radeon_local_handle_from_texture(struct drm_api *api,
|
||||
|
@ -244,16 +204,18 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api,
|
|||
unsigned *stride,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct pipe_buffer *buffer = NULL;
|
||||
if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
|
||||
struct r300_winsys_buffer *radeon_buffer;
|
||||
struct pb_buffer *_buf;
|
||||
|
||||
if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
|
||||
_buf = radeon_pb_buffer(radeon_buffer);
|
||||
*handle = radeon_drm_bufmgr_handle_from_buffer(_buf);
|
||||
|
||||
pipe_buffer_reference(&buffer, NULL);
|
||||
|
||||
return TRUE;
|
||||
pb_reference(&_buf, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_drm_api_destroy(struct drm_api *api)
|
||||
|
|
|
@ -59,11 +59,6 @@ boolean radeon_buffer_from_texture(struct drm_api* api,
|
|||
struct pipe_buffer** buffer,
|
||||
unsigned* stride);
|
||||
|
||||
struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
|
||||
struct pipe_screen* screen,
|
||||
const char* name,
|
||||
unsigned handle);
|
||||
|
||||
boolean radeon_handle_from_buffer(struct drm_api* api,
|
||||
struct pipe_screen* screen,
|
||||
struct pipe_buffer* buffer,
|
||||
|
|
|
@ -0,0 +1,361 @@
|
|||
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_bo_gem.h"
|
||||
#include "radeon_cs_gem.h"
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_list.h"
|
||||
#include "pipebuffer/pb_buffer.h"
|
||||
#include "pipebuffer/pb_bufmgr.h"
|
||||
|
||||
#include "radeon_winsys.h"
|
||||
struct radeon_drm_bufmgr;
|
||||
|
||||
struct radeon_drm_buffer {
|
||||
struct pb_buffer base;
|
||||
struct radeon_drm_bufmgr *mgr;
|
||||
|
||||
struct radeon_bo *bo;
|
||||
|
||||
boolean flinked;
|
||||
uint32_t flink;
|
||||
|
||||
boolean mapped;
|
||||
struct radeon_drm_buffer *next, *prev;
|
||||
};
|
||||
|
||||
extern const struct pb_vtbl radeon_drm_buffer_vtbl;
|
||||
|
||||
|
||||
static INLINE struct radeon_drm_buffer *
|
||||
radeon_drm_buffer(struct pb_buffer *buf)
|
||||
{
|
||||
assert(buf);
|
||||
assert(buf->vtbl == &radeon_drm_buffer_vtbl);
|
||||
return (struct radeon_drm_buffer *)buf;
|
||||
}
|
||||
|
||||
struct radeon_drm_bufmgr {
|
||||
struct pb_manager base;
|
||||
struct radeon_libdrm_winsys *rws;
|
||||
struct radeon_drm_buffer buffer_map_list;
|
||||
};
|
||||
|
||||
static INLINE struct radeon_drm_bufmgr *
|
||||
radeon_drm_bufmgr(struct pb_manager *mgr)
|
||||
{
|
||||
assert(mgr);
|
||||
return (struct radeon_drm_bufmgr *)mgr;
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_buffer_destroy(struct pb_buffer *_buf)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
|
||||
|
||||
if (buf->mapped) {
|
||||
remove_from_list(buf);
|
||||
radeon_bo_unmap(buf->bo);
|
||||
buf->mapped = false;
|
||||
}
|
||||
radeon_bo_unref(buf->bo);
|
||||
|
||||
FREE(buf);
|
||||
}
|
||||
|
||||
static void *
|
||||
radeon_drm_buffer_map(struct pb_buffer *_buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
|
||||
int write;
|
||||
|
||||
if (flags & PIPE_BUFFER_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 (buf->mapped)
|
||||
return buf->bo->ptr;
|
||||
|
||||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
|
||||
write = 1;
|
||||
}
|
||||
|
||||
if (radeon_bo_map(buf->bo, write)) {
|
||||
return NULL;
|
||||
}
|
||||
buf->mapped = true;
|
||||
insert_at_tail(&buf->mgr->buffer_map_list, buf);
|
||||
return buf->bo->ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_buffer_unmap(struct pb_buffer *_buf)
|
||||
{
|
||||
(void)_buf;
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf,
|
||||
struct pb_buffer **base_buf,
|
||||
unsigned *offset)
|
||||
{
|
||||
*base_buf = buf;
|
||||
*offset = 0;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
radeon_drm_buffer_validate(struct pb_buffer *_buf,
|
||||
struct pb_validate *vl,
|
||||
unsigned flags)
|
||||
{
|
||||
/* Always pinned */
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_buffer_fence(struct pb_buffer *buf,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
}
|
||||
|
||||
const struct pb_vtbl radeon_drm_buffer_vtbl = {
|
||||
radeon_drm_buffer_destroy,
|
||||
radeon_drm_buffer_map,
|
||||
radeon_drm_buffer_unmap,
|
||||
radeon_drm_buffer_validate,
|
||||
radeon_drm_buffer_fence,
|
||||
radeon_drm_buffer_get_base_buffer,
|
||||
};
|
||||
|
||||
|
||||
static uint32_t radeon_domain_from_usage(unsigned usage)
|
||||
{
|
||||
uint32_t domain = 0;
|
||||
|
||||
if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
|
||||
domain |= RADEON_GEM_DOMAIN_VRAM;
|
||||
}
|
||||
if (usage & PIPE_BUFFER_USAGE_PIXEL) {
|
||||
domain |= RADEON_GEM_DOMAIN_VRAM;
|
||||
}
|
||||
if (usage & PIPE_BUFFER_USAGE_VERTEX) {
|
||||
domain |= RADEON_GEM_DOMAIN_GTT;
|
||||
}
|
||||
if (usage & PIPE_BUFFER_USAGE_INDEX) {
|
||||
domain |= RADEON_GEM_DOMAIN_GTT;
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
|
||||
uint32_t handle)
|
||||
{
|
||||
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
|
||||
struct radeon_libdrm_winsys *rws = mgr->rws;
|
||||
struct radeon_drm_buffer *buf;
|
||||
struct radeon_bo *bo;
|
||||
|
||||
bo = radeon_bo_open(rws->bom, handle, 0,
|
||||
0, 0, 0);
|
||||
if (bo == NULL)
|
||||
return NULL;
|
||||
|
||||
buf = CALLOC_STRUCT(radeon_drm_buffer);
|
||||
if (!buf) {
|
||||
radeon_bo_unref(bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
make_empty_list(buf);
|
||||
|
||||
pipe_reference_init(&buf->base.base.reference, 1);
|
||||
buf->base.base.alignment = 0;
|
||||
buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL;
|
||||
buf->base.base.size = 0;
|
||||
buf->base.vtbl = &radeon_drm_buffer_vtbl;
|
||||
buf->mgr = mgr;
|
||||
|
||||
buf->bo = bo;
|
||||
|
||||
// fprintf(stderr,"hand %p : %d\n", &buf->base, handle);
|
||||
return &buf->base;
|
||||
|
||||
}
|
||||
|
||||
static struct pb_buffer *
|
||||
radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
|
||||
pb_size size,
|
||||
const struct pb_desc *desc)
|
||||
{
|
||||
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
|
||||
struct radeon_libdrm_winsys *rws = mgr->rws;
|
||||
struct radeon_drm_buffer *buf;
|
||||
uint32_t domain;
|
||||
|
||||
buf = CALLOC_STRUCT(radeon_drm_buffer);
|
||||
if (!buf)
|
||||
goto error1;
|
||||
|
||||
pipe_reference_init(&buf->base.base.reference, 1);
|
||||
buf->base.base.alignment = desc->alignment;
|
||||
buf->base.base.usage = desc->usage;
|
||||
buf->base.base.size = size;
|
||||
buf->base.vtbl = &radeon_drm_buffer_vtbl;
|
||||
buf->mgr = mgr;
|
||||
|
||||
make_empty_list(buf);
|
||||
domain = radeon_domain_from_usage(desc->usage);
|
||||
buf->bo = radeon_bo_open(rws->bom, 0, size,
|
||||
desc->alignment, domain, 0);
|
||||
if (buf->bo == NULL)
|
||||
goto error2;
|
||||
|
||||
// fprintf(stderr,"%p : %d\n", &buf->base, size);
|
||||
return &buf->base;
|
||||
|
||||
error2:
|
||||
FREE(buf);
|
||||
error1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_bufmgr_flush(struct pb_manager *mgr)
|
||||
{
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
static void
|
||||
radeon_drm_bufmgr_destroy(struct pb_manager *_mgr)
|
||||
{
|
||||
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
|
||||
FREE(mgr);
|
||||
}
|
||||
|
||||
struct pb_manager *
|
||||
radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
|
||||
{
|
||||
struct radeon_drm_bufmgr *mgr;
|
||||
|
||||
mgr = CALLOC_STRUCT(radeon_drm_bufmgr);
|
||||
if (!mgr)
|
||||
return NULL;
|
||||
|
||||
mgr->base.destroy = radeon_drm_bufmgr_destroy;
|
||||
mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer;
|
||||
mgr->base.flush = radeon_drm_bufmgr_flush;
|
||||
|
||||
mgr->rws = rws;
|
||||
make_empty_list(&mgr->buffer_map_list);
|
||||
return &mgr->base;
|
||||
}
|
||||
|
||||
uint32_t radeon_drm_bufmgr_handle_from_buffer(struct pb_buffer *_buf)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
|
||||
|
||||
return buf->bo->handle;
|
||||
}
|
||||
|
||||
boolean radeon_drm_bufmgr_shared_handle_from_buffer(struct pb_buffer *_buf,
|
||||
uint32_t *handle)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
|
||||
struct drm_gem_flink flink;
|
||||
int retval, fd;
|
||||
if (!buf->flinked) {
|
||||
fd = buf->mgr->rws->fd;
|
||||
flink.handle = buf->bo->handle;
|
||||
|
||||
retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
|
||||
if (retval) {
|
||||
return false;
|
||||
}
|
||||
|
||||
buf->flinked = TRUE;
|
||||
buf->flink = flink.name;
|
||||
}
|
||||
*handle = buf->flink;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
|
||||
{
|
||||
struct radeon_drm_buffer *buf;
|
||||
if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
|
||||
buf = radeon_drm_buffer(_buf);
|
||||
} else {
|
||||
struct pb_buffer *base_buf;
|
||||
pb_size offset;
|
||||
pb_get_base_buffer(_buf, &base_buf, &offset);
|
||||
|
||||
buf = radeon_drm_buffer(base_buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf, boolean microtiled, boolean macrotiled, uint32_t pitch)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (microtiled)
|
||||
flags |= RADEON_BO_FLAGS_MICRO_TILE;
|
||||
if (macrotiled)
|
||||
flags |= RADEON_BO_FLAGS_MACRO_TILE;
|
||||
|
||||
radeon_bo_set_tiling(buf->bo, flags, pitch);
|
||||
|
||||
}
|
||||
|
||||
boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
|
||||
uint32_t rd, uint32_t wd)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
|
||||
radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
|
||||
rd, wd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
|
||||
uint32_t rd, uint32_t wd,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
|
||||
int retval;
|
||||
|
||||
retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
|
||||
buf->bo, rd, wd, flags);
|
||||
if (retval) {
|
||||
debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
|
||||
buf, rd, wd, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
|
||||
{
|
||||
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
|
||||
struct radeon_drm_buffer *rpb, *t_rpb;
|
||||
|
||||
foreach_s(rpb, t_rpb, &mgr->buffer_map_list) {
|
||||
rpb->mapped = 0;
|
||||
radeon_bo_unmap(rpb->bo);
|
||||
remove_from_list(rpb);
|
||||
}
|
||||
|
||||
make_empty_list(&mgr->buffer_map_list);
|
||||
|
||||
|
||||
}
|
|
@ -22,29 +22,104 @@
|
|||
|
||||
#include "radeon_r300.h"
|
||||
|
||||
static void radeon_set_flush_cb(struct radeon_winsys *winsys,
|
||||
static struct r300_winsys_buffer *
|
||||
radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
struct pb_desc desc;
|
||||
struct pb_manager *provider;
|
||||
struct pb_buffer *buffer;
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.alignment = alignment;
|
||||
desc.usage = usage;
|
||||
|
||||
if (usage == PIPE_BUFFER_USAGE_CONSTANT)
|
||||
provider = ws->mman;
|
||||
else if (usage == PIPE_BUFFER_USAGE_VERTEX ||
|
||||
usage == PIPE_BUFFER_USAGE_INDEX)
|
||||
provider = ws->cman;
|
||||
else
|
||||
provider = ws->kman;
|
||||
buffer = provider->create_buffer(provider, size, &desc);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
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,
|
||||
boolean microtiled,
|
||||
boolean macrotiled)
|
||||
{
|
||||
struct pb_buffer *_buf = radeon_pb_buffer(buf);
|
||||
radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
|
||||
}
|
||||
|
||||
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, 0);
|
||||
}
|
||||
|
||||
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_reference(struct r300_winsys_screen *rws,
|
||||
struct r300_winsys_buffer **pdst,
|
||||
struct r300_winsys_buffer *src)
|
||||
{
|
||||
struct pb_buffer *_src = radeon_pb_buffer(src);
|
||||
struct pb_buffer *_dst = radeon_pb_buffer(*pdst);
|
||||
|
||||
pb_reference(&_dst, _src);
|
||||
|
||||
*pdst = radeon_libdrm_winsys_buffer(_dst);
|
||||
}
|
||||
|
||||
static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
|
||||
void (*flush_cb)(void *),
|
||||
void *data)
|
||||
{
|
||||
winsys->priv->flush_cb = flush_cb;
|
||||
winsys->priv->flush_data = data;
|
||||
radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, 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 radeon_winsys* winsys,
|
||||
struct pipe_buffer* pbuffer,
|
||||
static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
|
||||
struct r300_winsys_buffer *buf,
|
||||
uint32_t rd,
|
||||
uint32_t wd)
|
||||
{
|
||||
struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
|
||||
struct pb_buffer *_buf = radeon_pb_buffer(buf);
|
||||
|
||||
radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd);
|
||||
return TRUE;
|
||||
return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
|
||||
}
|
||||
|
||||
static boolean radeon_validate(struct radeon_winsys* winsys)
|
||||
static boolean radeon_validate(struct r300_winsys_screen *rws)
|
||||
{
|
||||
if (radeon_cs_space_check(winsys->priv->cs) < 0) {
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
if (radeon_cs_space_check(ws->cs) < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -52,108 +127,146 @@ static boolean radeon_validate(struct radeon_winsys* winsys)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean radeon_check_cs(struct radeon_winsys* winsys, int size)
|
||||
static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size)
|
||||
{
|
||||
struct radeon_cs* cs = winsys->priv->cs;
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
struct radeon_cs *cs = ws->cs;
|
||||
|
||||
return radeon_validate(winsys) && cs->cdw + size <= cs->ndw;
|
||||
return radeon_validate(rws) && cs->cdw + size <= cs->ndw;
|
||||
}
|
||||
|
||||
static void radeon_begin_cs(struct radeon_winsys* winsys,
|
||||
static void radeon_begin_cs(struct r300_winsys_screen *rws,
|
||||
int size,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line)
|
||||
{
|
||||
radeon_cs_begin(winsys->priv->cs, size, file, function, line);
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
radeon_cs_begin(ws->cs, size, file, function, line);
|
||||
}
|
||||
|
||||
static void radeon_write_cs_dword(struct radeon_winsys* winsys,
|
||||
static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
|
||||
uint32_t dword)
|
||||
{
|
||||
radeon_cs_write_dword(winsys->priv->cs, dword);
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
radeon_cs_write_dword(ws->cs, dword);
|
||||
}
|
||||
|
||||
static void radeon_write_cs_reloc(struct radeon_winsys* winsys,
|
||||
struct pipe_buffer* pbuffer,
|
||||
static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
|
||||
struct r300_winsys_buffer *buf,
|
||||
uint32_t rd,
|
||||
uint32_t wd,
|
||||
uint32_t flags)
|
||||
{
|
||||
int retval = 0;
|
||||
struct radeon_pipe_buffer* radeon_buffer =
|
||||
(struct radeon_pipe_buffer*)pbuffer;
|
||||
|
||||
assert(!radeon_buffer->pb);
|
||||
|
||||
retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo,
|
||||
rd, wd, flags);
|
||||
|
||||
if (retval) {
|
||||
debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
|
||||
pbuffer, rd, wd, flags);
|
||||
}
|
||||
struct pb_buffer *_buf = radeon_pb_buffer(buf);
|
||||
radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
|
||||
}
|
||||
|
||||
static void radeon_reset_bos(struct radeon_winsys *winsys)
|
||||
static void radeon_reset_bos(struct r300_winsys_screen *rws)
|
||||
{
|
||||
radeon_cs_space_reset_bos(winsys->priv->cs);
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
radeon_cs_space_reset_bos(ws->cs);
|
||||
}
|
||||
|
||||
static void radeon_end_cs(struct radeon_winsys* winsys,
|
||||
static void radeon_end_cs(struct r300_winsys_screen *rws,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line)
|
||||
{
|
||||
radeon_cs_end(winsys->priv->cs, file, function, line);
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
radeon_cs_end(ws->cs, file, function, line);
|
||||
}
|
||||
|
||||
static void radeon_flush_cs(struct radeon_winsys* winsys)
|
||||
static void radeon_flush_cs(struct r300_winsys_screen *rws)
|
||||
{
|
||||
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
|
||||
int retval;
|
||||
|
||||
/* Don't flush a zero-sized CS. */
|
||||
if (!winsys->priv->cs->cdw) {
|
||||
if (!ws->cs->cdw) {
|
||||
return;
|
||||
}
|
||||
|
||||
radeon_drm_bufmgr_flush_maps(ws->kman);
|
||||
/* Emit the CS. */
|
||||
retval = radeon_cs_emit(winsys->priv->cs);
|
||||
retval = radeon_cs_emit(ws->cs);
|
||||
if (retval) {
|
||||
debug_printf("radeon: Bad CS, dumping...\n");
|
||||
radeon_cs_print(winsys->priv->cs, stderr);
|
||||
radeon_cs_print(ws->cs, stderr);
|
||||
}
|
||||
|
||||
/* Reset CS.
|
||||
* 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(winsys->priv->cs);
|
||||
radeon_cs_erase(ws->cs);
|
||||
}
|
||||
|
||||
static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
|
||||
enum r300_value_id id)
|
||||
{
|
||||
struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
|
||||
|
||||
switch(id) {
|
||||
case R300_VID_PCI_ID:
|
||||
return ws->pci_id;
|
||||
case R300_VID_GB_PIPES:
|
||||
return ws->gb_pipes;
|
||||
case R300_VID_Z_PIPES:
|
||||
return ws->z_pipes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
ws->mman->destroy(ws->mman);
|
||||
|
||||
radeon_bo_manager_gem_dtor(ws->bom);
|
||||
radeon_cs_manager_gem_dtor(ws->csm);
|
||||
}
|
||||
|
||||
void
|
||||
radeon_setup_winsys(int fd, struct radeon_winsys* winsys)
|
||||
radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
|
||||
{
|
||||
struct radeon_winsys_priv* priv = winsys->priv;
|
||||
ws->csm = radeon_cs_manager_gem_ctor(fd);
|
||||
|
||||
priv->csm = radeon_cs_manager_gem_ctor(fd);
|
||||
ws->bom = radeon_bo_manager_gem_ctor(fd);
|
||||
ws->kman = radeon_drm_bufmgr_create(ws);
|
||||
|
||||
ws->cman = pb_cache_manager_create(ws->kman, 100000);
|
||||
ws->mman = pb_malloc_bufmgr_create();
|
||||
|
||||
/* Size limit on IBs is 64 kibibytes. */
|
||||
priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4);
|
||||
radeon_cs_set_limit(priv->cs,
|
||||
RADEON_GEM_DOMAIN_GTT, winsys->gart_size);
|
||||
radeon_cs_set_limit(priv->cs,
|
||||
RADEON_GEM_DOMAIN_VRAM, winsys->vram_size);
|
||||
ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
|
||||
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);
|
||||
|
||||
winsys->add_buffer = radeon_add_buffer;
|
||||
winsys->validate = radeon_validate;
|
||||
ws->base.add_buffer = radeon_add_buffer;
|
||||
ws->base.validate = radeon_validate;
|
||||
ws->base.destroy = radeon_winsys_destroy;
|
||||
ws->base.check_cs = radeon_check_cs;
|
||||
ws->base.begin_cs = radeon_begin_cs;
|
||||
ws->base.write_cs_dword = radeon_write_cs_dword;
|
||||
ws->base.write_cs_reloc = radeon_write_cs_reloc;
|
||||
ws->base.end_cs = radeon_end_cs;
|
||||
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;
|
||||
|
||||
winsys->check_cs = radeon_check_cs;
|
||||
winsys->begin_cs = radeon_begin_cs;
|
||||
winsys->write_cs_dword = radeon_write_cs_dword;
|
||||
winsys->write_cs_reloc = radeon_write_cs_reloc;
|
||||
winsys->end_cs = radeon_end_cs;
|
||||
winsys->flush_cs = radeon_flush_cs;
|
||||
winsys->reset_bos = radeon_reset_bos;
|
||||
winsys->set_flush_cb = radeon_set_flush_cb;
|
||||
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_map = radeon_r300_winsys_buffer_map;
|
||||
ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
|
||||
ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include <stdlib.h>
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_bo_gem.h"
|
||||
#include "radeon_cs_gem.h"
|
||||
|
||||
#include "r300_winsys.h"
|
||||
|
||||
#include "radeon_winsys.h"
|
||||
#include "radeon_buffer.h"
|
||||
|
||||
void radeon_setup_winsys(int fd, struct radeon_winsys* winsys);
|
||||
void radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys);
|
||||
|
||||
#endif /* RADEON_R300_H */
|
||||
|
|
|
@ -30,16 +30,17 @@
|
|||
#ifndef RADEON_WINSYS_H
|
||||
#define RADEON_WINSYS_H
|
||||
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "r300_winsys.h"
|
||||
|
||||
struct radeon_winsys_priv;
|
||||
|
||||
struct radeon_winsys {
|
||||
struct radeon_libdrm_winsys {
|
||||
/* Parent class. */
|
||||
struct pipe_winsys base;
|
||||
struct r300_winsys_screen base;
|
||||
|
||||
/* Winsys private */
|
||||
struct radeon_winsys_priv* priv;
|
||||
struct pb_manager *kman;
|
||||
|
||||
struct pb_manager *mman;
|
||||
|
||||
struct pb_manager *cman;
|
||||
|
||||
/* PCI ID */
|
||||
uint32_t pci_id;
|
||||
|
@ -56,56 +57,27 @@ struct radeon_winsys {
|
|||
/* VRAM size. */
|
||||
uint32_t vram_size;
|
||||
|
||||
/* Add a pipe_buffer to the list of buffer objects to validate. */
|
||||
boolean (*add_buffer)(struct radeon_winsys* winsys,
|
||||
struct pipe_buffer* pbuffer,
|
||||
uint32_t rd,
|
||||
uint32_t wd);
|
||||
/* DRM FD */
|
||||
int fd;
|
||||
|
||||
/* Revalidate all currently setup pipe_buffers.
|
||||
* Returns TRUE if a flush is required. */
|
||||
boolean (*validate)(struct radeon_winsys* winsys);
|
||||
/* Radeon BO manager. */
|
||||
struct radeon_bo_manager *bom;
|
||||
|
||||
/* Check to see if there's room for commands. */
|
||||
boolean (*check_cs)(struct radeon_winsys* winsys, int size);
|
||||
/* Radeon CS manager. */
|
||||
struct radeon_cs_manager *csm;
|
||||
|
||||
/* Start a command emit. */
|
||||
void (*begin_cs)(struct radeon_winsys* winsys,
|
||||
int size,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line);
|
||||
/* Current CS. */
|
||||
struct radeon_cs *cs;
|
||||
|
||||
/* Write a dword to the command buffer. */
|
||||
void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword);
|
||||
|
||||
/* Write a relocated dword to the command buffer. */
|
||||
void (*write_cs_reloc)(struct radeon_winsys* winsys,
|
||||
struct pipe_buffer* bo,
|
||||
uint32_t rd,
|
||||
uint32_t wd,
|
||||
uint32_t flags);
|
||||
|
||||
/* Finish a command emit. */
|
||||
void (*end_cs)(struct radeon_winsys* winsys,
|
||||
const char* file,
|
||||
const char* function,
|
||||
int line);
|
||||
|
||||
/* Flush the CS. */
|
||||
void (*flush_cs)(struct radeon_winsys* winsys);
|
||||
|
||||
/* winsys flush - callback from winsys when flush required */
|
||||
void (*set_flush_cb)(struct radeon_winsys *winsys,
|
||||
void (*flush_cb)(void *), void *data);
|
||||
|
||||
void (*reset_bos)(struct radeon_winsys *winsys);
|
||||
|
||||
void (*buffer_set_tiling)(struct radeon_winsys* winsys,
|
||||
struct pipe_buffer* buffer,
|
||||
uint32_t pitch,
|
||||
boolean microtiled,
|
||||
boolean macrotiled);
|
||||
/* Flush CB */
|
||||
void (*flush_cb)(void *);
|
||||
void *flush_data;
|
||||
};
|
||||
|
||||
static INLINE struct radeon_libdrm_winsys *
|
||||
radeon_winsys_screen(struct r300_winsys_screen *base)
|
||||
{
|
||||
return (struct radeon_libdrm_winsys *)base;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue