| @@ -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", \ | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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 */ | |||
| @@ -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. */ | |||
| @@ -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. */ | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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. */ | |||
| /** | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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) { | |||
| @@ -1,5 +1,6 @@ | |||
| /* | |||
| * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
| * Copyright 2010 Marek Olšák <maraeo@gmail.com> | |||
| * | |||
| * 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 */ | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||