From e5d5dab8c03f72097ec3e5b465fe93b6e369bb2d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 5 Nov 2008 14:31:46 +0100 Subject: r300: bo and cs abstraction. This abstract memory management and command stream building so we can use different backend either legacy one which use old pathway or a new one like with a new memory manager. This works was done by : Nicolai Haehnle Dave Airlie Jerome Glisse --- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/mesa/drivers/dri/radeon/radeon_cs_legacy.h (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h new file mode 100644 index 0000000000..6ab384e978 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2008 Nicolai Haehnle + * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Aapo Tahkola + * Nicolai Haehnle + * Jérôme Glisse + */ +#ifndef RADEON_CS_LEGACY_H +#define RADEON_CS_LEGACY_H + +#include "radeon_cs.h" +#include "radeon_context.h" + +struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx); + +#endif -- cgit v1.2.3 From 3b43c28195ffce79822728b546a707ee14a03320 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 9 Nov 2008 19:00:28 +0100 Subject: r300: cs + DRI2 support If DRI2 is enabled then switch cmd assembly to directly build hw packet. --- src/mesa/drivers/dri/r300/Makefile | 4 +- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 311 ++++++++++++++++--------- src/mesa/drivers/dri/r300/r300_cmdbuf.h | 7 + src/mesa/drivers/dri/r300/r300_context.h | 2 +- src/mesa/drivers/dri/r300/r300_emit.c | 15 +- src/mesa/drivers/dri/r300/r300_emit.h | 105 ++++++--- src/mesa/drivers/dri/r300/r300_ioctl.c | 101 +++++--- src/mesa/drivers/dri/r300/r300_mipmap_tree.c | 5 +- src/mesa/drivers/dri/r300/r300_render.c | 62 ++++- src/mesa/drivers/dri/r300/r300_state.c | 65 +++--- src/mesa/drivers/dri/r300/r300_swtcl.c | 2 +- src/mesa/drivers/dri/r300/radeon_context.c | 139 ++++++++++- src/mesa/drivers/dri/r300/radeon_context.h | 1 + src/mesa/drivers/dri/r300/radeon_lock.h | 4 + src/mesa/drivers/dri/r300/radeon_span.c | 241 ++++++++++++------- src/mesa/drivers/dri/r300/radeon_state.c | 2 + src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 22 +- src/mesa/drivers/dri/radeon/radeon_buffer.h | 3 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 40 +++- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 1 + src/mesa/drivers/dri/radeon/radeon_screen.c | 174 +++++++++++--- 21 files changed, 958 insertions(+), 348 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index f1141523c0..c041bc6ad0 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -57,8 +57,8 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \ -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \ -# -DRADEON_BO_TRACK_OPEN \ # -DRADEON_BO_TRACK_REF \ +# -DRADEON_BO_TRACK_OPEN \ -Wall SYMLINKS = \ @@ -80,6 +80,8 @@ COMMON_SYMLINKS = \ radeon_bo_legacy.h \ radeon_cs_legacy.h +DRI_LIB_DEPS += -ldrm_radeon + ##### TARGETS ##### include ../Makefile.template diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 7d7fed4e5d..dbb7761b3b 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -55,6 +55,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_mipmap_tree.h" #include "r300_state.h" #include "radeon_cs_legacy.h" +#include "radeon_cs_gem.h" +#include "radeon_reg.h" + +#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 +# define RADEON_ONE_REG_WR (1 << 15) // Set this to 1 for extremely verbose debugging of command buffers #define DEBUG_CMDBUF 0 @@ -106,8 +111,6 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) */ void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller) { - assert(dwords < r300->cmdbuf.size); - if ((r300->cmdbuf.cs->cdw + dwords + 128) > r300->cmdbuf.size || radeon_cs_need_flush(r300->cmdbuf.cs)) { r300FlushCmdBuf(r300, caller); @@ -157,12 +160,12 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) struct r300_state_atom *atom; int dwords; - BEGIN_BATCH_NO_AUTOSTATE(4); - OUT_BATCH(cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN)); - OUT_BATCH(cmdpacket0(R300_TX_INVALTAGS, 1)); + cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN); + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH(cmdpacket0(r300->radeon.radeonScreen, R300_TX_INVALTAGS, 1)); OUT_BATCH(R300_TX_FLUSH); - OUT_BATCH(cmdpacify()); END_BATCH(); + end_3d(r300); /* Emit actual atoms */ foreach(atom, &r300->hw.atomlist) { @@ -173,7 +176,7 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) r300PrintStateAtom(r300, atom); } if (atom->emit) { - (*atom->emit)(r300); + (*atom->emit)(r300, atom); } else { BEGIN_BATCH_NO_AUTOSTATE(dwords); OUT_BATCH_TABLE(atom->cmd, dwords); @@ -227,14 +230,62 @@ void r300EmitState(r300ContextPtr r300) r300->hw.all_dirty = GL_FALSE; } -#define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count) +static unsigned packet0_count(r300ContextPtr r300, uint32_t *pkt) +{ + if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { + return ((((*pkt) >> 16) & 0x3FFF) + 1); + } else { + drm_r300_cmd_header_t *t = (drm_r300_cmd_header_t*)pkt; + return t->packet0.count; + } + return 0; +} + #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) #define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count) -static void emit_tex_offsets(r300ContextPtr r300) +void emit_vpu(r300ContextPtr r300, struct r300_state_atom * atom) +{ + BATCH_LOCALS(r300); + drm_r300_cmd_header_t cmd; + uint32_t addr, ndw, i; + + if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { + uint32_t dwords; + dwords = (*atom->check) (r300, atom); + BEGIN_BATCH_NO_AUTOSTATE(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + return; + } + + cmd.u = atom->cmd[0]; + addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo; + ndw = cmd.vpu.count * 4; + if (ndw) { + /* flush processing vertices */ + OUT_BATCH(CP_PACKET0(R300_SC_SCREENDOOR, 0)); + OUT_BATCH(0x0); + OUT_BATCH(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); + OUT_BATCH((1 << 15) | (1 << 28)); + OUT_BATCH(CP_PACKET0(R300_SC_SCREENDOOR, 0)); + OUT_BATCH(0x00FFFFFF); + OUT_BATCH(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0)); + OUT_BATCH(1); + /* write vpu */ + OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_ADDRESS, 0)); + OUT_BATCH(addr); + OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR); + for (i = 0; i < ndw; i++) { + OUT_BATCH(atom->cmd[i+1]); + } + } +} + +static void emit_tex_offsets(r300ContextPtr r300, struct r300_state_atom * atom) { BATCH_LOCALS(r300); - int numtmus = packet0_count(r300->hw.tex.offset.cmd); + int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd); if (numtmus) { int i; @@ -255,19 +306,23 @@ static void emit_tex_offsets(r300ContextPtr r300) } } -static void emit_cb_offset(r300ContextPtr r300) +static void emit_cb_offset(r300ContextPtr r300, struct r300_state_atom * atom) { BATCH_LOCALS(r300); struct radeon_renderbuffer *rrb; uint32_t cbpitch; + GLframebuffer *fb = r300->radeon.dri.drawable->driverPrivate; rrb = r300->radeon.state.color.rrb; + if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { + rrb = fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + } if (!rrb) { fprintf(stderr, "no rrb\n"); return; } - cbpitch = rrb->pitch; + cbpitch = (rrb->pitch / rrb->cpp); if (rrb->cpp == 4) cbpitch |= R300_COLOR_FORMAT_ARGB8888; else @@ -284,7 +339,7 @@ static void emit_cb_offset(r300ContextPtr r300) END_BATCH(); } -static void emit_zb_offset(r300ContextPtr r300) +static void emit_zb_offset(r300ContextPtr r300, struct r300_state_atom * atom) { BATCH_LOCALS(r300); struct radeon_renderbuffer *rrb; @@ -294,11 +349,11 @@ static void emit_zb_offset(r300ContextPtr r300) if (!rrb) return; - zbpitch = rrb->pitch; + zbpitch = (rrb->pitch / rrb->cpp); if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { zbpitch |= R300_DEPTHMACROTILE_ENABLE; } - if (r300->radeon.glCtx->Visual.depthBits == 24) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ zbpitch |= R300_DEPTHMICROTILE_TILED; } @@ -317,13 +372,17 @@ static int check_always(r300ContextPtr r300, struct r300_state_atom *atom) static int check_variable(r300ContextPtr r300, struct r300_state_atom *atom) { int cnt; - cnt = packet0_count(atom->cmd); + if (atom->cmd[0] == CP_PACKET2) { + return 0; + } + cnt = packet0_count(r300, atom->cmd); return cnt ? cnt + 1 : 0; } -static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) +int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) { int cnt; + cnt = vpu_count(atom->cmd); return cnt ? (cnt * 4) + 1 : 0; } @@ -331,6 +390,7 @@ static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) { int cnt; + cnt = r500fp_count(atom->cmd); return cnt ? (cnt * 6) + 1 : 0; } @@ -338,7 +398,8 @@ static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) { int cnt; - cnt = r500fp_count(atom->cmd); + + cnt = r500fp_count(atom->cmd); return cnt ? (cnt * 4) + 1 : 0; } @@ -383,92 +444,92 @@ void r300InitCmdBuf(r300ContextPtr r300) /* Initialize state atoms */ ALLOC_STATE(vpt, always, R300_VPT_CMDSIZE, 0); - r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(R300_SE_VPORT_XSCALE, 6); + r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VPORT_XSCALE, 6); ALLOC_STATE(vap_cntl, always, R300_VAP_CNTL_SIZE, 0); - r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(R300_VAP_PVS_STATE_FLUSH_REG, 1); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0; - r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(R300_VAP_CNTL, 1); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL, 1); if (is_r500) { ALLOC_STATE(vap_index_offset, always, 2, 0); - r300->hw.vap_index_offset.cmd[0] = cmdpacket0(R500_VAP_INDEX_OFFSET, 1); + r300->hw.vap_index_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_VAP_INDEX_OFFSET, 1); r300->hw.vap_index_offset.cmd[1] = 0; } ALLOC_STATE(vte, always, 3, 0); - r300->hw.vte.cmd[0] = cmdpacket0(R300_SE_VTE_CNTL, 2); + r300->hw.vte.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SE_VTE_CNTL, 2); ALLOC_STATE(vap_vf_max_vtx_indx, always, 3, 0); - r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(R300_VAP_VF_MAX_VTX_INDX, 2); + r300->hw.vap_vf_max_vtx_indx.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VF_MAX_VTX_INDX, 2); ALLOC_STATE(vap_cntl_status, always, 2, 0); - r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(R300_VAP_CNTL_STATUS, 1); + r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL_STATUS, 1); ALLOC_STATE(vir[0], variable, R300_VIR_CMDSIZE, 0); r300->hw.vir[0].cmd[R300_VIR_CMD_0] = - cmdpacket0(R300_VAP_PROG_STREAM_CNTL_0, 1); + cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_0, 1); ALLOC_STATE(vir[1], variable, R300_VIR_CMDSIZE, 1); r300->hw.vir[1].cmd[R300_VIR_CMD_0] = - cmdpacket0(R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); + cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); ALLOC_STATE(vic, always, R300_VIC_CMDSIZE, 0); - r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_VTX_STATE_CNTL, 2); + r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_VTX_STATE_CNTL, 2); ALLOC_STATE(vap_psc_sgn_norm_cntl, always, 2, 0); - r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); + r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); if (has_tcl) { ALLOC_STATE(vap_clip_cntl, always, 2, 0); - r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(R300_VAP_CLIP_CNTL, 1); + r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CLIP_CNTL, 1); ALLOC_STATE(vap_clip, always, 5, 0); - r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_GB_VERT_CLIP_ADJ, 4); + r300->hw.vap_clip.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_GB_VERT_CLIP_ADJ, 4); ALLOC_STATE(vap_pvs_vtx_timeout_reg, always, 2, 0); - r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(VAP_PVS_VTX_TIMEOUT_REG, 1); + r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, VAP_PVS_VTX_TIMEOUT_REG, 1); } ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0); r300->hw.vof.cmd[R300_VOF_CMD_0] = - cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0, 2); + cmdpacket0(r300->radeon.radeonScreen, R300_VAP_OUTPUT_VTX_FMT_0, 2); if (has_tcl) { ALLOC_STATE(pvs, always, R300_PVS_CMDSIZE, 0); r300->hw.pvs.cmd[R300_PVS_CMD_0] = - cmdpacket0(R300_VAP_PVS_CODE_CNTL_0, 3); + cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_CODE_CNTL_0, 3); } ALLOC_STATE(gb_enable, always, 2, 0); - r300->hw.gb_enable.cmd[0] = cmdpacket0(R300_GB_ENABLE, 1); + r300->hw.gb_enable.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_ENABLE, 1); ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0); - r300->hw.gb_misc.cmd[0] = cmdpacket0(R300_GB_MSPOS0, 5); + r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 5); ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0); - r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(R300_TX_ENABLE, 1); + r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_ENABLE, 1); ALLOC_STATE(ga_point_s0, always, 5, 0); - r300->hw.ga_point_s0.cmd[0] = cmdpacket0(R300_GA_POINT_S0, 4); + r300->hw.ga_point_s0.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_S0, 4); ALLOC_STATE(ga_triangle_stipple, always, 2, 0); - r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(R300_GA_TRIANGLE_STIPPLE, 1); + r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_TRIANGLE_STIPPLE, 1); ALLOC_STATE(ps, always, R300_PS_CMDSIZE, 0); - r300->hw.ps.cmd[0] = cmdpacket0(R300_GA_POINT_SIZE, 1); + r300->hw.ps.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_SIZE, 1); ALLOC_STATE(ga_point_minmax, always, 4, 0); - r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(R300_GA_POINT_MINMAX, 3); + r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POINT_MINMAX, 3); ALLOC_STATE(lcntl, always, 2, 0); - r300->hw.lcntl.cmd[0] = cmdpacket0(R300_GA_LINE_CNTL, 1); + r300->hw.lcntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_CNTL, 1); ALLOC_STATE(ga_line_stipple, always, 4, 0); - r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 3); + r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_STIPPLE_VALUE, 3); ALLOC_STATE(shade, always, 5, 0); - r300->hw.shade.cmd[0] = cmdpacket0(R300_GA_ENHANCE, 4); + r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 4); ALLOC_STATE(polygon_mode, always, 4, 0); - r300->hw.polygon_mode.cmd[0] = cmdpacket0(R300_GA_POLY_MODE, 3); + r300->hw.polygon_mode.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_POLY_MODE, 3); ALLOC_STATE(fogp, always, 3, 0); - r300->hw.fogp.cmd[0] = cmdpacket0(R300_GA_FOG_SCALE, 2); + r300->hw.fogp.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_FOG_SCALE, 2); ALLOC_STATE(zbias_cntl, always, 2, 0); - r300->hw.zbias_cntl.cmd[0] = cmdpacket0(R300_SU_TEX_WRAP, 1); + r300->hw.zbias_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_TEX_WRAP, 1); ALLOC_STATE(zbs, always, R300_ZBS_CMDSIZE, 0); r300->hw.zbs.cmd[R300_ZBS_CMD_0] = - cmdpacket0(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); + cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_FRONT_SCALE, 4); ALLOC_STATE(occlusion_cntl, always, 2, 0); - r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(R300_SU_POLY_OFFSET_ENABLE, 1); + r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_POLY_OFFSET_ENABLE, 1); ALLOC_STATE(cul, always, R300_CUL_CMDSIZE, 0); - r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(R300_SU_CULL_MODE, 1); + r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_CULL_MODE, 1); ALLOC_STATE(su_depth_scale, always, 3, 0); - r300->hw.su_depth_scale.cmd[0] = cmdpacket0(R300_SU_DEPTH_SCALE, 2); + r300->hw.su_depth_scale.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_DEPTH_SCALE, 2); ALLOC_STATE(rc, always, R300_RC_CMDSIZE, 0); - r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(R300_RS_COUNT, 2); + r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_COUNT, 2); if (is_r500) { ALLOC_STATE(ri, always, R500_RI_CMDSIZE, 0); - r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R500_RS_IP_0, 16); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_IP_0, 16); for (i = 0; i < 8; i++) { r300->hw.ri.cmd[R300_RI_CMD_0 + i +1] = (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | @@ -477,132 +538,144 @@ void r300InitCmdBuf(r300ContextPtr r300) (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); } ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, 1); } else { ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); - r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_IP_0, 8); ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, 1); } ALLOC_STATE(sc_hyperz, always, 3, 0); - r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2); + r300->hw.sc_hyperz.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_HYPERZ, 2); ALLOC_STATE(sc_screendoor, always, 2, 0); - r300->hw.sc_screendoor.cmd[0] = cmdpacket0(R300_SC_SCREENDOOR, 1); + r300->hw.sc_screendoor.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1); ALLOC_STATE(us_out_fmt, always, 6, 0); - r300->hw.us_out_fmt.cmd[0] = cmdpacket0(R300_US_OUT_FMT, 5); + r300->hw.us_out_fmt.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_OUT_FMT, 5); if (is_r500) { ALLOC_STATE(fp, always, R500_FP_CMDSIZE, 0); - r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(R500_US_CONFIG, 2); + r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CONFIG, 2); r300->hw.fp.cmd[R500_FP_CNTL] = R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO; - r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(R500_US_CODE_ADDR, 3); - r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(R500_US_FC_CTRL, 1); + r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R500_US_CODE_ADDR, 3); + r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(r300->radeon.radeonScreen, R500_US_FC_CTRL, 1); r300->hw.fp.cmd[R500_FP_FC_CNTL] = 0; /* FIXME when we add flow control */ ALLOC_STATE(r500fp, r500fp, R500_FPI_CMDSIZE, 0); - r300->hw.r500fp.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 0, 0); + r300->hw.r500fp.cmd[R300_FPI_CMD_0] = + cmdr500fp(r300->radeon.radeonScreen, 0, 0, 0, 0); ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0); - r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 1, 0); + r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = + cmdr500fp(r300->radeon.radeonScreen, 0, 0, 1, 0); } else { ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0); - r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(R300_US_CONFIG, 3); - r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(R300_US_CODE_ADDR_0, 4); + r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CONFIG, 3); + r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CODE_ADDR_0, 4); + ALLOC_STATE(fpt, variable, R300_FPT_CMDSIZE, 0); - r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_US_TEX_INST_0, 0); + r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_TEX_INST_0, 0); ALLOC_STATE(fpi[0], variable, R300_FPI_CMDSIZE, 0); - r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, 1); + r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, 1); ALLOC_STATE(fpi[1], variable, R300_FPI_CMDSIZE, 1); - r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, 1); + r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, 1); ALLOC_STATE(fpi[2], variable, R300_FPI_CMDSIZE, 2); - r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, 1); + r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, 1); ALLOC_STATE(fpi[3], variable, R300_FPI_CMDSIZE, 3); - r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, 1); + r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, 1); ALLOC_STATE(fpp, variable, R300_FPP_CMDSIZE, 0); - r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, 0); + r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_PFS_PARAM_0_X, 0); } ALLOC_STATE(fogs, always, R300_FOGS_CMDSIZE, 0); - r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_FG_FOG_BLEND, 1); + r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_BLEND, 1); ALLOC_STATE(fogc, always, R300_FOGC_CMDSIZE, 0); - r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FG_FOG_COLOR_R, 3); + r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_FOG_COLOR_R, 3); ALLOC_STATE(at, always, R300_AT_CMDSIZE, 0); - r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_FG_ALPHA_FUNC, 2); + r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_ALPHA_FUNC, 2); ALLOC_STATE(fg_depth_src, always, 2, 0); - r300->hw.fg_depth_src.cmd[0] = cmdpacket0(R300_FG_DEPTH_SRC, 1); + r300->hw.fg_depth_src.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_FG_DEPTH_SRC, 1); ALLOC_STATE(rb3d_cctl, always, 2, 0); - r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(R300_RB3D_CCTL, 1); + r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CCTL, 1); ALLOC_STATE(bld, always, R300_BLD_CMDSIZE, 0); - r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(R300_RB3D_CBLEND, 2); + r300->hw.bld.cmd[R300_BLD_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_CBLEND, 2); ALLOC_STATE(cmk, always, R300_CMK_CMDSIZE, 0); - r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(RB3D_COLOR_CHANNEL_MASK, 1); + r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RB3D_COLOR_CHANNEL_MASK, 1); if (is_r500) { ALLOC_STATE(blend_color, always, 3, 0); - r300->hw.blend_color.cmd[0] = cmdpacket0(R500_RB3D_CONSTANT_COLOR_AR, 2); + r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_CONSTANT_COLOR_AR, 2); } else { ALLOC_STATE(blend_color, always, 2, 0); - r300->hw.blend_color.cmd[0] = cmdpacket0(R300_RB3D_BLEND_COLOR, 1); + r300->hw.blend_color.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_BLEND_COLOR, 1); } ALLOC_STATE(rop, always, 2, 0); - r300->hw.rop.cmd[0] = cmdpacket0(R300_RB3D_ROPCNTL, 1); + r300->hw.rop.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_ROPCNTL, 1); ALLOC_STATE(cb, always, R300_CB_CMDSIZE, 0); r300->hw.cb.emit = &emit_cb_offset; ALLOC_STATE(rb3d_dither_ctl, always, 10, 0); - r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(R300_RB3D_DITHER_CTL, 9); + r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9); ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0); - r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(R300_RB3D_AARESOLVE_CTL, 1); + r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_AARESOLVE_CTL, 1); ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); - r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0); r300->hw.zs.cmd[R300_ZS_CMD_0] = - cmdpacket0(R300_ZB_CNTL, 3); + cmdpacket0(r300->radeon.radeonScreen, R300_ZB_CNTL, 3); ALLOC_STATE(zstencil_format, always, 5, 0); r300->hw.zstencil_format.cmd[0] = - cmdpacket0(R300_ZB_FORMAT, 4); + cmdpacket0(r300->radeon.radeonScreen, R300_ZB_FORMAT, 4); ALLOC_STATE(zb, always, R300_ZB_CMDSIZE, 0); r300->hw.zb.emit = emit_zb_offset; ALLOC_STATE(zb_depthclearvalue, always, 2, 0); - r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE, 1); + r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_DEPTHCLEARVALUE, 1); ALLOC_STATE(unk4F30, always, 3, 0); - r300->hw.unk4F30.cmd[0] = cmdpacket0(0x4F30, 2); + r300->hw.unk4F30.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4F30, 2); ALLOC_STATE(zb_hiz_offset, always, 2, 0); - r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(R300_ZB_HIZ_OFFSET, 1); + r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_OFFSET, 1); ALLOC_STATE(zb_hiz_pitch, always, 2, 0); - r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(R300_ZB_HIZ_PITCH, 1); + r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_HIZ_PITCH, 1); /* VPU only on TCL */ if (has_tcl) { int i; ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); - r300->hw.vpi.cmd[R300_VPI_CMD_0] = - cmdvpu(R300_PVS_CODE_START, 0); + r300->hw.vpi.cmd[0] = + cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0); + r300->hw.vpi.emit = emit_vpu; if (is_r500) { ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); - r300->hw.vpp.cmd[R300_VPP_CMD_0] = - cmdvpu(R500_PVS_CONST_START, 0); + r300->hw.vpp.cmd[0] = + cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0); + r300->hw.vpp.emit = emit_vpu; ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); - r300->hw.vps.cmd[R300_VPS_CMD_0] = - cmdvpu(R500_POINT_VPORT_SCALE_OFFSET, 1); + r300->hw.vps.cmd[0] = + cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1); + r300->hw.vps.emit = emit_vpu; for (i = 0; i < 6; i++) { ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); - r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = - cmdvpu(R500_PVS_UCP_START + i, 1); + r300->hw.vpucp[i].cmd[0] = + cmdvpu(r300->radeon.radeonScreen, + R500_PVS_UCP_START + i, 1); + r300->hw.vpucp[i].emit = emit_vpu; } } else { ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); - r300->hw.vpp.cmd[R300_VPP_CMD_0] = - cmdvpu(R300_PVS_CONST_START, 0); + r300->hw.vpp.cmd[0] = + cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0); + r300->hw.vpp.emit = emit_vpu; ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); - r300->hw.vps.cmd[R300_VPS_CMD_0] = - cmdvpu(R300_POINT_VPORT_SCALE_OFFSET, 1); + r300->hw.vps.cmd[0] = + cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1); + r300->hw.vps.emit = emit_vpu; for (i = 0; i < 6; i++) { ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); - r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = - cmdvpu(R300_PVS_UCP_START + i, 1); + r300->hw.vpucp[i].cmd[0] = + cmdvpu(r300->radeon.radeonScreen, + R300_PVS_UCP_START + i, 1); + r300->hw.vpucp[i].emit = emit_vpu; } } } @@ -610,34 +683,34 @@ void r300InitCmdBuf(r300ContextPtr r300) /* Textures */ ALLOC_STATE(tex.filter, variable, mtu + 1, 0); r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FILTER0_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 0); ALLOC_STATE(tex.filter_1, variable, mtu + 1, 0); r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FILTER1_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, 0); ALLOC_STATE(tex.size, variable, mtu + 1, 0); - r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_SIZE_0, 0); + r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, 0); ALLOC_STATE(tex.format, variable, mtu + 1, 0); r300->hw.tex.format.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FORMAT_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, 0); ALLOC_STATE(tex.pitch, variable, mtu + 1, 0); - r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FORMAT2_0, 0); + r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, 0); ALLOC_STATE(tex.offset, variable, 1, 0); r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_OFFSET_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, 0); r300->hw.tex.offset.emit = &emit_tex_offsets; ALLOC_STATE(tex.chroma_key, variable, mtu + 1, 0); r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_CHROMA_KEY_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, 0); ALLOC_STATE(tex.border_color, variable, mtu + 1, 0); r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_BORDER_COLOR_0, 0); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0); r300->hw.is_dirty = GL_TRUE; r300->hw.all_dirty = GL_TRUE; @@ -663,7 +736,12 @@ void r300InitCmdBuf(r300ContextPtr r300) size * 4, r300->hw.max_state_size * 4); } - r300->cmdbuf.csm = radeon_cs_manager_legacy(&r300->radeon); + if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { + int fd = r300->radeon.radeonScreen->driScreen->fd; + r300->cmdbuf.csm = radeon_cs_manager_gem(fd); + } else { + r300->cmdbuf.csm = radeon_cs_manager_legacy(&r300->radeon); + } if (r300->cmdbuf.csm == NULL) { /* FIXME: fatal error */ return; @@ -684,4 +762,9 @@ void r300DestroyCmdBuf(r300ContextPtr r300) foreach(atom, &r300->hw.atomlist) { FREE(atom->cmd); } + if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { + radeon_cs_manager_gem_shutdown(r300->cmdbuf.csm); + } else { + radeon_cs_manager_legacy_shutdown(r300->cmdbuf.csm); + } } diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index 98cb1af126..b21619fd18 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -86,6 +86,10 @@ void r300BeginBatch(r300ContextPtr r300, */ #define OUT_BATCH_RELOC(data, bo, offset, flags) \ do { \ + if (offset) {\ + fprintf(stderr, "(%s:%s:%d) offset : %d\n",\ + __FILE__, __FUNCTION__, __LINE__, offset);\ + }\ radeon_cs_write_dword(b_l_r300->cmdbuf.cs, offset);\ radeon_cs_write_reloc(b_l_r300->cmdbuf.cs,bo,0,(bo)->size,flags);\ } while(0) @@ -119,4 +123,7 @@ void r300BeginBatch(r300ContextPtr r300, do { \ } while(0) +void emit_vpu(r300ContextPtr r300, struct r300_state_atom * atom); +int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom); + #endif /* __R300_CMDBUF_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 5f8b8c1a40..63bf67e76e 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -208,7 +208,7 @@ struct r300_state_atom { GLboolean dirty; int (*check) (r300ContextPtr, struct r300_state_atom * atom); - void (*emit) (r300ContextPtr); + void (*emit) (r300ContextPtr, struct r300_state_atom * atom); }; #define R300_VPT_CMD_0 0 diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index d07e7baf6b..d2628633d4 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -178,7 +178,7 @@ static void r300EmitVec(GLcontext * ctx, struct r300_aos *aos, aos->stride = size; } aos->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, - 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT); + 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0); aos->offset = 0; aos->components = size; aos->count = count; @@ -436,6 +436,18 @@ int r300EmitArrays(GLcontext * ctx) } /* Setup INPUT_ROUTE. */ + if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + R300_STATECHANGE(rmesa, vir[0]); + rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF; + rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF; + rmesa->hw.vir[0].cmd[0] |= + (r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], + vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16; + R300_STATECHANGE(rmesa, vir[1]); + rmesa->hw.vir[1].cmd[0] |= + (r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, + nr) & 0x3FFF) << 16; + } else { R300_STATECHANGE(rmesa, vir[0]); ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], @@ -444,6 +456,7 @@ int r300EmitArrays(GLcontext * ctx) ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, nr); + } /* Setup INPUT_CNTL. */ R300_STATECHANGE(rmesa, vic); diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index c596e895ce..bf34ced86e 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -46,23 +46,31 @@ /* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up * with DRM */ +#define CP_PACKET2 (2 << 30) #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) #define CP_PACKET3( pkt, n ) \ (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) -static INLINE uint32_t cmdpacket0(int reg, int count) +static INLINE uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) { - drm_r300_cmd_header_t cmd; - - cmd.packet0.cmd_type = R300_CMD_PACKET0; - cmd.packet0.count = count; - cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; - cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); - - return cmd.u; + if (!rscrn->driScreen->dri2.enabled) { + drm_r300_cmd_header_t cmd; + + cmd.packet0.cmd_type = R300_CMD_PACKET0; + cmd.packet0.count = count; + cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; + cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); + + return cmd.u; + } + if (count) { + return CP_PACKET0(reg, count - 1); + } + return CP_PACKET2; } -static INLINE uint32_t cmdvpu(int addr, int count) +static INLINE uint32_t cmdvpu(struct radeon_screen *rscrn, int addr, int count) { drm_r300_cmd_header_t cmd; @@ -74,7 +82,8 @@ static INLINE uint32_t cmdvpu(int addr, int count) return cmd.u; } -static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) +static INLINE uint32_t cmdr500fp(struct radeon_screen *rscrn, + int addr, int count, int type, int clamp) { drm_r300_cmd_header_t cmd; @@ -88,7 +97,7 @@ static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) return cmd.u; } -static INLINE uint32_t cmdpacket3(int packet) +static INLINE uint32_t cmdpacket3(struct radeon_screen *rscrn, int packet) { drm_r300_cmd_header_t cmd; @@ -98,7 +107,8 @@ static INLINE uint32_t cmdpacket3(int packet) return cmd.u; } -static INLINE uint32_t cmdcpdelay(unsigned short count) +static INLINE uint32_t cmdcpdelay(struct radeon_screen *rscrn, + unsigned short count) { drm_r300_cmd_header_t cmd; @@ -108,7 +118,8 @@ static INLINE uint32_t cmdcpdelay(unsigned short count) return cmd.u; } -static INLINE uint32_t cmdwait(unsigned char flags) +static INLINE uint32_t cmdwait(struct radeon_screen *rscrn, + unsigned char flags) { drm_r300_cmd_header_t cmd; @@ -118,7 +129,7 @@ static INLINE uint32_t cmdwait(unsigned char flags) return cmd.u; } -static INLINE uint32_t cmdpacify(void) +static INLINE uint32_t cmdpacify(struct radeon_screen *rscrn) { drm_r300_cmd_header_t cmd; @@ -130,13 +141,13 @@ static INLINE uint32_t cmdpacify(void) /** Single register write to command buffer; requires 2 dwords. */ #define OUT_BATCH_REGVAL(reg, val) \ - OUT_BATCH(cmdpacket0((reg), 1)); \ + OUT_BATCH(cmdpacket0(b_l_r300->radeon.radeonScreen, (reg), 1)); \ OUT_BATCH((val)) /** Continuous register range write to command buffer; requires 1 dword, * expects count dwords afterwards for register contents. */ #define OUT_BATCH_REGSEQ(reg, count) \ - OUT_BATCH(cmdpacket0((reg), (count))); + OUT_BATCH(cmdpacket0(b_l_r300->radeon.radeonScreen, (reg), (count))); /** Write a 32 bit float to the ring; requires 1 dword. */ #define OUT_BATCH_FLOAT32(f) \ @@ -147,7 +158,10 @@ static INLINE uint32_t cmdpacify(void) * Outputs 2 dwords and expects (num_extra+1) additional dwords afterwards. */ #define OUT_BATCH_PACKET3(packet, num_extra) do {\ - OUT_BATCH(cmdpacket3(R300_CMD_PACKET3_RAW)); \ + if (!b_l_r300->radeon.radeonScreen->driScreen->dri2.enabled) { \ + OUT_BATCH(cmdpacket3(b_l_r300->radeon.radeonScreen,\ + R300_CMD_PACKET3_RAW)); \ + }\ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \ } while(0) @@ -158,27 +172,62 @@ void static INLINE end_3d(r300ContextPtr rmesa) { BATCH_LOCALS(rmesa); - BEGIN_BATCH(1); - OUT_BATCH(cmdpacify()); - END_BATCH(); + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH(1); + OUT_BATCH(cmdpacify(rmesa->radeon.radeonScreen)); + END_BATCH(); + } } void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count) { BATCH_LOCALS(rmesa); - BEGIN_BATCH(1); - OUT_BATCH(cmdcpdelay(count)); - END_BATCH(); + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH(1); + OUT_BATCH(cmdcpdelay(rmesa->radeon.radeonScreen, count)); + END_BATCH(); + } } void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags) { BATCH_LOCALS(rmesa); - - BEGIN_BATCH(1); - OUT_BATCH(cmdwait(flags)); - END_BATCH(); + uint32_t wait_until; + + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH_NO_AUTOSTATE(1); + OUT_BATCH(cmdwait(rmesa->radeon.radeonScreen, flags)); + END_BATCH(); + } else { + switch(flags) { + case R300_WAIT_2D: + wait_until = (1 << 14); + break; + case R300_WAIT_3D: + wait_until = (1 << 15); + break; + case R300_NEW_WAIT_2D_3D: + wait_until = (1 << 14) | (1 << 15); + break; + case R300_NEW_WAIT_2D_2D_CLEAN: + wait_until = (1 << 14) | (1 << 16) | (1 << 18); + break; + case R300_NEW_WAIT_3D_3D_CLEAN: + wait_until = (1 << 15) | (1 << 17) | (1 << 18); + break; + case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: + wait_until = (1 << 14) | (1 << 16) | (1 << 18); + wait_until |= (1 << 15) | (1 << 17) | (1 << 18); + break; + default: + return; + } + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); + OUT_BATCH(wait_until); + END_BATCH(); + } } extern int r300EmitArrays(GLcontext * ctx); diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index a308573649..a3353db520 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -56,9 +56,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_reg.h" #include "r300_emit.h" #include "r300_fragprog.h" +#include "r300_context.h" #include "vblank.h" +#define R200_3D_DRAW_IMMD_2 0xC0003500 + #define CLEARBUFFER_COLOR 0x1 #define CLEARBUFFER_DEPTH 0x2 #define CLEARBUFFER_STENCIL 0x4 @@ -79,7 +82,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, dPriv->w, dPriv->h); if (rrb) { - cbpitch = rrb->pitch; + cbpitch = (rrb->pitch / rrb->cpp); if (rrb->cpp == 4) cbpitch |= R300_COLOR_FORMAT_ARGB8888; else @@ -105,11 +108,11 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, #if 1 if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) { assert(rrbd != 0); - cbpitch = rrbd->pitch; + cbpitch = (rrbd->pitch / rrbd->cpp); if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ cbpitch |= R300_DEPTHMACROTILE_ENABLE; } - if (r300->radeon.glCtx->Visual.depthBits == 24) { + if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ cbpitch |= R300_DEPTHMICROTILE_TILED; } BEGIN_BATCH_NO_AUTOSTATE(4); @@ -119,7 +122,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, END_BATCH(); } #endif - BEGIN_BATCH_NO_AUTOSTATE(15); + BEGIN_BATCH_NO_AUTOSTATE(6); OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1); if (flags & CLEARBUFFER_COLOR) { OUT_BATCH((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | @@ -130,7 +133,6 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, OUT_BATCH(0); } - OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3); { uint32_t t1, t2; @@ -157,22 +159,40 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, R300_S_FRONT_ZFAIL_OP_SHIFT); } + OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3); OUT_BATCH(t1); OUT_BATCH(t2); - OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) | + OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << + R300_STENCILWRITEMASK_SHIFT) | (ctx->Stencil.Clear & R300_STENCILREF_MASK)); + END_BATCH(); } - OUT_BATCH(cmdpacket3(R300_CMD_PACKET3_CLEAR)); - OUT_BATCH_FLOAT32(dPriv->w / 2.0); - OUT_BATCH_FLOAT32(dPriv->h / 2.0); - OUT_BATCH_FLOAT32(ctx->Depth.Clear); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); - END_BATCH(); + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + BEGIN_BATCH_NO_AUTOSTATE(9); + OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR)); + OUT_BATCH_FLOAT32(dPriv->w / 2.0); + OUT_BATCH_FLOAT32(dPriv->h / 2.0); + OUT_BATCH_FLOAT32(ctx->Depth.Clear); + OUT_BATCH_FLOAT32(1.0); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); + END_BATCH(); + } else { + OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); + OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | + (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + OUT_BATCH_FLOAT32(dPriv->w / 2.0); + OUT_BATCH_FLOAT32(dPriv->h / 2.0); + OUT_BATCH_FLOAT32(ctx->Depth.Clear); + OUT_BATCH_FLOAT32(1.0); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); + OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); + } r300EmitCacheFlush(rmesa); cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN); @@ -379,7 +399,7 @@ static void r300EmitClearState(GLcontext * ctx) OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1)); OUT_BATCH(R500_US_CODE_OFFSET_ADDR(0)); - OUT_BATCH(cmdr500fp(0, 1, 0, 0)); + OUT_BATCH(cmdr500fp(r300->radeon.radeonScreen, 0, 1, 0, 0)); OUT_BATCH(R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST | @@ -456,10 +476,12 @@ static void r300EmitClearState(GLcontext * ctx) END_BATCH(); if (has_tcl) { + struct r300_state_atom vpu; + uint32_t _cmd[10]; R300_STATECHANGE(r300, pvs); R300_STATECHANGE(r300, vpi); - BEGIN_BATCH(13); + BEGIN_BATCH(4); OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3); OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) | (0 << R300_PVS_XYZW_VALID_INST_SHIFT) | @@ -467,18 +489,37 @@ static void r300EmitClearState(GLcontext * ctx) OUT_BATCH((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | (0 << R300_PVS_MAX_CONST_ADDR_SHIFT)); OUT_BATCH(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT); - - OUT_BATCH(cmdvpu(0, 2)); - OUT_BATCH(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT)); - OUT_BATCH(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - OUT_BATCH(PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - OUT_BATCH(0x0); - - OUT_BATCH(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT)); - OUT_BATCH(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - OUT_BATCH(PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_SELECT_FORCE_0, PVS_SRC_REG_INPUT, VSF_FLAG_NONE)); - OUT_BATCH(0x0); END_BATCH(); + + vpu.check = check_vpu; + vpu.cmd = _cmd; + vpu.cmd[0] = cmdvpu(r300->radeon.radeonScreen, 0, 2); + + vpu.cmd[1] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, + 0, 0xf, PVS_DST_REG_OUT); + vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, + PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, + PVS_SRC_REG_INPUT, VSF_FLAG_NONE); + vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_REG_INPUT, VSF_FLAG_NONE); + vpu.cmd[4] = 0x0; + + vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, + PVS_DST_REG_OUT); + vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, + PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, + PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, + VSF_FLAG_NONE); + vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_SELECT_FORCE_0, + PVS_SRC_REG_INPUT, VSF_FLAG_NONE); + vpu.cmd[8] = 0x0; + emit_vpu(r300, &vpu); } } @@ -542,7 +583,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); - rrbd = (void *)r300->radeon.state.depth_buffer; + rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; if (flags & BUFFER_BIT_FRONT_LEFT) { rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c index 81ad7ea328..097f9cdfec 100644 --- a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c +++ b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c @@ -163,7 +163,10 @@ r300_mipmap_tree* r300_miptree_create(r300ContextPtr rmesa, r300TexObj *t, calculate_miptree_layout(mt); - mt->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, 0, mt->totalsize, 1024, 0); + mt->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, + 0, mt->totalsize, 1024, + RADEON_GEM_DOMAIN_VRAM, + 0); return mt; } diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 1762d4cb03..f281e28e42 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -179,7 +179,7 @@ static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) rmesa->state.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, 0, n_elts * 4, 4, - RADEON_GEM_DOMAIN_GTT); + RADEON_GEM_DOMAIN_GTT, 0); rmesa->state.elt_dma_offset = 0; radeon_bo_map(rmesa->state.elt_dma_bo, 1); out = rmesa->state.elt_dma_bo->ptr + rmesa->state.elt_dma_offset; @@ -199,11 +199,23 @@ static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type) type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit); + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); OUT_BATCH_RELOC(0, rmesa->state.elt_dma_bo, rmesa->state.elt_dma_offset, 0); OUT_BATCH(vertex_count); + } else { + OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2); + OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); + OUT_BATCH(rmesa->state.elt_dma_offset); + OUT_BATCH(vertex_count); + radeon_cs_write_reloc(rmesa->cmdbuf.cs, + rmesa->state.elt_dma_bo, + 0, + rmesa->state.elt_dma_bo->size, + 0); + } END_BATCH(); } } @@ -223,6 +235,8 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); OUT_BATCH(nr); + + if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { for (i = 0; i + 1 < nr; i += 2) { OUT_BATCH((rmesa->state.aos[i].components << 0) | (rmesa->state.aos[i].stride << 8) | @@ -243,6 +257,52 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) OUT_BATCH_RELOC(0, rmesa->state.aos[nr - 1].bo, rmesa->state.aos[nr - 1].offset + offset * 4 * rmesa->state.aos[nr - 1].stride, 0); } + } else { + for (i = 0; i + 1 < nr; i += 2) { + OUT_BATCH((rmesa->state.aos[i].components << 0) | + (rmesa->state.aos[i].stride << 8) | + (rmesa->state.aos[i + 1].components << 16) | + (rmesa->state.aos[i + 1].stride << 24)); + + voffset = rmesa->state.aos[i + 0].offset + + offset * 4 * rmesa->state.aos[i + 0].stride; + OUT_BATCH(voffset); + voffset = rmesa->state.aos[i + 1].offset + + offset * 4 * rmesa->state.aos[i + 1].stride; + OUT_BATCH(voffset); + } + + if (nr & 1) { + OUT_BATCH((rmesa->state.aos[nr - 1].components << 0) | + (rmesa->state.aos[nr - 1].stride << 8)); + OUT_BATCH(rmesa->state.aos[nr - 1].offset + offset * 4 * + rmesa->state.aos[nr - 1].stride); + } + for (i = 0; i + 1 < nr; i += 2) { + #if 0 + fprintf(stderr, "3D_LOAD_VBPNTR 0x%08X & 0x%08X\n", + rmesa->state.aos[i+0].bo->handle, + rmesa->state.aos[i+1].bo->handle); + #endif + radeon_cs_write_reloc(rmesa->cmdbuf.cs, + rmesa->state.aos[i+0].bo, + 0, + rmesa->state.aos[i+0].bo->size, + 0); + radeon_cs_write_reloc(rmesa->cmdbuf.cs, + rmesa->state.aos[i+1].bo, + 0, + rmesa->state.aos[i+1].bo->size, + 0); + } + if (nr & 1) { + radeon_cs_write_reloc(rmesa->cmdbuf.cs, + rmesa->state.aos[nr-1].bo, + 0, + rmesa->state.aos[nr-1].bo->size, + 0); + } + } END_BATCH(); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 44f9510d3c..c79e69ae04 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1101,10 +1101,19 @@ static void r300UpdateWindow(GLcontext * ctx) static void r300Viewport(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); + __DRIcontext *driContext = rmesa->radeon.dri.context; /* Don't pipeline viewport changes, conflict with window offset * setting below. Could apply deltas to rescue pipelined viewport * values, or keep the originals hanging around. */ + if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + if (driContext->driDrawablePriv != driContext->driReadablePriv) { + radeon_update_renderbuffers(driContext, + driContext->driReadablePriv); + } + } r300UpdateWindow(ctx); } @@ -1164,21 +1173,6 @@ void r300UpdateDrawBuffer(GLcontext * ctx) assert(rrb->pitch); R300_STATECHANGE(rmesa, cb); - -#if 0 - R200_STATECHANGE(rmesa, ctx); - - /* Note: we used the (possibly) page-flipped values */ - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] - = ((drb->flippedOffset + rmesa->r200Screen->fbLocation) - & R200_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; - - if (rmesa->sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= - R200_COLOR_TILE_ENABLE; - } -#endif } static void @@ -1398,7 +1392,8 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) } r300->hw.fpt.cmd[R300_FPT_CMD_0] = - cmdpacket0(R300_US_TEX_INST_0, code->tex.length); + cmdpacket0(r300->radeon.radeonScreen, + R300_US_TEX_INST_0, code->tex.length); } static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) @@ -1541,21 +1536,21 @@ static void r300SetupTextures(GLcontext * ctx) } r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1); r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER1_0, last_hw_tmu + 1); r300->hw.tex.size.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_SIZE_0, last_hw_tmu + 1); r300->hw.tex.format.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FORMAT_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT_0, last_hw_tmu + 1); r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FORMAT2_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, last_hw_tmu + 1); r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, last_hw_tmu + 1); r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_CHROMA_KEY_0, last_hw_tmu + 1); r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); if (!fp) /* should only happenen once, just after context is created */ return; @@ -1567,7 +1562,7 @@ static void r300SetupTextures(GLcontext * ctx) r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0; r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = - cmdpacket0(R300_TX_FILTER0_0, 1); + cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1); } r300SetupFragmentShaderTextures(ctx, tmu_mappings); } else @@ -1729,7 +1724,7 @@ static void r300SetupRSUnit(GLcontext * ctx) | R300_HIRES_EN; assert(high_rr >= 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_RS_INST_0, high_rr + 1); r300->hw.rc.cmd[2] = high_rr; if (InputsRead) @@ -1889,7 +1884,7 @@ static void r500SetupRSUnit(GLcontext * ctx) | R300_HIRES_EN; assert(high_rr >= 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, high_rr + 1); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R500_RS_INST_0, high_rr + 1); r300->hw.rc.cmd[2] = 0xC0 | high_rr; if (InputsRead) @@ -2087,6 +2082,7 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa) (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); } + static void r300SetupVertexProgram(r300ContextPtr rmesa) { GLcontext *ctx = rmesa->radeon.glCtx; @@ -2173,6 +2169,7 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) static void r300ResetHwState(r300ContextPtr r300) { GLcontext *ctx = r300->radeon.glCtx; + struct radeon_renderbuffer *rrb; int has_tcl = 1; if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) @@ -2364,8 +2361,8 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; - - if (r300->radeon.sarea->tiling_enabled) { + rrb = r300->radeon.state.depth_buffer; + if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) { /* XXX: Turn off when clearing buffers ? */ r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; @@ -2499,10 +2496,10 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) R300_STATECHANGE(rmesa, fpi[1]); R300_STATECHANGE(rmesa, fpi[2]); R300_STATECHANGE(rmesa, fpi[3]); - rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, code->alu.length); - rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, code->alu.length); - rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, code->alu.length); - rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); + rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_INST_0, code->alu.length); + rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_RGB_ADDR_0, code->alu.length); + rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, code->alu.length); + rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, code->alu.length); for (i = 0; i < code->alu.length; i++) { rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst0; rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst1; @@ -2533,7 +2530,7 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) } R300_STATECHANGE(rmesa, fpp); - rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, code->const_nr * 4); + rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); for (i = 0; i < code->const_nr; i++) { const GLfloat *constant = get_fragmentprogram_constant(ctx, &fp->mesa_program.Base, code->constant[i]); diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index f21766b4d8..43a2599dfe 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -271,7 +271,7 @@ r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) GLuint bytes = vsize * nverts; rmesa->swtcl.bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, - 0, bytes, 4, RADEON_GEM_DOMAIN_GTT); + 0, bytes, 4, RADEON_GEM_DOMAIN_GTT, 0); radeon_bo_map(rmesa->swtcl.bo, 1); if (rmesa->swtcl.flush == NULL) { rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index e62cf46d1e..e65b8c1cc4 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -220,7 +220,7 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) ctx = radeon->glCtx; if (ctx->Visual.doubleBufferMode) { - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ if (radeon->doPageFlip) { radeonPageFlip(dPriv); } else { @@ -276,10 +276,11 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, radeon->radeonScreen->fbLocation, size, 4096, + RADEON_GEM_DOMAIN_VRAM, 0); } rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->frontPitch; + rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; } if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { if (!rb->bo) { @@ -288,10 +289,11 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, radeon->radeonScreen->fbLocation, size, 4096, + RADEON_GEM_DOMAIN_VRAM, 0); } rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->backPitch; + rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; } if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { if (!rb->bo) { @@ -300,13 +302,122 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, radeon->radeonScreen->fbLocation, size, 4096, + RADEON_GEM_DOMAIN_VRAM, 0); } rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; } } +void +radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +{ + unsigned int attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + struct radeon_renderbuffer *rb; + int i, count; + GLframebuffer *draw; + radeonContextPtr radeon; + + draw = drawable->driverPrivate; + screen = context->driScreenPriv; + radeon = (radeonContextPtr) context->driverPrivate; + i = 0; + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_DEPTH; + } + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + /* set one cliprect to cover the whole drawable */ + drawable->x = 0; + drawable->y = 0; + drawable->backX = 0; + drawable->backY = 0; + drawable->numClipRects = 1; + drawable->pClipRects[0].x1 = 0; + drawable->pClipRects[0].y1 = 0; + drawable->pClipRects[0].x2 = drawable->w; + drawable->pClipRects[0].y2 = drawable->h; + drawable->numBackClipRects = 1; + drawable->pBackClipRects[0].x1 = 0; + drawable->pBackClipRects[0].y1 = 0; + drawable->pBackClipRects[0].x2 = drawable->w; + drawable->pBackClipRects[0].y2 = drawable->h; + for (i = 0; i < count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + if (rb->bo == NULL) { + fprintf(stderr, "failled to attach front %d\n", + buffers[i].name); + } + break; + case __DRI_BUFFER_BACK_LEFT: + rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_DEPTH: + rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_STENCIL: + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + } + radeon = (radeonContextPtr) context->driverPrivate; + driUpdateFramebufferSize(radeon->glCtx, drawable); +} + /* Force the context `c' to be the current context and associate with it * buffer `b'. @@ -324,11 +435,21 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, _mesa_make_current(NULL, NULL, NULL); return GL_TRUE; } - radeon = (radeonContextPtr) driContextPriv->driverPrivate; dfb = driDrawPriv->driverPrivate; rfb = driReadPriv->driverPrivate; + if (driContextPriv->driScreenPriv->dri2.enabled) { + radeon_update_renderbuffers(driContextPriv, driDrawPriv); + if (driDrawPriv != driReadPriv) + radeon_update_renderbuffers(driContextPriv, driReadPriv); + radeon->state.color.rrb = + (void *)dfb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + radeon->state.depth_buffer = + (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; + } + + if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx); @@ -336,7 +457,9 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, if (driReadPriv != driDrawPriv) driUpdateFramebufferSize(radeon->glCtx, driReadPriv); - radeon_make_renderbuffer_current(radeon, dfb); + if (!driContextPriv->driScreenPriv->dri2.enabled) { + radeon_make_renderbuffer_current(radeon, dfb); + } _mesa_make_current(radeon->glCtx, dfb, rfb); @@ -364,7 +487,9 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, _mesa_update_state(radeon->glCtx); - radeonUpdatePageFlipping(radeon); + if (!driContextPriv->driScreenPriv->dri2.enabled) { + radeonUpdatePageFlipping(radeon); + } if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "End %s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 5658df7d1b..d5bbf2928d 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -203,6 +203,7 @@ extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driDrawPriv, __DRIdrawablePrivate * driReadPriv); extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); +void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); /* ================================================================ * Debugging: diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h index a344837f47..eaef49c325 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.h +++ b/src/mesa/drivers/dri/r300/radeon_lock.h @@ -97,19 +97,23 @@ extern int prevLockLine; do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ DRM_CAS((rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret); \ if (__ret) \ radeonGetLock((rmesa), 0); \ + }\ DEBUG_LOCK(); \ } while (0) #define UNLOCK_HARDWARE( rmesa ) \ do { \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ DRM_UNLOCK((rmesa)->dri.fd, \ (rmesa)->dri.hwLock, \ (rmesa)->dri.hwContext); \ DEBUG_RESET(); \ + }\ } while (0) #endif /* __RADEON_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c index b12b19f24e..30dde80994 100644 --- a/src/mesa/drivers/dri/r300/radeon_span.c +++ b/src/mesa/drivers/dri/r300/radeon_span.c @@ -61,8 +61,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. struct radeon_renderbuffer *rrb = (void *) rb; \ const __DRIdrawablePrivate *dPriv = rrb->dPriv; \ const GLuint bottom = dPriv->h - 1; \ - GLubyte *buf = (GLubyte *) ((char*)rrb->bo->ptr) \ - + (dPriv->y * rrb->pitch + dPriv->x) * rrb->cpp; \ GLuint p; \ (void)p; @@ -71,8 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. const __DRIdrawablePrivate *dPriv = rrb->dPriv; \ const GLuint bottom = dPriv->h - 1; \ GLuint xo = dPriv->x; \ - GLuint yo = dPriv->y; \ - GLubyte *buf = (GLubyte *) rrb->bo->ptr; + GLuint yo = dPriv->y; #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS @@ -82,6 +79,133 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define HW_UNLOCK() +static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 5; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 5) << 11; + offset += ((x & 31) >> 2) << 5; + offset += (x & 3) << 2; + } else { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 3) << 5; + offset += (x & 7) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 1; + } else { + nmacroblkpl = rrb->pitch >> 7; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 7) << 11; + offset += ((x & 127) >> 4) << 5; + offset += (x & 15) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 4) << 5; + offset += (x & 15) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint microblkxs; + GLint macroblkxs; + GLint nmacroblkpl; + GLint nmicroblkpl; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + microblkxs = 16 / rrb->cpp; + macroblkxs = 128 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } else { + microblkxs = 32 / rrb->cpp; + macroblkxs = 256 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } else { + microblkxs = 32 / rrb->cpp; + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } + return &ptr[offset]; +} + /* ================================================================ * Color buffer */ @@ -93,7 +217,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y -#define GET_PTR(X,Y) (buf + ((Y) * rrb->pitch + (X)) * 2) +#define GET_PTR(X,Y) radeon_ptr16(rrb, (X), (Y)) #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions @@ -103,7 +227,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y -#define GET_PTR(X,Y) (buf + ((Y) * rrb->pitch + (X)) * 4) +#define GET_PTR(X,Y) radeon_ptr32(rrb, (X), (Y)) #include "spantmp2.h" /* ================================================================ @@ -120,66 +244,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * too... */ -static GLuint radeon_mba_z32(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLuint pitch = rrb->pitch; - if (rrb->depthHasSurface) { - return 4 * (x + y * pitch); - } else { - GLuint ba, address = 0; /* a[0..1] = 0 */ - -#ifdef COMPILE_R300 - ba = (y / 8) * (pitch / 8) + (x / 8); -#else - ba = (y / 16) * (pitch / 16) + (x / 16); -#endif - - address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ - address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ - address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ - address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ - - address |= (y & 0x8) << 7; /* a[10] = y[3] */ - address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ - address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ - - return address; - } -} - -static INLINE GLuint -radeon_mba_z16(const struct radeon_renderbuffer *rrb, GLint x, GLint y) -{ - GLuint pitch = rrb->pitch; - if (rrb->depthHasSurface) { - return 2 * (x + y * pitch); - } else { - GLuint ba, address = 0; /* a[0] = 0 */ - - ba = (y / 16) * (pitch / 32) + (x / 32); - - address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ - address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ - address |= (x & 0x8) << 4; /* a[7] = x[3] */ - address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ - address |= (y & 0x8) << 7; /* a[10] = y[3] */ - address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ - address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ - - return address; - } -} - /* 16-bit depth buffer functions */ #define VALUE_TYPE GLushort #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + radeon_mba_z16( rrb, _x + xo, _y + yo )) = d; + *(GLushort *)radeon_ptr(rrb, _x + xo, _y + yo) = d #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + radeon_mba_z16( rrb, _x + xo, _y + yo )); + d = *(GLushort *)radeon_ptr(rrb, _x + xo, _y + yo) #define TAG(x) radeon##x##_z16 #include "depthtmp.h" @@ -194,35 +267,36 @@ radeon_mba_z16(const struct radeon_renderbuffer *rrb, GLint x, GLint y) #ifdef COMPILE_R300 #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ + GLuint tmp = *_ptr; \ tmp &= 0x000000ff; \ tmp |= ((d << 8) & 0xffffff00); \ - *(GLuint *)(buf + offset) = tmp; \ + *_ptr = tmp; \ } while (0) #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ + GLuint tmp = *_ptr; \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ - *(GLuint *)(buf + offset) = tmp; \ + *_ptr = tmp; \ } while (0) #endif #ifdef COMPILE_R300 #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint *)(buf + radeon_mba_z32( rrb, _x + xo, \ - _y + yo )) & 0xffffff00) >> 8; \ + d = (*(GLuint*)(radeon_ptr32(rrb, _x + xo, _y + yo)) & 0xffffff00) >> 8; \ }while(0) #else #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + radeon_mba_z32( rrb, _x + xo, \ - _y + yo )) & 0x00ffffff; + d = *(GLuint*)(radeon_ptr32(rrb, _x + xo, _y + yo )) & 0x00ffffff; #endif - +/* + fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ + d = *(GLuint*)(radeon_ptr(rrb, _x + xo, _y + yo )) & 0x00ffffff; +*/ #define TAG(x) radeon##x##_z24_s8 #include "depthtmp.h" @@ -235,35 +309,35 @@ do { \ #ifdef COMPILE_R300 #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + xo, _y + yo); \ + GLuint tmp = *_ptr; \ tmp &= 0xffffff00; \ tmp |= (d) & 0xff; \ - *(GLuint *)(buf + offset) = tmp; \ + *_ptr = tmp; \ } while (0) #else #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + xo, _y + yo); \ + GLuint tmp = *_ptr; \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ - *(GLuint *)(buf + offset) = tmp; \ + *_ptr = tmp; \ } while (0) #endif #ifdef COMPILE_R300 #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ + GLuint tmp = *_ptr; \ d = tmp & 0x000000ff; \ } while (0) #else #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint offset = radeon_mba_z32( rrb, _x + xo, _y + yo ); \ - GLuint tmp = *(GLuint *)(buf + offset); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + xo, _y + yo ); \ + GLuint tmp = *_ptr; \ d = (tmp & 0xff000000) >> 24; \ } while (0) #endif @@ -274,9 +348,14 @@ do { \ static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) { struct radeon_renderbuffer *rrb = (void*)rb; + int r; if (rrb->bo) { - radeon_bo_map(rrb->bo, write); + r = radeon_bo_map(rrb->bo, write); + if (r) { + fprintf(stderr, "(%s) error(%d) mapping buffer.\n", + __FUNCTION__, r); + } } } diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 024190317b..9cce179308 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -153,6 +153,7 @@ void radeonSetCliprects(radeonContextPtr radeon) GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + if (!radeon->radeonScreen->driScreen->dri2.enabled) { if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { /* Can't ignore 2d windows if we are page flipping. */ if (drawable->numBackClipRects == 0 || radeon->doPageFlip || @@ -168,6 +169,7 @@ void radeonSetCliprects(radeonContextPtr radeon) radeon->numClipRects = drawable->numClipRects; radeon->pClipRects = drawable->pClipRects; } + } if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index 580ff374c7..d57b19de8d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -233,6 +233,7 @@ static void legacy_track_pending(struct bo_manager_legacy *boml) static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, uint32_t size, uint32_t alignment, + uint32_t domains, uint32_t flags) { struct bo_legacy *bo_legacy; @@ -245,6 +246,7 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, bo_legacy->base.handle = 0; bo_legacy->base.size = size; bo_legacy->base.alignment = alignment; + bo_legacy->base.domains = domains; bo_legacy->base.flags = flags; bo_legacy->base.ptr = NULL; bo_legacy->map_count = 0; @@ -337,7 +339,7 @@ static void bo_free(struct bo_legacy *bo_legacy) } if (!bo_legacy->static_bo) { legacy_free_handle(boml, bo_legacy->base.handle); - if (bo_legacy->base.flags & RADEON_GEM_DOMAIN_GTT) { + if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { /* dma buffers */ bo_dma_free(&bo_legacy->base); } else { @@ -353,6 +355,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size, uint32_t alignment, + uint32_t domains, uint32_t flags) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; @@ -371,14 +374,14 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, return NULL; } - bo_legacy = bo_allocate(boml, size, alignment, flags); + bo_legacy = bo_allocate(boml, size, alignment, domains, flags); bo_legacy->static_bo = 0; r = legacy_new_handle(boml, &bo_legacy->base.handle); if (r) { bo_free(bo_legacy); return NULL; } - if (bo_legacy->base.flags & RADEON_GEM_DOMAIN_GTT) { + if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) { legacy_track_pending(boml); /* dma buffers */ r = bo_dma_alloc(&(bo_legacy->base)); @@ -555,7 +558,7 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo, *eoffset = bo_legacy->offset + bo->size; return 0; } - if (!(bo->flags & RADEON_GEM_DOMAIN_GTT)) { + if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) { r = bo_vram_validate(bo, soffset, eoffset); if (r) { return r; @@ -650,7 +653,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) /* biggest framebuffer size */ size = 4096*4096*4; /* allocate front */ - bo = bo_allocate(bom, size, 0, 0); + bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); return NULL; @@ -666,7 +669,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) bom->nhandle = bo->base.handle + 1; } /* allocate back */ - bo = bo_allocate(bom, size, 0, 0); + bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); return NULL; @@ -682,14 +685,15 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) bom->nhandle = bo->base.handle + 1; } /* allocate depth */ - bo = bo_allocate(bom, size, 0, 0); + bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); return NULL; } bo->base.flags = 0; if (scrn->sarea->tiling_enabled) { - bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE; + bo->base.flags |= RADEON_BO_FLAGS_MACRO_TILE; + bo->base.flags |= RADEON_BO_FLAGS_MICRO_TILE; } bo->static_bo = 1; bo->offset = bom->screen->depthOffset + bom->fb_location; @@ -711,7 +715,7 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) { struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; - if (bo_legacy->static_bo || (bo->flags & RADEON_GEM_DOMAIN_GTT)) { + if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) { return 0; } return bo->size; diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer.h b/src/mesa/drivers/dri/radeon/radeon_buffer.h index d41558f2e0..d32809ef1a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_buffer.h +++ b/src/mesa/drivers/dri/radeon/radeon_buffer.h @@ -39,7 +39,8 @@ struct radeon_renderbuffer unsigned int height; /* boo Xorg 6.8.2 compat */ - int depthHasSurface; + int has_surface; + __DRIdrawablePrivate *dPriv; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index a2a8423e6a..8de928692a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -270,22 +270,30 @@ static int cs_emit(struct radeon_cs *cs) int r; /* please flush pipe do all pending work */ - cs_write_dword(cs, cmdpacket0(R300_SC_SCREENDOOR, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_SC_SCREENDOOR, 1)); cs_write_dword(cs, 0x0); - cs_write_dword(cs, cmdpacket0(R300_SC_SCREENDOOR, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_SC_SCREENDOOR, 1)); cs_write_dword(cs, 0x00FFFFFF); - cs_write_dword(cs, cmdpacket0(R300_SC_HYPERZ, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_SC_HYPERZ, 1)); cs_write_dword(cs, 0x0); - cs_write_dword(cs, cmdpacket0(R300_US_CONFIG, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_US_CONFIG, 1)); cs_write_dword(cs, 0x0); - cs_write_dword(cs, cmdpacket0(R300_ZB_CNTL, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_ZB_CNTL, 1)); cs_write_dword(cs, 0x0); - cs_write_dword(cs, cmdwait(R300_WAIT_3D)); - cs_write_dword(cs, cmdpacket0(R300_RB3D_DSTCACHE_CTLSTAT, 1)); + cs_write_dword(cs, cmdwait(csm->ctx->radeonScreen, R300_WAIT_3D)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_RB3D_DSTCACHE_CTLSTAT, 1)); cs_write_dword(cs, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); - cs_write_dword(cs, cmdpacket0(R300_ZB_ZCACHE_CTLSTAT, 1)); + cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen, + R300_ZB_ZCACHE_CTLSTAT, 1)); cs_write_dword(cs, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); - cs_write_dword(cs, cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN)); + cs_write_dword(cs, cmdwait(csm->ctx->radeonScreen, + R300_WAIT_3D | R300_WAIT_3D_CLEAN)); /* append buffer age */ age.scratch.cmd_type = R300_CMD_SCRATCH; @@ -318,8 +326,15 @@ static int cs_emit(struct radeon_cs *cs) } r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd)); + if (r) { + return r; + } cs_set_age(cs); - return r; + for (int i = 0; i < cs->cdw; i++) { + fprintf(stderr, "pkt[%04d]=0x%08X\n", i, cs->packets[i]); + } + exit(0); + return 0; } static int cs_destroy(struct radeon_cs *cs) @@ -374,3 +389,8 @@ struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx) csm->pending_age = 1; return (struct radeon_cs_manager*)csm; } + +void radeon_cs_manager_legacy_shutdown(struct radeon_cs_manager *csm) +{ + free(csm); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index 6ab384e978..cf0f20ec30 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -36,5 +36,6 @@ #include "radeon_context.h" struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx); +void radeon_cs_manager_legacy_shutdown(struct radeon_cs_manager *csm); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 861310de65..4f76fcf410 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -72,6 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "xmlpool.h" #include "radeon_bo_legacy.h" +#include "radeon_bo_gem.h" #if !RADEON_COMMON /* R100 */ PUBLIC const char __driConfigOptions[] = @@ -972,30 +973,100 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) return screen; } -/* Destroy the device specific screen private data struct. - */ -static void -radeonDestroyScreen( __DRIscreenPrivate *sPriv ) +static radeonScreenPtr +radeonCreateScreen2(__DRIscreenPrivate *sPriv) { - radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; + radeonScreenPtr screen; + int i; + + /* Allocate the private area */ + screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); + if ( !screen ) { + __driUtilMessage("%s: Could not allocate memory for screen structure", + __FUNCTION__); + fprintf(stderr, "leaving here\n"); + return NULL; + } + +#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control); +#endif + + /* parse information in __driConfigOptions */ + driParseOptionInfo (&screen->optionCache, + __driConfigOptions, __driNConfigOptions); + + screen->chip_flags = 0; + /* FIXME: do either an ioctl (bad) or a sysfs file for driver to + * information about which chipset is their */ + screen->chip_family = CHIP_FAMILY_RV350; + screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CLASS_R300; - if (!screen) - return; + i = 0; + screen->extensions[i++] = &driCopySubBufferExtension.base; + screen->extensions[i++] = &driFrameTrackingExtension.base; + screen->extensions[i++] = &driReadDrawableExtension; + + if ( screen->irq != 0 ) { + screen->extensions[i++] = &driSwapControlExtension.base; + screen->extensions[i++] = &driMediaStreamCounterExtension.base; + } + +#if !RADEON_COMMON + screen->extensions[i++] = &radeonTexOffsetExtension.base; +#endif - radeon_bo_manager_legacy_shutdown(screen->bom); +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) + if (IS_R200_CLASS(screen)) + screen->extensions[i++] = &r200AllocateExtension.base; + + screen->extensions[i++] = &r200texOffsetExtension.base; +#endif + +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + //screen->extensions[i++] = &r300texOffsetExtension.base; +#endif + + screen->extensions[i++] = NULL; + sPriv->extensions = screen->extensions; - if ( screen->gartTextures.map ) { - drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); + screen->driScreen = sPriv; + screen->bom = radeon_bo_manager_gem(sPriv->fd); + if (screen->bom == NULL) { + free(screen); + return NULL; } - drmUnmapBufs( screen->buffers ); - drmUnmap( screen->status.map, screen->status.size ); - drmUnmap( screen->mmio.map, screen->mmio.size ); + return screen; +} - /* free all option information */ - driDestroyOptionInfo (&screen->optionCache); +/* Destroy the device specific screen private data struct. + */ +static void +radeonDestroyScreen( __DRIscreenPrivate *sPriv ) +{ + radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; + + if (!screen) + return; + + if (sPriv->dri2.enabled) { + radeon_bo_manager_gem_shutdown(screen->bom); + } else { + radeon_bo_manager_legacy_shutdown(screen->bom); + + if ( screen->gartTextures.map ) { + drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); + } + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + } + + /* free all option information */ + driDestroyOptionInfo (&screen->optionCache); - FREE( screen ); - sPriv->private = NULL; + FREE( screen ); + sPriv->private = NULL; } @@ -1004,13 +1075,17 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) static GLboolean radeonInitDriver( __DRIscreenPrivate *sPriv ) { - sPriv->private = (void *) radeonCreateScreen( sPriv ); - if ( !sPriv->private ) { - radeonDestroyScreen( sPriv ); - return GL_FALSE; - } + if (sPriv->dri2.enabled) { + sPriv->private = (void *) radeonCreateScreen2( sPriv ); + } else { + sPriv->private = (void *) radeonCreateScreen( sPriv ); + } + if ( !sPriv->private ) { + radeonDestroyScreen( sPriv ); + return GL_FALSE; + } - return GL_TRUE; + return GL_TRUE; } #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) @@ -1130,6 +1205,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, struct radeon_renderbuffer *front = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base); + front->has_surface = 1; } /* back color renderbuffer */ @@ -1137,6 +1213,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, struct radeon_renderbuffer *back = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base); + back->has_surface = 1; } /* depth renderbuffer */ @@ -1144,7 +1221,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, struct radeon_renderbuffer *depth = radeon_create_renderbuffer(depthFormat, driDrawPriv); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base); - depth->depthHasSurface = screen->depthHasSurface; + depth->has_surface = screen->depthHasSurface; } /* stencil renderbuffer */ @@ -1152,7 +1229,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, struct radeon_renderbuffer *stencil = radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base); - stencil->depthHasSurface = screen->depthHasSurface; + stencil->has_surface = screen->depthHasSurface; } _mesa_add_soft_renderbuffers(fb, @@ -1227,7 +1304,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, driDrawPriv); radeonSetSpanFunctions(depthRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); - depthRb->depthHasSurface = screen->depthHasSurface; + depthRb->has_surface = screen->depthHasSurface; } else if (mesaVis->depthBits == 24) { driRenderbuffer *depthRb @@ -1238,7 +1315,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, driDrawPriv); radeonSetSpanFunctions(depthRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); - depthRb->depthHasSurface = screen->depthHasSurface; + depthRb->has_surface = screen->depthHasSurface; } /* stencil renderbuffer */ @@ -1251,7 +1328,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, driDrawPriv); radeonSetSpanFunctions(stencilRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); - stencilRb->depthHasSurface = screen->depthHasSurface; + stencilRb->has_surface = screen->depthHasSurface; } _mesa_add_soft_renderbuffers(fb, @@ -1369,6 +1446,45 @@ radeonInitScreen(__DRIscreenPrivate *psp) (dri_priv->bpp == 16) ? 0 : 8, 1); } +/** + * This is the driver specific part of the createNewScreen entry point. + * Called when using DRI2. + * + * \return the __GLcontextModes supported by this driver + */ +static const +__DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) +{ + fprintf(stderr, "DRI2 initialization\n"); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) + driInitExtensions( NULL, blend_extensions, GL_FALSE ); + driInitSingleExtension( NULL, ARB_vp_extension ); + driInitSingleExtension( NULL, NV_vp_extension ); + driInitSingleExtension( NULL, ATI_fs_extension ); + driInitExtensions( NULL, point_extensions, GL_FALSE ); +#endif + + if (!radeonInitDriver(psp)) { + return NULL; + } + + fprintf(stderr, "DRI2 initialized\n"); + + /* for now fill in all modes */ + return radeonFillInModes( psp, 24, 24, 8, 1); +} /** * Get information about previous buffer swaps. @@ -1417,6 +1533,8 @@ const struct __DriverAPIRec driDriverAPI = { .WaitForSBC = NULL, .SwapBuffersMSC = NULL, .CopySubBuffer = radeonCopySubBuffer, + /* DRI2 */ + .InitScreen2 = radeonInitScreen2, }; #else const struct __DriverAPIRec driDriverAPI = { -- cgit v1.2.3 From 56c458e0f2027bc19b45ed3112e84b6ace67920f Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 15 Nov 2008 10:40:32 +0100 Subject: radeon: update to libdrm-radeon API changes --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 8 ++++---- src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 16 +++++++++------- src/mesa/drivers/dri/radeon/radeon_bo_legacy.h | 4 ++-- src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 4 ++-- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 4 ++-- src/mesa/drivers/dri/radeon/radeon_screen.c | 8 ++++---- 6 files changed, 23 insertions(+), 21 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 517860da43..b8740e298b 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -746,9 +746,9 @@ void r300InitCmdBuf(r300ContextPtr r300) if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { int fd = r300->radeon.radeonScreen->driScreen->fd; - r300->cmdbuf.csm = radeon_cs_manager_gem(fd); + r300->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); } else { - r300->cmdbuf.csm = radeon_cs_manager_legacy(&r300->radeon); + r300->cmdbuf.csm = radeon_cs_manager_legacy_ctor(&r300->radeon); } if (r300->cmdbuf.csm == NULL) { /* FIXME: fatal error */ @@ -771,8 +771,8 @@ void r300DestroyCmdBuf(r300ContextPtr r300) FREE(atom->cmd); } if (r300->radeon.radeonScreen->driScreen->dri2.enabled) { - radeon_cs_manager_gem_shutdown(r300->cmdbuf.csm); + radeon_cs_manager_gem_dtor(r300->cmdbuf.csm); } else { - radeon_cs_manager_legacy_shutdown(r300->cmdbuf.csm); + radeon_cs_manager_legacy_dtor(r300->cmdbuf.csm); } } diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index d57b19de8d..3aa1d869f1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -407,7 +407,7 @@ static void bo_ref(struct radeon_bo *bo) { } -static void bo_unref(struct radeon_bo *bo) +static struct radeon_bo *bo_unref(struct radeon_bo *bo) { struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -419,7 +419,9 @@ static void bo_unref(struct radeon_bo *bo) if (!bo_legacy->is_pending) { bo_free(bo_legacy); } + return NULL; } + return bo; } static int bo_map(struct radeon_bo *bo, int write) @@ -589,7 +591,7 @@ void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending) boml->cpendings++; } -void radeon_bo_manager_legacy_shutdown(struct radeon_bo_manager *bom) +void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom; struct bo_legacy *bo_legacy; @@ -609,7 +611,7 @@ void radeon_bo_manager_legacy_shutdown(struct radeon_bo_manager *bom) free(boml); } -struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) +struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn) { struct bo_manager_legacy *bom; struct bo_legacy *bo; @@ -646,7 +648,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) bom->nfree_handles = 0x400; bom->free_handles = (uint32_t*)malloc(bom->nfree_handles * 4); if (bom->free_handles == NULL) { - radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); + radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); return NULL; } @@ -655,7 +657,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) /* allocate front */ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { - radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); + radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); return NULL; } if (scrn->sarea->tiling_enabled) { @@ -671,7 +673,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) /* allocate back */ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { - radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); + radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); return NULL; } if (scrn->sarea->tiling_enabled) { @@ -687,7 +689,7 @@ struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn) /* allocate depth */ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); if (bo == NULL) { - radeon_bo_manager_legacy_shutdown((struct radeon_bo_manager*)bom); + radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom); return NULL; } bo->base.flags = 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h index 316b023fb0..208171e372 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h @@ -39,8 +39,8 @@ void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending); int radeon_bo_legacy_validate(struct radeon_bo *bo, uint32_t *soffset, uint32_t *eoffset); -struct radeon_bo_manager *radeon_bo_manager_legacy(struct radeon_screen *scrn); -void radeon_bo_manager_legacy_shutdown(struct radeon_bo_manager *bom); +struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn); +void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom); void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom); unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo); diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index b69537bc65..6bc41bca3b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -397,7 +397,7 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = { cs_need_flush }; -struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx) +struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx) { struct cs_manager_legacy *csm; @@ -413,7 +413,7 @@ struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx) return (struct radeon_cs_manager*)csm; } -void radeon_cs_manager_legacy_shutdown(struct radeon_cs_manager *csm) +void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm) { free(csm); } diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index cf0f20ec30..71a4dad58d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -35,7 +35,7 @@ #include "radeon_cs.h" #include "radeon_context.h" -struct radeon_cs_manager *radeon_cs_manager_legacy(struct radeon_context *ctx); -void radeon_cs_manager_legacy_shutdown(struct radeon_cs_manager *csm); +struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); +void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 93131d269c..79cc4c8c8e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -973,7 +973,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->sarea_priv_offset = dri_priv->sarea_priv_offset; screen->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + screen->sarea_priv_offset); - screen->bom = radeon_bo_manager_legacy(screen); + screen->bom = radeon_bo_manager_legacy_ctor(screen); if (screen->bom == NULL) { free(screen); return NULL; @@ -1040,7 +1040,7 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv) sPriv->extensions = screen->extensions; screen->driScreen = sPriv; - screen->bom = radeon_bo_manager_gem(sPriv->fd); + screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd); if (screen->bom == NULL) { free(screen); return NULL; @@ -1060,9 +1060,9 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) if (sPriv->dri2.enabled) { radeon_tracker_print(&screen->bom->tracker, stderr); - radeon_bo_manager_gem_shutdown(screen->bom); + radeon_bo_manager_gem_dtor(screen->bom); } else { - radeon_bo_manager_legacy_shutdown(screen->bom); + radeon_bo_manager_legacy_dtor(screen->bom); if ( screen->gartTextures.map ) { drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); -- cgit v1.2.3 From 61da612a4f8862e0aac4ff4fc87c133cb8a1c4a5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 Jan 2009 15:12:57 +1000 Subject: r300: start moving new r300 cmdbuf into common code --- src/mesa/drivers/dri/r200/Makefile | 2 + src/mesa/drivers/dri/r200/r200_state.c | 4 +- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 108 +++--------------------- src/mesa/drivers/dri/r300/r300_cmdbuf.h | 13 ++- src/mesa/drivers/dri/r300/r300_context.c | 3 +- src/mesa/drivers/dri/r300/r300_context.h | 17 +--- src/mesa/drivers/dri/r300/r300_ioctl.c | 6 +- src/mesa/drivers/dri/r300/r300_render.c | 10 +-- src/mesa/drivers/dri/r300/r300_swtcl.c | 6 +- src/mesa/drivers/dri/r300/radeon_context.h | 1 - src/mesa/drivers/dri/r300/radeon_lock.h | 74 +--------------- src/mesa/drivers/dri/radeon/common_context.h | 29 +++++-- src/mesa/drivers/dri/radeon/common_lock.c | 2 +- src/mesa/drivers/dri/radeon/common_lock.h | 23 +++-- src/mesa/drivers/dri/radeon/common_misc.c | 112 ++++++++++++++++++++++++- src/mesa/drivers/dri/radeon/common_misc.h | 6 ++ src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 1 + 18 files changed, 194 insertions(+), 225 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 34aa74735b..5ba1603d79 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -51,6 +51,7 @@ COMMON_SYMLINKS = \ radeon_screen.c \ radeon_screen.h \ radeon_bo_legacy.h \ + radeon_cs_legacy.h \ radeon_buffer.h \ common_context.h \ common_lock.c \ @@ -58,6 +59,7 @@ COMMON_SYMLINKS = \ common_misc.h \ common_misc.c + ##### TARGETS ##### diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 67357fadfd..997c1711f9 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -1711,7 +1711,7 @@ void r200UpdateViewportOffset( GLcontext *ctx ) } } - r200UpdateScissor( ctx ); + radeonUpdateScissor( ctx ); } @@ -2056,7 +2056,7 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_SCISSOR_TEST: R200_FIREVERTICES( rmesa ); rmesa->radeon.state.scissor.enabled = state; - r200UpdateScissor( ctx ); + radeonUpdateScissor( ctx ); break; case GL_STENCIL_TEST: diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 32d0dcf547..bbca71dd16 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -69,70 +69,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define SPACE_FOR_FLUSHING 4 -/** - * Send the current command buffer via ioctl to the hardware. - */ -int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller) -{ - int ret = 0; - - if (r300->cmdbuf.flushing) { - fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); - exit(-1); - } - r300->cmdbuf.flushing = 1; - if (r300->cmdbuf.cs->cdw) { - ret = radeon_cs_emit(r300->cmdbuf.cs); - r300->hw.all_dirty = 1; - } - radeon_cs_erase(r300->cmdbuf.cs); - r300->cmdbuf.flushing = 0; - return ret; -} - -int r300FlushCmdBuf(r300ContextPtr r300, const char *caller) -{ - int ret; - - LOCK_HARDWARE(&r300->radeon); - ret = r300FlushCmdBufLocked(r300, caller); - UNLOCK_HARDWARE(&r300->radeon); - - if (ret) { - fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); - _mesa_exit(ret); - } - - return ret; -} - -/** - * Make sure that enough space is available in the command buffer - * by flushing if necessary. - * - * \param dwords The number of dwords we need to be free on the command buffer - */ -void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller) -{ - if ((r300->cmdbuf.cs->cdw + dwords + 128) > r300->cmdbuf.size || - radeon_cs_need_flush(r300->cmdbuf.cs)) { - r300FlushCmdBuf(r300, caller); - } -} - void r300BeginBatch(r300ContextPtr r300, int n, int dostate, const char *file, const char *function, int line) { - r300EnsureCmdBufSpace(r300, n, function); - if (!r300->cmdbuf.cs->cdw && dostate) { + rcommonEnsureCmdBufSpace(&r300->radeon, n, function); + if (!r300->radeon.cmdbuf.cs->cdw && dostate) { if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "Reemit state after flush (from %s)\n", function); r300EmitState(r300); } - radeon_cs_begin(r300->cmdbuf.cs, n, file, function, line); + radeon_cs_begin(r300->radeon.cmdbuf.cs, n, file, function, line); } static void r300PrintStateAtom(r300ContextPtr r300, @@ -209,15 +158,15 @@ void r300EmitState(r300ContextPtr r300) if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS)) fprintf(stderr, "%s\n", __FUNCTION__); - if (r300->cmdbuf.cs->cdw && !r300->hw.is_dirty && !r300->hw.all_dirty) + if (r300->radeon.cmdbuf.cs->cdw && !r300->hw.is_dirty && !r300->hw.all_dirty) return; /* To avoid going across the entire set of states multiple times, just check * for enough space for the case of emitting all state. */ - r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__); + rcommonEnsureCmdBufSpace(&r300->radeon, r300->hw.max_state_size, __FUNCTION__); - if (!r300->cmdbuf.cs->cdw) { + if (!r300->radeon.cmdbuf.cs->cdw) { if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "Begin reemit state\n"); @@ -473,7 +422,7 @@ int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom) */ void r300InitCmdBuf(r300ContextPtr r300) { - int size, mtu; + int mtu; int has_tcl = 1; int is_r500 = 0; int i; @@ -770,40 +719,7 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.is_dirty = GL_TRUE; r300->hw.all_dirty = GL_TRUE; - /* Initialize command buffer */ - size = - 256 * driQueryOptioni(&r300->radeon.optionCache, - "command_buffer_size"); - if (size < 2 * r300->hw.max_state_size) { - size = 2 * r300->hw.max_state_size + 65535; - } - if (size > 64 * 256) - size = 64 * 256; - - size = 64 * 1024 / 4; - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { - fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", - sizeof(drm_r300_cmd_header_t)); - fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", - sizeof(drm_radeon_cmd_buffer_t)); - fprintf(stderr, - "Allocating %d bytes command buffer (max state is %d bytes)\n", - size * 4, r300->hw.max_state_size * 4); - } - - if (r300->radeon.radeonScreen->kernel_mm) { - int fd = r300->radeon.radeonScreen->driScreen->fd; - r300->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); - } else { - r300->cmdbuf.csm = radeon_cs_manager_legacy_ctor(&r300->radeon); - } - if (r300->cmdbuf.csm == NULL) { - /* FIXME: fatal error */ - return; - } - r300->cmdbuf.cs = radeon_cs_create(r300->cmdbuf.csm, size); - assert(r300->cmdbuf.cs != NULL); - r300->cmdbuf.size = size; + rcommonInitCmdBuf(&r300->radeon, r300->hw.max_state_size); } /** @@ -813,13 +729,9 @@ void r300DestroyCmdBuf(r300ContextPtr r300) { struct radeon_state_atom *atom; - radeon_cs_destroy(r300->cmdbuf.cs); foreach(atom, &r300->hw.atomlist) { FREE(atom->cmd); } - if (r300->radeon.radeonScreen->driScreen->dri2.enabled || r300->radeon.radeonScreen->kernel_mm) { - radeon_cs_manager_gem_dtor(r300->cmdbuf.csm); - } else { - radeon_cs_manager_legacy_dtor(r300->cmdbuf.csm); - } + rcommonDestroyCmdBuf(&r300->radeon); + } diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index f4cc5d3bb1..0c76c6c99a 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -39,14 +39,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_context.h" #include "radeon_cs.h" -extern int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller); -extern int r300FlushCmdBuf(r300ContextPtr r300, const char *caller); extern void r300EmitState(r300ContextPtr r300); extern void r300InitCmdBuf(r300ContextPtr r300); extern void r300DestroyCmdBuf(r300ContextPtr r300); -extern void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller); void r300BeginBatch(r300ContextPtr r300, int n, @@ -78,7 +75,7 @@ void r300BeginBatch(r300ContextPtr r300, */ #define OUT_BATCH(data) \ do { \ - radeon_cs_write_dword(b_l_r300->cmdbuf.cs, data);\ + radeon_cs_write_dword(b_l_r300->radeon.cmdbuf.cs, data);\ } while(0) /** @@ -90,8 +87,8 @@ void r300BeginBatch(r300ContextPtr r300, fprintf(stderr, "(%s:%s:%d) offset : %d\n",\ __FILE__, __FUNCTION__, __LINE__, offset);\ }\ - radeon_cs_write_dword(b_l_r300->cmdbuf.cs, offset);\ - radeon_cs_write_reloc(b_l_r300->cmdbuf.cs, \ + radeon_cs_write_dword(b_l_r300->radeon.cmdbuf.cs, offset);\ + radeon_cs_write_reloc(b_l_r300->radeon.cmdbuf.cs, \ bo, \ rd, \ wd, \ @@ -105,7 +102,7 @@ void r300BeginBatch(r300ContextPtr r300, do { \ int _i; \ for (_i=0; _i < n; _i++) {\ - radeon_cs_write_dword(b_l_r300->cmdbuf.cs, ptr[_i]);\ + radeon_cs_write_dword(b_l_r300->radeon.cmdbuf.cs, ptr[_i]);\ }\ } while(0) @@ -116,7 +113,7 @@ void r300BeginBatch(r300ContextPtr r300, */ #define END_BATCH() \ do { \ - radeon_cs_end(b_l_r300->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ + radeon_cs_end(b_l_r300->radeon.cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ } while(0) /** diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 974cf5fcef..6b79e7dea3 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -65,6 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_tex.h" #include "r300_emit.h" #include "r300_swtcl.h" +#include "radeon_bo_legacy.h" #include "vblank.h" @@ -443,7 +444,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) _vbo_DestroyContext(r300->radeon.glCtx); _swrast_DestroyContext(r300->radeon.glCtx); - r300FlushCmdBuf(r300, __FUNCTION__); + rcommonFlushCmdBuf(&r300->radeon, __FUNCTION__); r300DestroyCmdBuf(r300); if (radeon->state.scissor.pClipRects) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index de188c3f36..1a430169f5 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_drm.h" #include "dri_util.h" #include "texmem.h" +#include "radeon_context.h" #include "radeon_bo.h" #include "main/macros.h" @@ -504,20 +505,6 @@ struct r300_hw_state { r300TexObj *textures[R300_MAX_TEXTURE_UNITS]; }; -/** - * This structure holds the command buffer while it is being constructed. - * - * The first batch of commands in the buffer is always the state that needs - * to be re-emitted when the context is lost. This batch can be skipped - * otherwise. - */ -struct r300_cmdbuf { - struct radeon_cs_manager *csm; - struct radeon_cs *cs; - int size; /** # of dwords total */ - unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ -}; - /** * State cache */ @@ -838,7 +825,7 @@ struct r300_context { struct radeon_context radeon; /* parent class, must be first */ struct r300_hw_state hw; - struct r300_cmdbuf cmdbuf; + struct r300_state state; struct gl_vertex_program *curr_vp; struct r300_vertex_program *selected_vp; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index e70e5f6d52..63989636c2 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -589,7 +589,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) } /* Make sure it fits there. */ - r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__); + rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; @@ -623,8 +623,8 @@ void r300Flush(GLcontext * ctx) rmesa->swtcl.flush(rmesa); } - if (rmesa->cmdbuf.cs->cdw) { - r300FlushCmdBuf(rmesa, __FUNCTION__); + if (rmesa->radeon.cmdbuf.cs->cdw) { + rcommonFlushCmdBuf(&rmesa->radeon, __FUNCTION__); } } diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index ccc00b381f..cb6652fabe 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -212,7 +212,7 @@ static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type) OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2); OUT_BATCH(rmesa->state.elt_dma_offset); OUT_BATCH(vertex_count); - radeon_cs_write_reloc(rmesa->cmdbuf.cs, + radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, rmesa->state.elt_dma_bo, RADEON_GEM_DOMAIN_GTT, 0, 0); } @@ -295,13 +295,13 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) for (i = 0; i + 1 < nr; i += 2) { voffset = rmesa->state.aos[i + 0].offset + offset * 4 * rmesa->state.aos[i + 0].stride; - radeon_cs_write_reloc(rmesa->cmdbuf.cs, + radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, rmesa->state.aos[i+0].bo, RADEON_GEM_DOMAIN_GTT, 0, 0); voffset = rmesa->state.aos[i + 1].offset + offset * 4 * rmesa->state.aos[i + 1].stride; - radeon_cs_write_reloc(rmesa->cmdbuf.cs, + radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, rmesa->state.aos[i+1].bo, RADEON_GEM_DOMAIN_GTT, 0, 0); @@ -309,7 +309,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) if (nr & 1) { voffset = rmesa->state.aos[nr - 1].offset + offset * 4 * rmesa->state.aos[nr - 1].stride; - radeon_cs_write_reloc(rmesa->cmdbuf.cs, + radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, rmesa->state.aos[nr-1].bo, RADEON_GEM_DOMAIN_GTT, 0, 0); @@ -346,7 +346,7 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, * This is supposed to ensure that we can get all rendering * commands into a single command buffer. */ - r300EnsureCmdBufSpace(rmesa, 64, __FUNCTION__); + rcommonEnsureCmdBufSpace(&rmesa->radeon, 64, __FUNCTION__); if (vb->Elts) { if (num_verts > 65535) { diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index fbfa8f452b..0108f7cf6a 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -247,9 +247,9 @@ static void flush_last_swtcl_prim( r300ContextPtr rmesa ) fprintf(stderr, "%s\n", __FUNCTION__); rmesa->swtcl.flush = NULL; radeon_bo_unmap(rmesa->swtcl.bo); - r300EnsureCmdBufSpace(rmesa, - rmesa->hw.max_state_size + (12*sizeof(int)), - __FUNCTION__); + rcommonEnsureCmdBufSpace(rmesa, + rmesa->hw.max_state_size + (12*sizeof(int)), + __FUNCTION__); r300EmitState(rmesa); r300EmitVertexAOS(rmesa, rmesa->swtcl.vertex_size, diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index be21a8cfbc..736bf7c649 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -50,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_util.h" #include "radeon_screen.h" -#include "common_context.h" #include "common_misc.h" #if R200_MERGED diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h index eaef49c325..f2d17a54d4 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.h +++ b/src/mesa/drivers/dri/r300/radeon_lock.h @@ -42,78 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_LOCK_H__ #define __RADEON_LOCK_H__ -#include "radeon_context.h" - -extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); -extern void radeonUpdatePageFlipping(radeonContextPtr rmesa); - -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if (prevLockFile) { \ - fprintf(stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__); \ - exit(1); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_CAS((rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret); \ - if (__ret) \ - radeonGetLock((rmesa), 0); \ - }\ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_UNLOCK((rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext); \ - DEBUG_RESET(); \ - }\ - } while (0) +#include "common_lock.h" #endif /* __RADEON_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index e4d210392c..eb95dc9d75 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -1,6 +1,14 @@ #ifndef COMMON_CONTEXT_H #define COMMON_CONTEXT_H + +#include "main/mm.h" +#include "math/m_vector.h" +#include "texmem.h" +#include "tnl/t_context.h" +#include "main/colormac.h" + + /* This union is used to avoid warnings/miscompilation with float to uint32_t casts due to strict-aliasing */ typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; @@ -9,11 +17,6 @@ struct radeon_context; typedef struct radeon_context radeonContextRec; typedef struct radeon_context *radeonContextPtr; -#include "main/mm.h" -#include "math/m_vector.h" -#include "texmem.h" -#include "tnl/t_context.h" - #define TEX_0 0x1 #define TEX_1 0x2 @@ -256,6 +259,20 @@ struct radeon_state { struct radeon_stencilbuffer_state stencil; }; +/** + * This structure holds the command buffer while it is being constructed. + * + * The first batch of commands in the buffer is always the state that needs + * to be re-emitted when the context is lost. This batch can be skipped + * otherwise. + */ +struct radeon_cmdbuf { + struct radeon_cs_manager *csm; + struct radeon_cs *cs; + int size; /** # of dwords total */ + unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ +}; + struct radeon_context { GLcontext *glCtx; radeonScreenPtr radeonScreen; /* Screen private DRI data */ @@ -308,6 +325,8 @@ struct radeon_context { */ driOptionCache optionCache; + struct radeon_cmdbuf cmdbuf; + struct { void (*get_lock)(radeonContextPtr radeon); void (*update_viewport_offset)(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/radeon/common_lock.c b/src/mesa/drivers/dri/radeon/common_lock.c index d983e8ce92..09517450a9 100644 --- a/src/mesa/drivers/dri/radeon/common_lock.c +++ b/src/mesa/drivers/dri/radeon/common_lock.c @@ -84,7 +84,7 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa) #else /* Turn on/off page flipping according to the flags in the sarea: */ -static void radeonUpdatePageFlipping(radeonContextPtr rmesa) +void radeonUpdatePageFlipping(radeonContextPtr rmesa) { rmesa->doPageFlip = rmesa->sarea->pfState; if (rmesa->glCtx->WinSysDrawBuffer) { diff --git a/src/mesa/drivers/dri/radeon/common_lock.h b/src/mesa/drivers/dri/radeon/common_lock.h index 50a4a0b05a..431b076f02 100644 --- a/src/mesa/drivers/dri/radeon/common_lock.h +++ b/src/mesa/drivers/dri/radeon/common_lock.h @@ -41,6 +41,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef COMMON_LOCK_H #define COMMON_LOCK_H + +#include "main/colormac.h" +#include "radeon_screen.h" +#include "common_context.h" + extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); /* Turn DEBUG_LOCKING on to find locking conflicts. @@ -93,19 +98,23 @@ extern int prevLockLine; do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ - if ( __ret ) \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ + if ( __ret ) \ radeonGetLock( (rmesa), 0 ); \ + } \ DEBUG_LOCK(); \ } while (0) #define UNLOCK_HARDWARE( rmesa ) \ do { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ - DEBUG_RESET(); \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_UNLOCK( (rmesa)->dri.fd, \ + (rmesa)->dri.hwLock, \ + (rmesa)->dri.hwContext ); \ + DEBUG_RESET(); \ + } \ } while (0) #endif diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index eab9cc74e3..ba3c76daa9 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -51,11 +51,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" #include "vblank.h" - +#include "radeon_bo.h" +#include "radeon_cs.h" +#include "radeon_bo_legacy.h" +#include "radeon_cs_legacy.h" +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" #include "dri_util.h" #include "radeon_drm.h" -#include "radeon_screen.h" #include "radeon_buffer.h" +#include "radeon_screen.h" #include "common_context.h" #include "common_misc.h" #include "common_lock.h" @@ -577,3 +582,106 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, } } +/* cmdbuffer */ +/** + * Send the current command buffer via ioctl to the hardware. + */ +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) +{ + int ret = 0; + + if (rmesa->cmdbuf.flushing) { + fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); + exit(-1); + } + rmesa->cmdbuf.flushing = 1; + if (rmesa->cmdbuf.cs->cdw) { + ret = radeon_cs_emit(rmesa->cmdbuf.cs); + rmesa->vtbl.set_all_dirty(rmesa->glCtx); + } + radeon_cs_erase(rmesa->cmdbuf.cs); + rmesa->cmdbuf.flushing = 0; + return ret; +} + +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) +{ + int ret; + + LOCK_HARDWARE(rmesa); + ret = rcommonFlushCmdBufLocked(rmesa, caller); + UNLOCK_HARDWARE(rmesa); + + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + _mesa_exit(ret); + } + + return ret; +} + +/** + * Make sure that enough space is available in the command buffer + * by flushing if necessary. + * + * \param dwords The number of dwords we need to be free on the command buffer + */ +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) +{ + if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || + radeon_cs_need_flush(rmesa->cmdbuf.cs)) { + rcommonFlushCmdBuf(rmesa, caller); + } +} + +void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size) +{ + GLuint size; + /* Initialize command buffer */ + size = 256 * driQueryOptioni(&rmesa->optionCache, + "command_buffer_size"); + if (size < 2 * max_state_size) { + size = 2 * max_state_size + 65535; + } + if (size > 64 * 256) + size = 64 * 256; + + size = 64 * 1024 / 4; + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { + fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", + sizeof(drm_r300_cmd_header_t)); + fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", + sizeof(drm_radeon_cmd_buffer_t)); + fprintf(stderr, + "Allocating %d bytes command buffer (max state is %d bytes)\n", + size * 4, max_state_size * 4); + } + + if (rmesa->radeonScreen->kernel_mm) { + int fd = rmesa->radeonScreen->driScreen->fd; + rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); + } else { + rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); + } + if (rmesa->cmdbuf.csm == NULL) { + /* FIXME: fatal error */ + return; + } + rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); + assert(rmesa->cmdbuf.cs != NULL); + rmesa->cmdbuf.size = size; + +} +/** + * Destroy the command buffer + */ +void rcommonDestroyCmdBuf(radeonContextPtr rmesa) +{ + radeon_cs_destroy(rmesa->cmdbuf.cs); + if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { + radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); + } else { + radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); + } +} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h index cc4832c75e..7057ad941f 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -1,6 +1,7 @@ #ifndef COMMON_MISC_H #define COMMON_MISC_H +#include "common_context.h" void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); @@ -17,4 +18,9 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, void radeonUpdatePageFlipping(radeonContextPtr rmesa); +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); +void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size); +void rcommonDestroyCmdBuf(radeonContextPtr rmesa); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index 71a4dad58d..4da2479eee 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -33,7 +33,7 @@ #define RADEON_CS_LEGACY_H #include "radeon_cs.h" -#include "radeon_context.h" +#include "common_context.h" struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index c099d0ee34..e655408338 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" #include "radeon_screen.h" #include "radeon_buffer.h" +#include "common_misc.h" #if !RADEON_COMMON #include "radeon_context.h" #include "radeon_span.h" -- cgit v1.2.3 From 23d3559bd4ece1fcab5513ebdaa38600d6654374 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Feb 2009 22:38:10 +1000 Subject: radeon: renaming and headers cleanup --- src/mesa/drivers/dri/radeon/Makefile | 17 +- src/mesa/drivers/dri/radeon/common_cmdbuf.h | 143 -- src/mesa/drivers/dri/radeon/common_context.h | 502 ---- src/mesa/drivers/dri/radeon/common_lock.c | 126 - src/mesa/drivers/dri/radeon/common_lock.h | 120 - src/mesa/drivers/dri/radeon/common_misc.c | 2715 -------------------- src/mesa/drivers/dri/radeon/common_misc.h | 166 -- src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 2 +- src/mesa/drivers/dri/radeon/radeon_cmdbuf.h | 143 ++ src/mesa/drivers/dri/radeon/radeon_common.c | 843 ++++++ src/mesa/drivers/dri/radeon/radeon_common.h | 56 + .../drivers/dri/radeon/radeon_common_context.c | 584 +++++ .../drivers/dri/radeon/radeon_common_context.h | 513 ++++ src/mesa/drivers/dri/radeon/radeon_context.c | 42 +- src/mesa/drivers/dri/radeon/radeon_context.h | 3 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 4 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 2 +- src/mesa/drivers/dri/radeon/radeon_dma.c | 323 +++ src/mesa/drivers/dri/radeon/radeon_dma.h | 51 + src/mesa/drivers/dri/radeon/radeon_ioctl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_lock.c | 124 + src/mesa/drivers/dri/radeon/radeon_lock.h | 81 +- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 4 +- src/mesa/drivers/dri/radeon/radeon_span.c | 226 +- src/mesa/drivers/dri/radeon/radeon_state.c | 1 - src/mesa/drivers/dri/radeon/radeon_state_init.c | 1 - src/mesa/drivers/dri/radeon/radeon_swtcl.c | 1 - src/mesa/drivers/dri/radeon/radeon_tcl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_texture.c | 849 ++++++ src/mesa/drivers/dri/radeon/radeon_texture.h | 108 + 31 files changed, 3916 insertions(+), 3840 deletions(-) delete mode 100644 src/mesa/drivers/dri/radeon/common_cmdbuf.h delete mode 100644 src/mesa/drivers/dri/radeon/common_context.h delete mode 100644 src/mesa/drivers/dri/radeon/common_lock.c delete mode 100644 src/mesa/drivers/dri/radeon/common_lock.h delete mode 100644 src/mesa/drivers/dri/radeon/common_misc.c delete mode 100644 src/mesa/drivers/dri/radeon/common_misc.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_cmdbuf.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_common.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_common.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_common_context.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_common_context.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_dma.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_dma.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_lock.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_texture.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_texture.h (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 2d00f521a6..16bc063baf 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -8,6 +8,16 @@ LIBNAME = radeon_dri.so MINIGLX_SOURCES = server/radeon_dri.c +RADEON_COMMON_SOURCES = \ + radeon_texture.c \ + radeon_common_context.c \ + radeon_dma.c \ + radeon_lock.c \ + radeon_bo_legacy.c \ + radeon_cs_legacy.c \ + radeon_mipmap_tree.c \ + radeon_span.c + DRIVER_SOURCES = \ radeon_context.c \ radeon_ioctl.c \ @@ -18,14 +28,9 @@ DRIVER_SOURCES = \ radeon_texstate.c \ radeon_tcl.c \ radeon_swtcl.c \ - radeon_span.c \ radeon_maos.c \ radeon_sanity.c \ - common_lock.c \ - common_misc.c \ - radeon_bo_legacy.c \ - radeon_cs_legacy.c \ - radeon_mipmap_tree.c + $(RADEON_COMMON_SOURCES) C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/radeon/common_cmdbuf.h b/src/mesa/drivers/dri/radeon/common_cmdbuf.h deleted file mode 100644 index 5526934209..0000000000 --- a/src/mesa/drivers/dri/radeon/common_cmdbuf.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef COMMON_CMDBUF_H -#define COMMON_CMDBUF_H - -#include "radeon_cs.h" - -void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); -int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); -int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); -void rcommonInitCmdBuf(radeonContextPtr rmesa); -void rcommonDestroyCmdBuf(radeonContextPtr rmesa); - -void rcommonBeginBatch(radeonContextPtr rmesa, - int n, - int dostate, - const char *file, - const char *function, - int line); - -#define RADEON_CP_PACKET3_NOP 0xC0001000 -#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 -#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 -#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 -#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 -#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 -#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 -#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 -#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 -#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 -#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 -#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 -#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 -#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 -#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 -#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 -#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 -#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 -#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 -#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 -#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 - -#define CP_PACKET2 (2 << 30) -#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) -#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) -#define CP_PACKET3( pkt, n ) \ - (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) - -/** - * Every function writing to the command buffer needs to declare this - * to get the necessary local variables. - */ -#define BATCH_LOCALS(rmesa) \ - const radeonContextPtr b_l_rmesa = rmesa - -/** - * Prepare writing n dwords to the command buffer, - * including producing any necessary state emits on buffer wraparound. - */ -#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__) - -/** - * Same as BEGIN_BATCH, but do not cause automatic state emits. - */ -#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__) - -/** - * Write one dword to the command buffer. - */ -#define OUT_BATCH(data) \ - do { \ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ - } while(0) - -/** - * Write a relocated dword to the command buffer. - */ -#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ - do { \ - if (0 && offset) { \ - fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ - __FILE__, __FUNCTION__, __LINE__, offset); \ - } \ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \ - radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ - bo, rd, wd, flags); \ - if (!b_l_rmesa->radeonScreen->kernel_mm) \ - b_l_rmesa->cmdbuf.cs->section_cdw += 2; \ - } while(0) - - -/** - * Write n dwords from ptr to the command buffer. - */ -#define OUT_BATCH_TABLE(ptr,n) \ - do { \ - int _i; \ - for (_i=0; _i < n; _i++) {\ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\ - }\ - } while(0) - -/** - * Finish writing dwords to the command buffer. - * The number of (direct or indirect) OUT_BATCH calls between the previous - * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. - */ -#define END_BATCH() \ - do { \ - radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ - } while(0) - -/** - * After the last END_BATCH() of rendering, this indicates that flushing - * the command buffer now is okay. - */ -#define COMMIT_BATCH() \ - do { \ - } while(0) - - -/** Single register write to command buffer; requires 2 dwords. */ -#define OUT_BATCH_REGVAL(reg, val) \ - OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ - OUT_BATCH((val)) - -/** Continuous register range write to command buffer; requires 1 dword, - * expects count dwords afterwards for register contents. */ -#define OUT_BATCH_REGSEQ(reg, count) \ - OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))); - -/** Write a 32 bit float to the ring; requires 1 dword. */ -#define OUT_BATCH_FLOAT32(f) \ - OUT_BATCH(radeonPackFloat32((f))); - - -/* Fire the buffered vertices no matter what. - */ -static INLINE void radeon_firevertices(radeonContextPtr radeon) -{ - if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) - radeonFlush(radeon->glCtx); -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h deleted file mode 100644 index c3a445e0d2..0000000000 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ /dev/null @@ -1,502 +0,0 @@ - -#ifndef COMMON_CONTEXT_H -#define COMMON_CONTEXT_H - -#include "main/mm.h" -#include "math/m_vector.h" -#include "texmem.h" -#include "tnl/t_context.h" -#include "main/colormac.h" - -#include "radeon_screen.h" -#include "radeon_drm.h" -#include "dri_util.h" -#include "tnl/t_vertex.h" - -/* This union is used to avoid warnings/miscompilation - with float to uint32_t casts due to strict-aliasing */ -typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; - -struct radeon_context; -typedef struct radeon_context radeonContextRec; -typedef struct radeon_context *radeonContextPtr; - - -#define TEX_0 0x1 -#define TEX_1 0x2 -#define TEX_2 0x4 -#define TEX_3 0x8 -#define TEX_4 0x10 -#define TEX_5 0x20 - -/* Rasterizing fallbacks */ -/* See correponding strings in r200_swtcl.c */ -#define RADEON_FALLBACK_TEXTURE 0x0001 -#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 -#define RADEON_FALLBACK_STENCIL 0x0004 -#define RADEON_FALLBACK_RENDER_MODE 0x0008 -#define RADEON_FALLBACK_BLEND_EQ 0x0010 -#define RADEON_FALLBACK_BLEND_FUNC 0x0020 -#define RADEON_FALLBACK_DISABLE 0x0040 -#define RADEON_FALLBACK_BORDER_MODE 0x0080 - -#define R200_FALLBACK_TEXTURE 0x01 -#define R200_FALLBACK_DRAW_BUFFER 0x02 -#define R200_FALLBACK_STENCIL 0x04 -#define R200_FALLBACK_RENDER_MODE 0x08 -#define R200_FALLBACK_DISABLE 0x10 -#define R200_FALLBACK_BORDER_MODE 0x20 - -#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ -#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ -#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ -#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ -#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ -#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ -#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ -#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ -#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ - -/* The blit width for texture uploads - */ -#define BLIT_WIDTH_BYTES 1024 - -/* Use the templated vertex format: - */ -#define COLOR_IS_RGBA -#define TAG(x) radeon##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -struct radeon_colorbuffer_state { - GLuint clear; - int roundEnable; - struct radeon_renderbuffer *rrb; -}; - -struct radeon_depthbuffer_state { - GLuint clear; - GLfloat scale; - struct radeon_renderbuffer *rrb; -}; - -struct radeon_scissor_state { - drm_clip_rect_t rect; - GLboolean enabled; - - GLuint numClipRects; /* Cliprects active */ - GLuint numAllocedClipRects; /* Cliprects available */ - drm_clip_rect_t *pClipRects; -}; - -struct radeon_stencilbuffer_state { - GLboolean hwBuffer; - GLuint clear; /* rb3d_stencilrefmask value */ -}; - -struct radeon_stipple_state { - GLuint mask[32]; -}; - -struct radeon_state_atom { - struct radeon_state_atom *next, *prev; - const char *name; /* for debug */ - int cmd_size; /* size in bytes */ - GLuint idx; - GLuint is_tcl; - GLuint *cmd; /* one or more cmd's */ - GLuint *lastcmd; /* one or more cmd's */ - GLboolean dirty; /* dirty-mark in emit_state_list */ - int (*check) (GLcontext *, struct radeon_state_atom *atom); /* is this state active? */ - void (*emit) (GLcontext *, struct radeon_state_atom *atom); -}; - -struct radeon_hw_state { - /* Head of the linked list of state atoms. */ - struct radeon_state_atom atomlist; - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; -}; - - -/* Texture related */ -typedef struct _radeon_texture_image radeon_texture_image; - -struct _radeon_texture_image { - struct gl_texture_image base; - - /** - * If mt != 0, the image is stored in hardware format in the - * given mipmap tree. In this case, base.Data may point into the - * mapping of the buffer object that contains the mipmap tree. - * - * If mt == 0, the image is stored in normal memory pointed to - * by base.Data. - */ - struct _radeon_mipmap_tree *mt; - struct radeon_bo *bo; - - int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ - int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ -}; - - -static INLINE radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) -{ - return (radeon_texture_image*)image; -} - - -typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; - -#define RADEON_TXO_MICRO_TILE (1 << 3) - -/* Texture object in locally shared texture space. - */ -struct radeon_tex_obj { - // driTextureObject base; - struct gl_texture_object base; - struct _radeon_mipmap_tree *mt; - - /** - * This is true if we've verified that the mipmap tree above is complete - * and so on. - */ - GLboolean validated; - - GLuint override_offset; - GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ - GLuint tile_bits; /* hw texture tile bits used on this texture */ - struct radeon_bo *bo; - - GLuint bufAddr; /* Offset to start of locally - shared texture block */ - - GLuint dirty_state; /* Flags (1 per texunit) for - whether or not this texobj - has dirty hardware state - (pp_*) that needs to be - brought into the - texunit. */ - - drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; - /* Six, for the cube faces */ - - - - GLuint pp_txfilter; /* hardware register values */ - GLuint pp_txformat; - GLuint pp_txformat_x; - GLuint pp_txoffset; /* Image location in texmem. - All cube faces follow. */ - GLuint pp_txsize; /* npot only */ - GLuint pp_txpitch; /* npot only */ - GLuint pp_border_color; - GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ - - GLuint pp_txfilter_1; /* r300 */ - - GLboolean border_fallback; - - -}; - -static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) -{ - return (radeonTexObj*)texObj; -} - -/* Need refcounting on dma buffers: - */ -struct radeon_dma_buffer { - int refcount; /* the number of retained regions in buf */ - drmBufPtr buf; -}; - -struct radeon_aos { - struct radeon_bo *bo; /** Buffer object where vertex data is stored */ - int offset; /** Offset into buffer object, in bytes */ - int components; /** Number of components per vertex */ - int stride; /** Stride in dwords (may be 0 for repeating) */ - int count; /** Number of vertices */ -}; - -struct radeon_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ - int current_used; /** Number of bytes allocated and forgotten about */ - int current_vertexptr; /** End of active vertex region */ - - /** - * If current_vertexptr != current_used then flush must be non-zero. - * flush must be called before non-active vertex allocations can be - * performed. - */ - void (*flush) (GLcontext *); - - /* Number of "in-flight" DMA buffers, i.e. the number of buffers - * for which a DISCARD command is currently queued in the command buffer -. - */ - GLuint nr_released_bufs; -}; - -/* radeon_swtcl.c - */ -struct radeon_swtcl_info { - - GLuint RenderIndex; - GLuint vertex_size; - GLubyte *verts; - - /* Fallback rasterization functions - */ - GLuint hw_primitive; - GLenum render_primitive; - GLuint numverts; - - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - GLuint vertex_attr_count; - -}; - -struct radeon_ioctl { - GLuint vertex_offset; - struct radeon_bo *bo; - GLuint vertex_size; -}; - -#define RADEON_MAX_PRIMS 64 - -struct radeon_prim { - GLuint start; - GLuint end; - GLuint prim; -}; - -static INLINE GLuint radeonPackColor(GLuint cpp, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a) -{ - switch (cpp) { - case 2: - return PACK_COLOR_565(r, g, b); - case 4: - return PACK_COLOR_8888(a, r, g, b); - default: - return 0; - } -} - -#define MAX_CMD_BUF_SZ (16*1024) - -#define MAX_DMA_BUF_SZ (64*1024) - -struct radeon_store { - GLuint statenr; - GLuint primnr; - char cmd_buf[MAX_CMD_BUF_SZ]; - int cmd_used; - int elts_start; -}; - -struct radeon_dri_mirror { - __DRIcontextPrivate *context; /* DRI context */ - __DRIscreenPrivate *screen; /* DRI screen */ - - /** - * DRI drawable bound to this context for drawing. - */ - __DRIdrawablePrivate *drawable; - - /** - * DRI drawable bound to this context for reading. - */ - __DRIdrawablePrivate *readable; - - drm_context_t hwContext; - drm_hw_lock_t *hwLock; - int fd; - int drmMinor; -}; - -#define DEBUG_TEXTURE 0x001 -#define DEBUG_STATE 0x002 -#define DEBUG_IOCTL 0x004 -#define DEBUG_PRIMS 0x008 -#define DEBUG_VERTS 0x010 -#define DEBUG_FALLBACKS 0x020 -#define DEBUG_VFMT 0x040 -#define DEBUG_CODEGEN 0x080 -#define DEBUG_VERBOSE 0x100 -#define DEBUG_DRI 0x200 -#define DEBUG_DMA 0x400 -#define DEBUG_SANITY 0x800 -#define DEBUG_SYNC 0x1000 -#define DEBUG_PIXEL 0x2000 -#define DEBUG_MEMORY 0x4000 - - - -typedef void (*radeon_tri_func) (radeonContextPtr, - radeonVertex *, - radeonVertex *, radeonVertex *); - -typedef void (*radeon_line_func) (radeonContextPtr, - radeonVertex *, radeonVertex *); - -typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); - -struct radeon_state { - struct radeon_colorbuffer_state color; - struct radeon_depthbuffer_state depth; - struct radeon_scissor_state scissor; - struct radeon_stencilbuffer_state stencil; -}; - -/** - * This structure holds the command buffer while it is being constructed. - * - * The first batch of commands in the buffer is always the state that needs - * to be re-emitted when the context is lost. This batch can be skipped - * otherwise. - */ -struct radeon_cmdbuf { - struct radeon_cs_manager *csm; - struct radeon_cs *cs; - int size; /** # of dwords total */ - unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ -}; - -struct radeon_context { - GLcontext *glCtx; - radeonScreenPtr radeonScreen; /* Screen private DRI data */ - - /* Texture object bookkeeping - */ - unsigned nr_heaps; - driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; - driTextureObject swapped; - int texture_depth; - float initialMaxAnisotropy; - - struct radeon_dma dma; - struct radeon_hw_state hw; - /* Rasterization and vertex state: - */ - GLuint TclFallback; - GLuint Fallback; - GLuint NewGLState; - DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ - - /* Page flipping */ - GLuint doPageFlip; - - /* Drawable, cliprect and scissor information */ - GLuint numClipRects; /* Cliprects for the draw buffer */ - drm_clip_rect_t *pClipRects; - unsigned int lastStamp; - GLboolean lost_context; - drm_radeon_sarea_t *sarea; /* Private SAREA data */ - - /* Mirrors of some DRI state */ - struct radeon_dri_mirror dri; - - /* Busy waiting */ - GLuint do_usleeps; - GLuint do_irqs; - GLuint irqsEmitted; - drm_radeon_irq_wait_t iw; - - /* buffer swap */ - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; - - /* Derived state - for r300 only */ - struct radeon_state state; - - struct radeon_swtcl_info swtcl; - /* Configuration cache - */ - driOptionCache optionCache; - - struct radeon_cmdbuf cmdbuf; - - struct { - void (*get_lock)(radeonContextPtr radeon); - void (*update_viewport_offset)(GLcontext *ctx); - void (*update_draw_buffer)(GLcontext *ctx); - void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); - void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); - void (*pre_emit_atoms)(radeonContextPtr rmesa); - void (*pre_emit_state)(radeonContextPtr rmesa); - } vtbl; -}; - -#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) - -/** - * This function takes a float and packs it into a uint32_t - */ -static INLINE uint32_t radeonPackFloat32(float fl) -{ - union { - float fl; - uint32_t u; - } u; - - u.fl = fl; - return u.u; -} - -/* This is probably wrong for some values, I need to test this - * some more. Range checking would be a good idea also.. - * - * But it works for most things. I'll fix it later if someone - * else with a better clue doesn't - */ -static INLINE uint32_t radeonPackFloat24(float f) -{ - float mantissa; - int exponent; - uint32_t float24 = 0; - - if (f == 0.0) - return 0; - - mantissa = frexpf(f, &exponent); - - /* Handle -ve */ - if (mantissa < 0) { - float24 |= (1 << 23); - mantissa = mantissa * -1.0; - } - /* Handle exponent, bias of 63 */ - exponent += 62; - float24 |= (exponent << 16); - /* Kill 7 LSB of mantissa */ - float24 |= (radeonPackFloat32(mantissa) & 0x7FFFFF) >> 7; - - return float24; -} - -/* ================================================================ - * Debugging: - */ -#define DO_DEBUG 1 - -#if DO_DEBUG -extern int RADEON_DEBUG; -#else -#define RADEON_DEBUG 0 -#endif - -#include "common_misc.h" -#include "common_cmdbuf.h" -#endif diff --git a/src/mesa/drivers/dri/radeon/common_lock.c b/src/mesa/drivers/dri/radeon/common_lock.c deleted file mode 100644 index 91600ac4cd..0000000000 --- a/src/mesa/drivers/dri/radeon/common_lock.c +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - VA Linux Systems Inc., Fremont, California. -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Gareth Hughes - * Keith Whitwell - * Kevin E. Martin - */ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/colormac.h" -#include "dri_util.h" -#include "radeon_screen.h" -#include "common_context.h" -#include "common_lock.h" -#include "common_misc.h" - -#include "drirenderbuffer.h" - -#if DEBUG_LOCKING -char *prevLockFile = NULL; -int prevLockLine = 0; -#endif - -/* Turn on/off page flipping according to the flags in the sarea: - */ -void radeonUpdatePageFlipping(radeonContextPtr rmesa) -{ - int use_back; - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - GLframebuffer *fb = drawable->driverPrivate; - - rmesa->doPageFlip = rmesa->sarea->pfState; - if (rmesa->glCtx->WinSysDrawBuffer) { - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); - } - - use_back = rmesa->glCtx->DrawBuffer ? - (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == - BUFFER_BACK_LEFT) : 1; - use_back ^= (rmesa->sarea->pfCurrentPage == 1); - - if (use_back) - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - else - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; -} - -/* Update the hardware state. This is called if another context has - * grabbed the hardware lock, which includes the X server. This - * function also updates the driver's window state after the X server - * moves, resizes or restacks a window -- the change will be reflected - * in the drawable position and clip rects. Since the X server grabs - * the hardware lock when it changes the window state, this routine will - * automatically be called after such a change. - */ -void radeonGetLock(radeonContextPtr rmesa, GLuint flags) -{ - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - __DRIdrawablePrivate *const readable = rmesa->dri.readable; - __DRIscreenPrivate *sPriv = rmesa->dri.screen; - drm_radeon_sarea_t *sarea = rmesa->sarea; - - assert(drawable != NULL); - - drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); - - /* The window might have moved, so we might need to get new clip - * rects. - * - * NOTE: This releases and regrabs the hw lock to allow the X server - * to respond to the DRI protocol request for new drawable info. - * Since the hardware state depends on having the latest drawable - * clip rects, all state checking must be done _after_ this call. - */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); - if (drawable != readable) { - DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); - } - - if (rmesa->lastStamp != drawable->lastStamp) { - radeonUpdatePageFlipping(rmesa); - radeonSetCliprects(rmesa); - rmesa->vtbl.update_viewport_offset(rmesa->glCtx); - driUpdateFramebufferSize(rmesa->glCtx, drawable); - } - - rmesa->vtbl.get_lock(rmesa); - - rmesa->lost_context = GL_TRUE; -} diff --git a/src/mesa/drivers/dri/radeon/common_lock.h b/src/mesa/drivers/dri/radeon/common_lock.h deleted file mode 100644 index 431b076f02..0000000000 --- a/src/mesa/drivers/dri/radeon/common_lock.h +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - VA Linux Systems Inc., Fremont, California. -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Gareth Hughes - * Keith Whitwell - * Kevin E. Martin - */ - -#ifndef COMMON_LOCK_H -#define COMMON_LOCK_H - -#include "main/colormac.h" -#include "radeon_screen.h" -#include "common_context.h" - -extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); - -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( (rmesa), 0 ); \ - } \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ - DEBUG_RESET(); \ - } \ - } while (0) - -#endif diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c deleted file mode 100644 index f0035e54cf..0000000000 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ /dev/null @@ -1,2715 +0,0 @@ -/************************************************************************** - -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - */ - -#include -#include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/api_arrayelt.h" -#include "main/enums.h" -#include "main/colormac.h" -#include "main/light.h" -#include "main/framebuffer.h" -#include "main/simple_list.h" - -#include "swrast/swrast.h" -#include "vbo/vbo.h" -#include "tnl/tnl.h" -#include "tnl/t_pipeline.h" -#include "swrast_setup/swrast_setup.h" -#include "main/mipmap.h" -#include "main/texformat.h" -#include "main/texstore.h" -#include "main/teximage.h" -#include "main/texobj.h" - -#include "drirenderbuffer.h" -#include "vblank.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ - -#include "radeon_bo.h" -#include "radeon_cs.h" -#include "radeon_bo_legacy.h" -#include "radeon_cs_legacy.h" -#include "radeon_bo_gem.h" -#include "radeon_cs_gem.h" -#include "dri_util.h" -#include "radeon_drm.h" -#include "radeon_buffer.h" -#include "radeon_screen.h" -#include "common_context.h" -#include "common_misc.h" -#include "common_lock.h" -#include "common_cmdbuf.h" -#include "radeon_mipmap_tree.h" -#include "radeon_span.h" - -#define DRIVER_DATE "20090101" - -#ifndef RADEON_DEBUG -int RADEON_DEBUG = (0); -#endif - -#define DEBUG_CMDBUF 0 - -/* ============================================================= - * Scissoring - */ - -static GLboolean intersect_rect(drm_clip_rect_t * out, - drm_clip_rect_t * a, drm_clip_rect_t * b) -{ - *out = *a; - if (b->x1 > out->x1) - out->x1 = b->x1; - if (b->y1 > out->y1) - out->y1 = b->y1; - if (b->x2 < out->x2) - out->x2 = b->x2; - if (b->y2 < out->y2) - out->y2 = b->y2; - if (out->x1 >= out->x2) - return GL_FALSE; - if (out->y1 >= out->y2) - return GL_FALSE; - return GL_TRUE; -} - -void radeonRecalcScissorRects(radeonContextPtr radeon) -{ - drm_clip_rect_t *out; - int i; - - /* Grow cliprect store? - */ - if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { - while (radeon->state.scissor.numAllocedClipRects < - radeon->numClipRects) { - radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ - radeon->state.scissor.numAllocedClipRects *= 2; - } - - if (radeon->state.scissor.pClipRects) - FREE(radeon->state.scissor.pClipRects); - - radeon->state.scissor.pClipRects = - MALLOC(radeon->state.scissor.numAllocedClipRects * - sizeof(drm_clip_rect_t)); - - if (radeon->state.scissor.pClipRects == NULL) { - radeon->state.scissor.numAllocedClipRects = 0; - return; - } - } - - out = radeon->state.scissor.pClipRects; - radeon->state.scissor.numClipRects = 0; - - for (i = 0; i < radeon->numClipRects; i++) { - if (intersect_rect(out, - &radeon->pClipRects[i], - &radeon->state.scissor.rect)) { - radeon->state.scissor.numClipRects++; - out++; - } - } -} - -/** - * Update cliprects and scissors. - */ -void radeonSetCliprects(radeonContextPtr radeon) -{ - __DRIdrawablePrivate *const drawable = radeon->dri.drawable; - __DRIdrawablePrivate *const readable = radeon->dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; - - if (!radeon->radeonScreen->driScreen->dri2.enabled) { - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. */ - if (drawable->numBackClipRects == 0 || radeon->doPageFlip || - radeon->sarea->pfCurrentPage == 1) { - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } else { - radeon->numClipRects = drawable->numBackClipRects; - radeon->pClipRects = drawable->pBackClipRects; - } - } else { - /* front buffer (or none, or multiple buffers */ - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } - } - - if ((draw_fb->Width != drawable->w) || - (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, draw_fb, - drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; - } - - if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, read_fb, - readable->w, readable->h); - read_fb->Initialized = GL_TRUE; - } - } - - if (radeon->state.scissor.enabled) - radeonRecalcScissorRects(radeon); - - radeon->lastStamp = drawable->lastStamp; -} - -void radeonUpdateScissor( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if ( rmesa->dri.drawable ) { - __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; - - int x = ctx->Scissor.X; - int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; - int w = ctx->Scissor.X + ctx->Scissor.Width - 1; - int h = dPriv->h - ctx->Scissor.Y - 1; - - rmesa->state.scissor.rect.x1 = x + dPriv->x; - rmesa->state.scissor.rect.y1 = y + dPriv->y; - rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; - rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - radeonRecalcScissorRects( rmesa ); - } -} - -/* ============================================================= - * Scissoring - */ - -void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (ctx->Scissor.Enabled) { - /* We don't pipeline cliprect changes */ - radeon_firevertices(radeon); - radeonUpdateScissor(ctx); - } -} - - -/* ================================================================ - * SwapBuffers with client-side throttling - */ - -static uint32_t radeonGetLastFrame(radeonContextPtr radeon) -{ - drm_radeon_getparam_t gp; - int ret; - uint32_t frame; - - gp.param = RADEON_PARAM_LAST_FRAME; - gp.value = (int *)&frame; - ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, - ret); - exit(1); - } - - return frame; -} - -uint32_t radeonGetAge(radeonContextPtr radeon) -{ - drm_radeon_getparam_t gp; - int ret; - uint32_t age; - - gp.param = RADEON_PARAM_LAST_CLEAR; - gp.value = (int *)&age; - ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, - ret); - exit(1); - } - - return age; -} - -static void radeonEmitIrqLocked(radeonContextPtr radeon) -{ - drm_radeon_irq_emit_t ie; - int ret; - - ie.irq_seq = &radeon->iw.irq_seq; - ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT, - &ie, sizeof(ie)); - if (ret) { - fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, - ret); - exit(1); - } -} - -static void radeonWaitIrq(radeonContextPtr radeon) -{ - int ret; - - do { - ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT, - &radeon->iw, sizeof(radeon->iw)); - } while (ret && (errno == EINTR || errno == EBUSY)); - - if (ret) { - fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, - ret); - exit(1); - } -} - -static void radeonWaitForFrameCompletion(radeonContextPtr radeon) -{ - drm_radeon_sarea_t *sarea = radeon->sarea; - - if (radeon->do_irqs) { - if (radeonGetLastFrame(radeon) < sarea->last_frame) { - if (!radeon->irqsEmitted) { - while (radeonGetLastFrame(radeon) < - sarea->last_frame) ; - } else { - UNLOCK_HARDWARE(radeon); - radeonWaitIrq(radeon); - LOCK_HARDWARE(radeon); - } - radeon->irqsEmitted = 10; - } - - if (radeon->irqsEmitted) { - radeonEmitIrqLocked(radeon); - radeon->irqsEmitted--; - } - } else { - while (radeonGetLastFrame(radeon) < sarea->last_frame) { - UNLOCK_HARDWARE(radeon); - if (radeon->do_usleeps) - DO_USLEEP(1); - LOCK_HARDWARE(radeon); - } - } -} - -/* wait for idle */ -void radeonWaitForIdleLocked(radeonContextPtr radeon) -{ - int ret; - int i = 0; - - do { - ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); - if (ret) - DO_USLEEP(1); - } while (ret && ++i < 100); - - if (ret < 0) { - UNLOCK_HARDWARE(radeon); - fprintf(stderr, "Error: R300 timed out... exiting\n"); - exit(-1); - } -} - -static void radeonWaitForIdle(radeonContextPtr radeon) -{ - LOCK_HARDWARE(radeon); - radeonWaitForIdleLocked(radeon); - UNLOCK_HARDWARE(radeon); -} - - -/* Copy the back color buffer to the front color buffer. - */ -void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, - const drm_clip_rect_t *rect) -{ - radeonContextPtr rmesa; - GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - - if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); - } - - radeon_firevertices(rmesa); - LOCK_HARDWARE( rmesa ); - - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - if (!rect) - { - UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( rmesa ); - } - - nbox = dPriv->numClipRects; /* must be in locked region */ - - for ( i = 0 ; i < nbox ; ) { - GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = rmesa->sarea->boxes; - GLint n = 0; - - for ( ; i < nr ; i++ ) { - - *b = box[i]; - - if (rect) - { - if (rect->x1 > b->x1) - b->x1 = rect->x1; - if (rect->y1 > b->y1) - b->y1 = rect->y1; - if (rect->x2 < b->x2) - b->x2 = rect->x2; - if (rect->y2 < b->y2) - b->y2 = rect->y2; - - if (b->x1 >= b->x2 || b->y1 >= b->y2) - continue; - } - - b++; - n++; - } - rmesa->sarea->nbox = n; - - if (!n) - continue; - - ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); - - if ( ret ) { - fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); - UNLOCK_HARDWARE( rmesa ); - exit( 1 ); - } - } - - UNLOCK_HARDWARE( rmesa ); - if (!rect) - { - psp = dPriv->driScreenPriv; - rmesa->swap_count++; - (*psp->systemTime->getUST)( & ust ); - if ( missed_target ) { - rmesa->swap_missed_count++; - rmesa->swap_missed_ust = ust - rmesa->swap_ust; - } - - rmesa->swap_ust = ust; - rmesa->hw.all_dirty = GL_TRUE; - - } -} - -void radeonPageFlip( __DRIdrawablePrivate *dPriv ) -{ - radeonContextPtr rmesa; - GLint ret; - GLboolean missed_target; - __DRIscreenPrivate *psp; - struct radeon_renderbuffer *rrb; - GLframebuffer *fb = dPriv->driverPrivate; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - psp = dPriv->driScreenPriv; - - if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->sarea->pfCurrentPage); - } - - radeon_firevertices(rmesa); - - LOCK_HARDWARE( rmesa ); - - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(rmesa); - usleep(10000); /* throttle invisible client 10ms */ - return; - } - - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = rmesa->sarea->boxes; - b[0] = box[0]; - rmesa->sarea->nbox = 1; - - /* Throttle the frame rate -- only allow a few pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & missed_target ); - if ( missed_target ) { - rmesa->swap_missed_count++; - (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); - } - LOCK_HARDWARE( rmesa ); - - ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); - - UNLOCK_HARDWARE( rmesa ); - - if ( ret ) { - fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); - exit( 1 ); - } - - rmesa->swap_count++; - (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); - - /* Get ready for drawing next frame. Update the renderbuffers' - * flippedOffset/Pitch fields so we draw into the right place. - */ - driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, - rmesa->sarea->pfCurrentPage); - - rmesa->state.color.rrb = rrb; - - if (rmesa->vtbl.update_draw_buffer) - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); -} - -void radeonFlush(GLcontext *ctx) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (radeon->dma.flush) - radeon->dma.flush( ctx ); - - radeonEmitState(radeon); - - if (radeon->cmdbuf.cs->cdw) - rcommonFlushCmdBuf(radeon, __FUNCTION__); -} - -static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) -{ - BATCH_LOCALS(radeon); - struct radeon_state_atom *atom; - int dwords; - - if (radeon->vtbl.pre_emit_atoms) - radeon->vtbl.pre_emit_atoms(radeon); - - /* Emit actual atoms */ - foreach(atom, &radeon->hw.atomlist) { - if ((atom->dirty || radeon->hw.all_dirty) == dirty) { - dwords = (*atom->check) (radeon->glCtx, atom); - if (dwords) { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - radeon_print_state_atom(atom); - } - if (atom->emit) { - (*atom->emit)(radeon->glCtx, atom); - } else { - BEGIN_BATCH_NO_AUTOSTATE(dwords); - OUT_BATCH_TABLE(atom->cmd, dwords); - END_BATCH(); - } - atom->dirty = GL_FALSE; - } else { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - fprintf(stderr, " skip state %s\n", - atom->name); - } - } - } - } - - COMMIT_BATCH(); -} - -void radeonEmitState(radeonContextPtr radeon) -{ - if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (radeon->vtbl.pre_emit_state) - radeon->vtbl.pre_emit_state(radeon); - - /* this code used to return here but now it emits zbs */ - if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) - return; - - /* To avoid going across the entire set of states multiple times, just check - * for enough space for the case of emitting all state, and inline the - * radeonAllocCmdBuf code here without all the checks. - */ - rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); - - /* We always always emit zbs, this is due to a bug found by keithw in - the hardware and rediscovered after Erics changes by me. - if you ever touch this code make sure you emit zbs otherwise - you get tcl lockups on at least M7/7500 class of chips - airlied */ - /* special r100 case */ - // rmesa->hw.zbs.dirty=1; - - if (!radeon->cmdbuf.cs->cdw) { - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin reemit state\n"); - - radeonEmitAtoms(radeon, GL_FALSE); - } - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin dirty state\n"); - - radeonEmitAtoms(radeon, GL_TRUE); - radeon->hw.is_dirty = GL_FALSE; - radeon->hw.all_dirty = GL_FALSE; - -} - - -/* Make sure all commands have been sent to the hardware and have - * completed processing. - */ -void radeonFinish(GLcontext * ctx) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - - radeonFlush(ctx); - - if (radeon->radeonScreen->kernel_mm) { - for (i = 0; i < fb->_NumColorDrawBuffers; i++) { - struct radeon_renderbuffer *rrb; - rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; - if (rrb->bo) - radeon_bo_wait(rrb->bo); - } - } else if (radeon->do_irqs) { - LOCK_HARDWARE(radeon); - radeonEmitIrqLocked(radeon); - UNLOCK_HARDWARE(radeon); - radeonWaitIrq(radeon); - } else { - radeonWaitForIdle(radeon); - } -} - -/** - * Swap front and back buffer. - */ -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - radeonContextPtr radeon; - GLcontext *ctx; - - radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = radeon->glCtx; - - if (ctx->Visual.doubleBufferMode) { - _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ - if (radeon->doPageFlip) { - radeonPageFlip(dPriv); - } else { - radeonCopyBuffer(dPriv, NULL); - } - } - } else { - /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "%s: drawable has no context!", - __FUNCTION__); - } -} - -void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h ) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - radeonContextPtr radeon; - GLcontext *ctx; - - radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = radeon->glCtx; - - if (ctx->Visual.doubleBufferMode) { - drm_clip_rect_t rect; - rect.x1 = x + dPriv->x; - rect.y1 = (dPriv->h - y - h) + dPriv->y; - rect.x2 = rect.x1 + w; - rect.y2 = rect.y1 + h; - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - radeonCopyBuffer(dPriv, &rect); - } - } else { - /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "%s: drawable has no context!", - __FUNCTION__); - } -} - -/* cmdbuffer */ -/** - * Send the current command buffer via ioctl to the hardware. - */ -int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) -{ - int ret = 0; - - if (rmesa->cmdbuf.flushing) { - fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); - exit(-1); - } - rmesa->cmdbuf.flushing = 1; - if (rmesa->cmdbuf.cs->cdw) { - ret = radeon_cs_emit(rmesa->cmdbuf.cs); - rmesa->hw.all_dirty = GL_TRUE; - } - radeon_cs_erase(rmesa->cmdbuf.cs); - rmesa->cmdbuf.flushing = 0; - return ret; -} - -int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) -{ - int ret; - - radeonReleaseDmaRegion(rmesa); - - LOCK_HARDWARE(rmesa); - ret = rcommonFlushCmdBufLocked(rmesa, caller); - UNLOCK_HARDWARE(rmesa); - - if (ret) { - fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); - _mesa_exit(ret); - } - - return ret; -} - -/** - * Make sure that enough space is available in the command buffer - * by flushing if necessary. - * - * \param dwords The number of dwords we need to be free on the command buffer - */ -void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) -{ - if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || - radeon_cs_need_flush(rmesa->cmdbuf.cs)) { - rcommonFlushCmdBuf(rmesa, caller); - } -} - -void rcommonInitCmdBuf(radeonContextPtr rmesa) -{ - GLuint size; - /* Initialize command buffer */ - size = 256 * driQueryOptioni(&rmesa->optionCache, - "command_buffer_size"); - if (size < 2 * rmesa->hw.max_state_size) { - size = 2 * rmesa->hw.max_state_size + 65535; - } - if (size > 64 * 256) - size = 64 * 256; - - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { - fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", - sizeof(drm_r300_cmd_header_t)); - fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", - sizeof(drm_radeon_cmd_buffer_t)); - fprintf(stderr, - "Allocating %d bytes command buffer (max state is %d bytes)\n", - size * 4, rmesa->hw.max_state_size * 4); - } - - if (rmesa->radeonScreen->kernel_mm) { - int fd = rmesa->radeonScreen->driScreen->fd; - rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); - } else { - rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); - } - if (rmesa->cmdbuf.csm == NULL) { - /* FIXME: fatal error */ - return; - } - rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); - assert(rmesa->cmdbuf.cs != NULL); - rmesa->cmdbuf.size = size; - - if (!rmesa->radeonScreen->kernel_mm) { - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); - } else { - struct drm_radeon_gem_info mminfo; - - if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) - { - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_size); - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); - } - } - -} -/** - * Destroy the command buffer - */ -void rcommonDestroyCmdBuf(radeonContextPtr rmesa) -{ - radeon_cs_destroy(rmesa->cmdbuf.cs); - if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { - radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); - } else { - radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); - } -} - -void rcommonBeginBatch(radeonContextPtr rmesa, int n, - int dostate, - const char *file, - const char *function, - int line) -{ - rcommonEnsureCmdBufSpace(rmesa, n, function); - if (!rmesa->cmdbuf.cs->cdw && dostate) { - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "Reemit state after flush (from %s)\n", function); - radeonEmitState(rmesa); - } - radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); -} - - - -/* Return various strings for glGetString(). - */ -static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - static char buffer[128]; - - switch (name) { - case GL_VENDOR: - if (IS_R300_CLASS(radeon->radeonScreen)) - return (GLubyte *) "DRI R300 Project"; - else - return (GLubyte *) "Tungsten Graphics, Inc."; - - case GL_RENDERER: - { - unsigned offset; - GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : - radeon->radeonScreen->AGPMode; - const char* chipname; - - if (IS_R300_CLASS(radeon->radeonScreen)) - chipname = "R300"; - else if (IS_R200_CLASS(radeon->radeonScreen)) - chipname = "R200"; - else - chipname = "R100"; - - offset = driGetRendererString(buffer, chipname, DRIVER_DATE, - agp_mode); - - if (IS_R300_CLASS(radeon->radeonScreen)) { - sprintf(&buffer[offset], " %sTCL", - (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) - ? "" : "NO-"); - } else { - sprintf(&buffer[offset], " %sTCL", - !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) - ? "" : "NO-"); - } - - if (radeon->radeonScreen->driScreen->dri2.enabled) - strcat(buffer, " DRI2"); - - return (GLubyte *) buffer; - } - - default: - return NULL; - } -} - -/* Initialize the driver's misc functions. - */ -static void radeonInitDriverFuncs(struct dd_function_table *functions) -{ - functions->GetString = radeonGetString; -} - -/** - * Create and initialize all common fields of the context, - * including the Mesa context itself. - */ -GLboolean radeonInitContext(radeonContextPtr radeon, - struct dd_function_table* functions, - const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); - GLcontext* ctx; - GLcontext* shareCtx; - int fthrottle_mode; - - /* Fill in additional standard functions. */ - radeonInitDriverFuncs(functions); - - radeon->radeonScreen = screen; - /* Allocate and initialize the Mesa context */ - if (sharedContextPrivate) - shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; - else - shareCtx = NULL; - radeon->glCtx = _mesa_create_context(glVisual, shareCtx, - functions, (void *)radeon); - if (!radeon->glCtx) - return GL_FALSE; - - ctx = radeon->glCtx; - driContextPriv->driverPrivate = radeon; - - /* DRI fields */ - radeon->dri.context = driContextPriv; - radeon->dri.screen = sPriv; - radeon->dri.drawable = NULL; - radeon->dri.readable = NULL; - radeon->dri.hwContext = driContextPriv->hHWContext; - radeon->dri.hwLock = &sPriv->pSAREA->lock; - radeon->dri.fd = sPriv->fd; - radeon->dri.drmMinor = sPriv->drm_version.minor; - - radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + - screen->sarea_priv_offset); - - /* Setup IRQs */ - fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); - radeon->iw.irq_seq = -1; - radeon->irqsEmitted = 0; - radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && - radeon->radeonScreen->irq); - - radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - - if (!radeon->do_irqs) - fprintf(stderr, - "IRQ's not enabled, falling back to %s: %d %d\n", - radeon->do_usleeps ? "usleeps" : "busy waits", - fthrottle_mode, radeon->radeonScreen->irq); - - (*sPriv->systemTime->getUST) (&radeon->swap_ust); - - return GL_TRUE; -} - -/** - * Cleanup common context fields. - * Called by r200DestroyContext/r300DestroyContext - */ -void radeonCleanupContext(radeonContextPtr radeon) -{ - FILE *track; - struct radeon_renderbuffer *rb; - GLframebuffer *fb; - - /* free the Mesa context */ - _mesa_destroy_context(radeon->glCtx); - - fb = (void*)radeon->dri.drawable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - fb = (void*)radeon->dri.readable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - - /* _mesa_destroy_context() might result in calls to functions that - * depend on the DriverCtx, so don't set it to NULL before. - * - * radeon->glCtx->DriverCtx = NULL; - */ - - - - /* free the option cache */ - driDestroyOptionCache(&radeon->optionCache); - - rcommonDestroyCmdBuf(radeon); - - if (radeon->state.scissor.pClipRects) { - FREE(radeon->state.scissor.pClipRects); - radeon->state.scissor.pClipRects = 0; - } - track = fopen("/tmp/tracklog", "w"); - if (track) { - radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); - fclose(track); - } -} - -/* Force the context `c' to be unbound from its buffer. - */ -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, - radeon->glCtx); - - return GL_TRUE; -} - - -static void -radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) -{ - /* if radeon->fake */ - struct radeon_renderbuffer *rb; - - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->frontOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->backOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } -} - -static void -radeon_make_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) -{ - int size = 4096*4096*4; - /* if radeon->fake */ - struct radeon_renderbuffer *rb; - - if (radeon->radeonScreen->kernel_mm) { - radeon_make_kernel_renderbuffer_current(radeon, draw); - return; - } - - - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->frontOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->backOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } -} - - -void -radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) -{ - unsigned int attachments[10]; - __DRIbuffer *buffers; - __DRIscreen *screen; - struct radeon_renderbuffer *rb; - int i, count; - GLframebuffer *draw; - radeonContextPtr radeon; - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); - - draw = drawable->driverPrivate; - screen = context->driScreenPriv; - radeon = (radeonContextPtr) context->driverPrivate; - i = 0; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_DEPTH; - } - - buffers = (*screen->dri2.loader->getBuffers)(drawable, - &drawable->w, - &drawable->h, - attachments, i, - &count, - drawable->loaderPrivate); - if (buffers == NULL) - return; - - /* set one cliprect to cover the whole drawable */ - drawable->x = 0; - drawable->y = 0; - drawable->backX = 0; - drawable->backY = 0; - drawable->numClipRects = 1; - drawable->pClipRects[0].x1 = 0; - drawable->pClipRects[0].y1 = 0; - drawable->pClipRects[0].x2 = drawable->w; - drawable->pClipRects[0].y2 = drawable->h; - drawable->numBackClipRects = 1; - drawable->pBackClipRects[0].x1 = 0; - drawable->pBackClipRects[0].y1 = 0; - drawable->pBackClipRects[0].x2 = drawable->w; - drawable->pBackClipRects[0].y2 = drawable->h; - for (i = 0; i < count; i++) { - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - if (rb->bo == NULL) { - fprintf(stderr, "failled to attach front %d\n", - buffers[i].name); - } - break; - case __DRI_BUFFER_BACK_LEFT: - rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - break; - case __DRI_BUFFER_DEPTH: - rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - break; - case __DRI_BUFFER_STENCIL: - break; - case __DRI_BUFFER_ACCUM: - default: - fprintf(stderr, - "unhandled buffer attach event, attacment type %d\n", - buffers[i].attachment); - return; - } - } - radeon = (radeonContextPtr) context->driverPrivate; - driUpdateFramebufferSize(radeon->glCtx, drawable); -} - -/* Force the context `c' to be the current context and associate with it - * buffer `b'. - */ -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - radeonContextPtr radeon; - GLframebuffer *dfb, *rfb; - - if (!driContextPriv) { - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx is null\n", __FUNCTION__); - _mesa_make_current(NULL, NULL, NULL); - return GL_TRUE; - } - radeon = (radeonContextPtr) driContextPriv->driverPrivate; - dfb = driDrawPriv->driverPrivate; - rfb = driReadPriv->driverPrivate; - - if (driContextPriv->driScreenPriv->dri2.enabled) { - radeon_update_renderbuffers(driContextPriv, driDrawPriv); - if (driDrawPriv != driReadPriv) - radeon_update_renderbuffers(driContextPriv, driReadPriv); - radeon->state.color.rrb = - (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - radeon->state.depth.rrb = - (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; - } else { - radeon_make_renderbuffer_current(radeon, dfb); - } - - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); - - driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); - if (driReadPriv != driDrawPriv) - driUpdateFramebufferSize(radeon->glCtx, driReadPriv); - - - - _mesa_make_current(radeon->glCtx, dfb, rfb); - - if (radeon->dri.drawable != driDrawPriv) { - if (driDrawPriv->swap_interval == (unsigned)-1) { - driDrawPriv->vblFlags = - (radeon->radeonScreen->irq != 0) - ? driGetDefaultVBlankFlags(&radeon-> - optionCache) - : VBLANK_FLAG_NO_IRQ; - - driDrawableInitVBlank(driDrawPriv); - } - } - - radeon->dri.readable = driReadPriv; - - if (radeon->dri.drawable != driDrawPriv || - radeon->lastStamp != driDrawPriv->lastStamp) { - radeon->dri.drawable = driDrawPriv; - - radeonSetCliprects(radeon); - radeon->vtbl.update_viewport_offset(radeon->glCtx); - } - - _mesa_update_state(radeon->glCtx); - - if (!driContextPriv->driScreenPriv->dri2.enabled) { - radeonUpdatePageFlipping(radeon); - } - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "End %s\n", __FUNCTION__); - return GL_TRUE; -} - - -#if defined(USE_X86_ASM) -#define COPY_DWORDS( dst, src, nr ) \ -do { \ - int __tmp; \ - __asm__ __volatile__( "rep ; movsl" \ - : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ - : "0" (nr), \ - "D" ((long)dst), \ - "S" ((long)src) ); \ -} while (0) -#else -#define COPY_DWORDS( dst, src, nr ) \ -do { \ - int j; \ - for ( j = 0 ; j < nr ; j++ ) \ - dst[j] = ((int *)src)[j]; \ - dst += nr; \ -} while (0) -#endif - -static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 4) - COPY_DWORDS(out, data, count); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out++; - data += stride; - } -} - -void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 8) - COPY_DWORDS(out, data, count * 2); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out += 2; - data += stride; - } -} - -void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 12) { - COPY_DWORDS(out, data, count * 3); - } - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out[2] = *(int *)(data + 8); - out += 3; - data += stride; - } -} - -static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 16) - COPY_DWORDS(out, data, count * 4); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out[2] = *(int *)(data + 8); - out[3] = *(int *)(data + 12); - out += 4; - data += stride; - } -} - -void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, - GLvoid * data, int size, int stride, int count) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - uint32_t *out; - - if (stride == 0) { - radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); - count = 1; - aos->stride = 0; - } else { - radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); - aos->stride = size; - } - - aos->components = size; - aos->count = count; - - out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); - switch (size) { - case 1: radeonEmitVec4(out, data, stride, count); break; - case 2: radeonEmitVec8(out, data, stride, count); break; - case 3: radeonEmitVec12(out, data, stride, count); break; - case 4: radeonEmitVec16(out, data, stride, count); break; - default: - assert(0); - break; - } -} - - -void radeon_print_state_atom( struct radeon_state_atom *state ) -{ - int i; - - fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); - - if (RADEON_DEBUG & DEBUG_VERBOSE) - for (i = 0 ; i < state->cmd_size ; i++) - fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); - -} - -/* textures */ -/** - * Allocate an empty texture image object. - */ -struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) -{ - return CALLOC(sizeof(radeon_texture_image)); -} - -/** - * Free memory associated with this texture image. - */ -void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) -{ - radeon_texture_image* image = get_radeon_texture_image(timage); - - if (image->mt) { - radeon_miptree_unreference(image->mt); - image->mt = 0; - assert(!image->base.Data); - } else { - _mesa_free_texture_image_data(ctx, timage); - } - if (image->bo) { - radeon_bo_unref(image->bo); - image->bo = NULL; - } - if (timage->Data) { - _mesa_free_texmemory(timage->Data); - timage->Data = NULL; - } -} - -/* Set Data pointer and additional data for mapped texture image */ -static void teximage_set_map_data(radeon_texture_image *image) -{ - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - - image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; - image->base.RowStride = lvl->rowstride / image->mt->bpp; -} - - -/** - * Map a single texture image for glTexImage and friends. - */ -void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) -{ - if (image->mt) { - assert(!image->base.Data); - - radeon_bo_map(image->mt->bo, write_enable); - teximage_set_map_data(image); - } -} - - -void radeon_teximage_unmap(radeon_texture_image *image) -{ - if (image->mt) { - assert(image->base.Data); - - image->base.Data = 0; - radeon_bo_unmap(image->mt->bo); - } -} - -/** - * Map a validated texture for reading during software rendering. - */ -void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) - return; - - radeon_bo_map(t->mt->bo, GL_FALSE); - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) - teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); - } -} - -void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) - return; - - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) - texObj->Image[face][level]->Data = 0; - } - radeon_bo_unmap(t->mt->bo); -} - -GLuint radeon_face_for_target(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - default: - return 0; - } -} - -/** - * Wraps Mesa's implementation to ensure that the base level image is mapped. - * - * This relies on internal details of _mesa_generate_mipmap, in particular - * the fact that the memory for recreated texture images is always freed. - */ -static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - int i, face; - - - _mesa_generate_mipmap(ctx, target, texObj); - - for (face = 0; face < nr_faces; face++) { - for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { - radeon_texture_image *image; - - image = get_radeon_texture_image(texObj->Image[face][i]); - - if (image == NULL) - break; - - image->mtlevel = i; - image->mtface = face; - - radeon_miptree_unreference(image->mt); - image->mt = NULL; - } - } - -} - -void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) -{ - GLuint face = radeon_face_for_target(target); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); - - radeon_teximage_map(baseimage, GL_FALSE); - radeon_generate_mipmap(ctx, target, texObj); - radeon_teximage_unmap(baseimage); -} - - -/* try to find a format which will only need a memcopy */ -static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, - GLenum srcFormat, - GLenum srcType) -{ - const GLuint ui = 1; - const GLubyte littleEndian = *((const GLubyte *)&ui); - - /* r100 can only do this */ - if (IS_R100_CLASS(rmesa->radeonScreen)) - return _dri_texformat_argb8888; - - if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { - return &_mesa_texformat_rgba8888; - } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { - return &_mesa_texformat_rgba8888_rev; - } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8)) { - return &_mesa_texformat_argb8888_rev; - } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { - return &_mesa_texformat_argb8888; - } else - return _dri_texformat_argb8888; -} - -const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, - GLint internalFormat, - GLenum format, - GLenum type) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - const GLboolean do32bpt = - (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); - const GLboolean force16bpt = - (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); - (void)format; - -#if 0 - fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", - _mesa_lookup_enum_by_nr(internalFormat), internalFormat, - _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); -#endif - - switch (internalFormat) { - case 4: - case GL_RGBA: - case GL_COMPRESSED_RGBA: - switch (type) { - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return do32bpt ? _dri_texformat_argb8888 : - _dri_texformat_argb1555; - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return _dri_texformat_argb4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return _dri_texformat_argb1555; - default: - return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) : - _dri_texformat_argb4444; - } - - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return _dri_texformat_argb4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return _dri_texformat_argb1555; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - return _dri_texformat_rgb565; - default: - return do32bpt ? _dri_texformat_argb8888 : - _dri_texformat_rgb565; - } - - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return !force16bpt ? - radeonChoose8888TexFormat(rmesa, format,type) : - _dri_texformat_argb4444; - - case GL_RGBA4: - case GL_RGBA2: - return _dri_texformat_argb4444; - - case GL_RGB5_A1: - return _dri_texformat_argb1555; - - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return !force16bpt ? _dri_texformat_argb8888 : - _dri_texformat_rgb565; - - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - return _dri_texformat_rgb565; - - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COMPRESSED_ALPHA: - return _dri_texformat_a8; - - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_COMPRESSED_LUMINANCE: - return _dri_texformat_l8; - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - case GL_COMPRESSED_LUMINANCE_ALPHA: - return _dri_texformat_al88; - - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case GL_COMPRESSED_INTENSITY: - return _dri_texformat_i8; - - case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_APPLE || - type == GL_UNSIGNED_BYTE) - return &_mesa_texformat_ycbcr; - else - return &_mesa_texformat_ycbcr_rev; - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return &_mesa_texformat_rgba_dxt1; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return &_mesa_texformat_rgba_dxt3; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return &_mesa_texformat_rgba_dxt5; - - case GL_ALPHA16F_ARB: - return &_mesa_texformat_alpha_float16; - case GL_ALPHA32F_ARB: - return &_mesa_texformat_alpha_float32; - case GL_LUMINANCE16F_ARB: - return &_mesa_texformat_luminance_float16; - case GL_LUMINANCE32F_ARB: - return &_mesa_texformat_luminance_float32; - case GL_LUMINANCE_ALPHA16F_ARB: - return &_mesa_texformat_luminance_alpha_float16; - case GL_LUMINANCE_ALPHA32F_ARB: - return &_mesa_texformat_luminance_alpha_float32; - case GL_INTENSITY16F_ARB: - return &_mesa_texformat_intensity_float16; - case GL_INTENSITY32F_ARB: - return &_mesa_texformat_intensity_float32; - case GL_RGB16F_ARB: - return &_mesa_texformat_rgba_float16; - case GL_RGB32F_ARB: - return &_mesa_texformat_rgba_float32; - case GL_RGBA16F_ARB: - return &_mesa_texformat_rgba_float16; - case GL_RGBA32F_ARB: - return &_mesa_texformat_rgba_float32; - - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: -#if 0 - switch (type) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT: - return &_mesa_texformat_z16; - case GL_UNSIGNED_INT: - return &_mesa_texformat_z32; - case GL_UNSIGNED_INT_24_8_EXT: - default: - return &_mesa_texformat_z24_s8; - } -#else - return &_mesa_texformat_z16; -#endif - - default: - _mesa_problem(ctx, - "unexpected internalFormat 0x%x in r300ChooseTextureFormat", - (int)internalFormat); - return NULL; - } - - return NULL; /* never get here */ -} - -/** - * All glTexImage calls go through this function. - */ -static void radeon_teximage( - GLcontext *ctx, int dims, - GLint face, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLsizei imageSize, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - - radeon_firevertices(rmesa); - - t->validated = GL_FALSE; - - /* Choose and fill in the texture format for this image */ - texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type); - _mesa_set_fetch_functions(texImage, dims); - - if (texImage->TexFormat->TexelBytes == 0) { - texImage->IsCompressed = GL_TRUE; - texImage->CompressedSize = - ctx->Driver.CompressedTextureSize(ctx, texImage->Width, - texImage->Height, texImage->Depth, - texImage->TexFormat->MesaFormat); - } else { - texImage->IsCompressed = GL_FALSE; - texImage->CompressedSize = 0; - } - - /* Allocate memory for image */ - radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ - - if (!t->mt) - radeon_try_alloc_miptree(rmesa, t, texImage, face, level); - if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { - image->mt = t->mt; - image->mtlevel = level - t->mt->firstLevel; - image->mtface = face; - radeon_miptree_reference(t->mt); - } else { - int size; - if (texImage->IsCompressed) { - size = texImage->CompressedSize; - } else { - size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; - } - texImage->Data = _mesa_alloc_texmemory(size); - } - - /* Upload texture image; note that the spec allows pixels to be NULL */ - if (compressed) { - pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexImage"); - } else { - pixels = _mesa_validate_pbo_teximage( - ctx, dims, width, height, depth, - format, type, pixels, packing, "glTexImage"); - } - - if (pixels) { - radeon_teximage_map(image, GL_TRUE); - - if (compressed) { - memcpy(texImage->Data, pixels, imageSize); - } else { - GLuint dstRowStride; - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; - } - if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - } - - } - - /* SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); - } - - if (pixels) - radeon_teximage_unmap(image); - - _mesa_unmap_teximage_pbo(ctx, packing); - - -} - -void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) - -{ - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, - imageSize, 0, 0, data, 0, texObj, texImage, 1); -} - -void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -/** - * Update a subregion of the given texture image. - */ -static void radeon_texsubimage(GLcontext* ctx, int dims, int level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - - radeon_firevertices(rmesa); - - t->validated = GL_FALSE; - pixels = _mesa_validate_pbo_teximage(ctx, dims, - width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); - - if (pixels) { - GLint dstRowStride; - radeon_teximage_map(image, GL_TRUE); - - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; - } - - if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); - - - } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); - } - radeon_teximage_unmap(image); - - _mesa_unmap_teximage_pbo(ctx, packing); - - -} - -void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, - format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, - 1, format, type, pixels, packing, texObj, texImage, - 0); -} - -void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, - format, 0, data, 0, texObj, texImage, 1); -} - - -void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, - format, type, pixels, packing, texObj, texImage, 0); -} - -static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, - GLuint numrows, GLuint rowsize) -{ - assert(rowsize <= dststride); - assert(rowsize <= srcstride); - - if (rowsize == srcstride && rowsize == dststride) { - memcpy(dst, src, numrows*rowsize); - } else { - GLuint i; - for(i = 0; i < numrows; ++i) { - memcpy(dst, src, rowsize); - dst += dststride; - src += srcstride; - } - } -} - - -/** - * Ensure that the given image is stored in the given miptree from now on. - */ -static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) -{ - radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; - unsigned char *dest; - - assert(image->mt != mt); - assert(dstlvl->width == image->base.Width); - assert(dstlvl->height == image->base.Height); - assert(dstlvl->depth == image->base.Depth); - - - radeon_bo_map(mt->bo, GL_TRUE); - dest = mt->bo->ptr + dstlvl->faces[face].offset; - - if (image->mt) { - /* Format etc. should match, so we really just need a memcpy(). - * In fact, that memcpy() could be done by the hardware in many - * cases, provided that we have a proper memory manager. - */ - radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; - - assert(srclvl->size == dstlvl->size); - assert(srclvl->rowstride == dstlvl->rowstride); - - radeon_bo_map(image->mt->bo, GL_FALSE); - - memcpy(dest, - image->mt->bo->ptr + srclvl->faces[face].offset, - dstlvl->size); - radeon_bo_unmap(image->mt->bo); - - radeon_miptree_unreference(image->mt); - } else { - uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; - -// if (mt->tilebits) -// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); - - copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, - image->base.Height * image->base.Depth, srcrowstride); - - _mesa_free_texmemory(image->base.Data); - image->base.Data = 0; - } - - radeon_bo_unmap(mt->bo); - - image->mt = mt; - image->mtface = face; - image->mtlevel = level; - radeon_miptree_reference(image->mt); -} - -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); - int face, level; - - if (t->validated || t->image_override) - return GL_TRUE; - - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); - - if (baseimage->base.Border > 0) - return GL_FALSE; - - /* Ensure a matching miptree exists. - * - * Differing mipmap trees can result when the app uses TexImage to - * change texture dimensions. - * - * Prefer to use base image's miptree if it - * exists, since that most likely contains more valid data (remember - * that the base level is usually significantly larger than the rest - * of the miptree, so cubemaps are the only possible exception). - */ - if (baseimage->mt && - baseimage->mt != t->mt && - radeon_miptree_matches_texture(baseimage->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = baseimage->mt; - radeon_miptree_reference(t->mt); - } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - } - - if (!t->mt) { - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, " Allocate new miptree\n"); - radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); - if (!t->mt) { - _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); - return GL_FALSE; - } - } - - /* Ensure all images are stored in the single main miptree */ - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { - radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); - if (t->mt == image->mt) { - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "OK\n"); - continue; - } - - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "migrating\n"); - migrate_image_to_miptree(t->mt, image, face, level); - } - } - - return GL_TRUE; -} - - -GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 5; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 5) << 11; - offset += ((x & 31) >> 2) << 5; - offset += (x & 3) << 2; - } else { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 2; - } - } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 3) << 5; - offset += (x & 7) << 2; - } - } - return &ptr[offset]; -} - -GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 1; - } else { - nmacroblkpl = rrb->pitch >> 7; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 7) << 11; - offset += ((x & 127) >> 4) << 5; - offset += (x & 15) << 2; - } - } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 4) << 5; - offset += (x & 15) << 2; - } - } - return &ptr[offset]; -} - -GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint microblkxs; - GLint macroblkxs; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - microblkxs = 16 / rrb->cpp; - macroblkxs = 128 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } else { - microblkxs = 32 / rrb->cpp; - macroblkxs = 256 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } - } else { - microblkxs = 32 / rrb->cpp; - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } - } - return &ptr[offset]; -} - - -static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) -{ - struct radeon_renderbuffer *rrb = (void*)rb; - int r; - - if (rrb->bo) { - r = radeon_bo_map(rrb->bo, write); - if (r) { - fprintf(stderr, "(%s) error(%d) mapping buffer.\n", - __FUNCTION__, r); - } - } -} - -static void unmap_buffer(struct gl_renderbuffer *rb) -{ - struct radeon_renderbuffer *rrb = (void*)rb; - - if (rrb->bo) { - radeon_bo_unmap(rrb->bo); - } -} - -void radeonSpanRenderStart(GLcontext * ctx) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - radeon_firevertices(rmesa); - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) - ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); - } - - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); - } - - map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); - - if (ctx->DrawBuffer->_DepthBuffer) { - map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); - } - if (ctx->DrawBuffer->_StencilBuffer) - map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); - - /* The locking and wait for idle should really only be needed in classic mode. - * In a future memory manager based implementation, this should become - * unnecessary due to the fact that mapping our buffers, textures, etc. - * should implicitly wait for any previous rendering commands that must - * be waited on. */ - LOCK_HARDWARE(rmesa); - radeonWaitForIdleLocked(rmesa); -} - -void radeonSpanRenderFinish(GLcontext * ctx) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - _swrast_flush(ctx); - UNLOCK_HARDWARE(rmesa); - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) - ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); - } - - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) - unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); - - unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); - - if (ctx->DrawBuffer->_DepthBuffer) - unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); - if (ctx->DrawBuffer->_StencilBuffer) - unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); -} - -void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) -{ - struct radeon_cs_space_check bos[1]; - int flushed = 0, ret; - - size = MAX2(size, MAX_DMA_BUF_SZ * 16); - - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->dma.flush) { - rmesa->dma.flush(rmesa->glCtx); - } - - if (rmesa->dma.nr_released_bufs > 4) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - rmesa->dma.nr_released_bufs = 0; - } - - if (rmesa->dma.current) { - radeon_bo_unmap(rmesa->dma.current); - radeon_bo_unref(rmesa->dma.current); - rmesa->dma.current = 0; - } - -again_alloc: - rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, - 0, size, 4, RADEON_GEM_DOMAIN_GTT, - 0); - - if (!rmesa->dma.current) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - rmesa->dma.nr_released_bufs = 0; - goto again_alloc; - } - - rmesa->dma.current_used = 0; - rmesa->dma.current_vertexptr = 0; - - bos[0].bo = rmesa->dma.current; - bos[0].read_domains = RADEON_GEM_DOMAIN_GTT; - bos[0].write_domain =0 ; - bos[0].new_accounted = 0; - - ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1); - if (ret == RADEON_CS_SPACE_OP_TO_BIG) { - fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen"); - assert(0); - } else if (ret == RADEON_CS_SPACE_FLUSH) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - if (flushed) { - fprintf(stderr,"flushed but still no space\n"); - assert(0); - } - flushed = 1; - goto again_alloc; - } - radeon_bo_map(rmesa->dma.current, 1); -} - -/* Allocates a region from rmesa->dma.current. If there isn't enough - * space in current, grab a new buffer (and discard what was left of current) - */ -void radeonAllocDmaRegion(radeonContextPtr rmesa, - struct radeon_bo **pbo, int *poffset, - int bytes, int alignment) -{ - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); - - if (rmesa->dma.flush) - rmesa->dma.flush(rmesa->glCtx); - - assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); - - alignment--; - rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; - - if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) - radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); - - *poffset = rmesa->dma.current_used; - *pbo = rmesa->dma.current; - radeon_bo_ref(*pbo); - - /* Always align to at least 16 bytes */ - rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; - rmesa->dma.current_vertexptr = rmesa->dma.current_used; - - assert(rmesa->dma.current_used <= rmesa->dma.current->size); -} - -void radeonReleaseDmaRegion(radeonContextPtr rmesa) -{ - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current); - if (rmesa->dma.current) { - rmesa->dma.nr_released_bufs++; - radeon_bo_unmap(rmesa->dma.current); - radeon_bo_unref(rmesa->dma.current); - } - rmesa->dma.current = NULL; -} - - -/* Flush vertices in the current dma region. - */ -void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct radeon_dma *dma = &rmesa->dma; - - - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - dma->flush = NULL; - - if (dma->current) { - GLuint current_offset = dma->current_used; - - assert (dma->current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - dma->current_vertexptr); - - if (dma->current_used != dma->current_vertexptr) { - dma->current_used = dma->current_vertexptr; - - rmesa->vtbl.swtcl_flush(ctx, current_offset); - } - rmesa->swtcl.numverts = 0; - } -} -/* Alloc space in the current dma region. - */ -void * -rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) -{ - GLuint bytes = vsize * nverts; - void *head; - - if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) { - radeonRefillCurrentDmaRegion(rmesa, bytes); - } - - if (!rmesa->dma.flush) { - rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - rmesa->dma.flush = rcommon_flush_last_swtcl_prim; - } - - ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); - ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); - ASSERT( rmesa->dma.current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - rmesa->dma.current_vertexptr ); - -// fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr, -// rmesa->radeon.dma.current_vertexptr); - head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr); - rmesa->dma.current_vertexptr += bytes; - rmesa->swtcl.numverts += nverts; - return head; -} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h deleted file mode 100644 index ebf287a031..0000000000 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef COMMON_MISC_H -#define COMMON_MISC_H - -#include "common_context.h" -#include "radeon_buffer.h" -void radeonRecalcScissorRects(radeonContextPtr radeon); -void radeonSetCliprects(radeonContextPtr radeon); -void radeonUpdateScissor( GLcontext *ctx ); -void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); - -void radeonWaitForIdleLocked(radeonContextPtr radeon); -extern uint32_t radeonGetAge(radeonContextPtr radeon); -void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, - const drm_clip_rect_t *rect); -void radeonPageFlip( __DRIdrawablePrivate *dPriv ); -void radeon_common_finish(GLcontext * ctx); -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); -void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h ); - -void radeonUpdatePageFlipping(radeonContextPtr rmesa); - -GLboolean radeonInitContext(radeonContextPtr radeon, - struct dd_function_table* functions, - const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -void radeonCleanupContext(radeonContextPtr radeon); -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); -void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - -void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count); -void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); - -void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, - GLvoid * data, int size, int stride, int count); -void radeon_print_state_atom( struct radeon_state_atom *state ); - -struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); -void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); - -void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); -void radeon_teximage_unmap(radeon_texture_image *image); -void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); -void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); -void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); -GLuint radeon_face_for_target(GLenum target); -const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, - GLint internalFormat, - GLenum format, - GLenum type); - -void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void radeonSpanRenderStart(GLcontext * ctx); -void radeonSpanRenderFinish(GLcontext * ctx); -GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); -void radeonAllocDmaRegion(radeonContextPtr rmesa, - struct radeon_bo **pbo, int *poffset, - int bytes, int alignment); -void radeonReleaseDmaRegion(radeonContextPtr rmesa); - -void rcommon_flush_last_swtcl_prim(GLcontext *ctx); - -void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); - -void radeonFlush(GLcontext *ctx); -void radeonFinish(GLcontext * ctx); -void radeonEmitState(radeonContextPtr radeon); - -static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) -{ - struct radeon_renderbuffer *rrb; - rrb = rmesa->state.depth.rrb; - if (!rrb) - return NULL; - - return rrb; -} - -static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) -{ - struct radeon_renderbuffer *rrb; - GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; - - rrb = rmesa->state.color.rrb; - if (rmesa->radeonScreen->driScreen->dri2.enabled) { - rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } - if (!rrb) - return NULL; - return rrb; -} - - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index a716f1059b..b7658353af 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -47,7 +47,7 @@ #include "radeon_drm.h" #include "radeon_bo.h" #include "radeon_bo_legacy.h" -#include "common_context.h" +#include "radeon_common.h" struct bo_legacy { struct radeon_bo base; diff --git a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h new file mode 100644 index 0000000000..5526934209 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h @@ -0,0 +1,143 @@ +#ifndef COMMON_CMDBUF_H +#define COMMON_CMDBUF_H + +#include "radeon_cs.h" + +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); +void rcommonInitCmdBuf(radeonContextPtr rmesa); +void rcommonDestroyCmdBuf(radeonContextPtr rmesa); + +void rcommonBeginBatch(radeonContextPtr rmesa, + int n, + int dostate, + const char *file, + const char *function, + int line); + +#define RADEON_CP_PACKET3_NOP 0xC0001000 +#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 + +#define CP_PACKET2 (2 << 30) +#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + +/** + * Every function writing to the command buffer needs to declare this + * to get the necessary local variables. + */ +#define BATCH_LOCALS(rmesa) \ + const radeonContextPtr b_l_rmesa = rmesa + +/** + * Prepare writing n dwords to the command buffer, + * including producing any necessary state emits on buffer wraparound. + */ +#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__) + +/** + * Same as BEGIN_BATCH, but do not cause automatic state emits. + */ +#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__) + +/** + * Write one dword to the command buffer. + */ +#define OUT_BATCH(data) \ + do { \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ + } while(0) + +/** + * Write a relocated dword to the command buffer. + */ +#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ + do { \ + if (0 && offset) { \ + fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ + __FILE__, __FUNCTION__, __LINE__, offset); \ + } \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \ + radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ + bo, rd, wd, flags); \ + if (!b_l_rmesa->radeonScreen->kernel_mm) \ + b_l_rmesa->cmdbuf.cs->section_cdw += 2; \ + } while(0) + + +/** + * Write n dwords from ptr to the command buffer. + */ +#define OUT_BATCH_TABLE(ptr,n) \ + do { \ + int _i; \ + for (_i=0; _i < n; _i++) {\ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\ + }\ + } while(0) + +/** + * Finish writing dwords to the command buffer. + * The number of (direct or indirect) OUT_BATCH calls between the previous + * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. + */ +#define END_BATCH() \ + do { \ + radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ + } while(0) + +/** + * After the last END_BATCH() of rendering, this indicates that flushing + * the command buffer now is okay. + */ +#define COMMIT_BATCH() \ + do { \ + } while(0) + + +/** Single register write to command buffer; requires 2 dwords. */ +#define OUT_BATCH_REGVAL(reg, val) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ + OUT_BATCH((val)) + +/** Continuous register range write to command buffer; requires 1 dword, + * expects count dwords afterwards for register contents. */ +#define OUT_BATCH_REGSEQ(reg, count) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))); + +/** Write a 32 bit float to the ring; requires 1 dword. */ +#define OUT_BATCH_FLOAT32(f) \ + OUT_BATCH(radeonPackFloat32((f))); + + +/* Fire the buffered vertices no matter what. + */ +static INLINE void radeon_firevertices(radeonContextPtr radeon) +{ + if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) + radeonFlush(radeon->glCtx); +} + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c new file mode 100644 index 0000000000..87b6dac40b --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -0,0 +1,843 @@ +/************************************************************************** + +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + */ + +/* + - Scissor implementation + - buffer swap/copy ioctls + - finish/flush + - state emission + - cmdbuffer management +*/ + +#include +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/api_arrayelt.h" +#include "main/enums.h" +#include "main/colormac.h" +#include "main/light.h" +#include "main/framebuffer.h" +#include "main/simple_list.h" + +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + +#include "dri_util.h" +#include "drirenderbuffer.h" +#include "vblank.h" + +#include "radeon_common.h" +#include "radeon_common.h" +#include "radeon_bo.h" +#include "radeon_cs.h" +#include "radeon_bo_legacy.h" +#include "radeon_cs_legacy.h" +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" +#include "radeon_drm.h" +#include "radeon_mipmap_tree.h" + +#define DEBUG_CMDBUF 0 + +/* ============================================================= + * Scissoring + */ + +static GLboolean intersect_rect(drm_clip_rect_t * out, + drm_clip_rect_t * a, drm_clip_rect_t * b) +{ + *out = *a; + if (b->x1 > out->x1) + out->x1 = b->x1; + if (b->y1 > out->y1) + out->y1 = b->y1; + if (b->x2 < out->x2) + out->x2 = b->x2; + if (b->y2 < out->y2) + out->y2 = b->y2; + if (out->x1 >= out->x2) + return GL_FALSE; + if (out->y1 >= out->y2) + return GL_FALSE; + return GL_TRUE; +} + +void radeonRecalcScissorRects(radeonContextPtr radeon) +{ + drm_clip_rect_t *out; + int i; + + /* Grow cliprect store? + */ + if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { + while (radeon->state.scissor.numAllocedClipRects < + radeon->numClipRects) { + radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ + radeon->state.scissor.numAllocedClipRects *= 2; + } + + if (radeon->state.scissor.pClipRects) + FREE(radeon->state.scissor.pClipRects); + + radeon->state.scissor.pClipRects = + MALLOC(radeon->state.scissor.numAllocedClipRects * + sizeof(drm_clip_rect_t)); + + if (radeon->state.scissor.pClipRects == NULL) { + radeon->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = radeon->state.scissor.pClipRects; + radeon->state.scissor.numClipRects = 0; + + for (i = 0; i < radeon->numClipRects; i++) { + if (intersect_rect(out, + &radeon->pClipRects[i], + &radeon->state.scissor.rect)) { + radeon->state.scissor.numClipRects++; + out++; + } + } +} + +/** + * Update cliprects and scissors. + */ +void radeonSetCliprects(radeonContextPtr radeon) +{ + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip || + radeon->sarea->pfCurrentPage == 1) { + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } else { + radeon->numClipRects = drawable->numBackClipRects; + radeon->pClipRects = drawable->pBackClipRects; + } + } else { + /* front buffer (or none, or multiple buffers */ + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } + } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; + } + } + + if (radeon->state.scissor.enabled) + radeonRecalcScissorRects(radeon); + + radeon->lastStamp = drawable->lastStamp; +} + +void radeonUpdateScissor( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( rmesa->dri.drawable ) { + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + + int x = ctx->Scissor.X; + int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; + int w = ctx->Scissor.X + ctx->Scissor.Width - 1; + int h = dPriv->h - ctx->Scissor.Y - 1; + + rmesa->state.scissor.rect.x1 = x + dPriv->x; + rmesa->state.scissor.rect.y1 = y + dPriv->y; + rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; + rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; + + radeonRecalcScissorRects( rmesa ); + } +} + +/* ============================================================= + * Scissoring + */ + +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (ctx->Scissor.Enabled) { + /* We don't pipeline cliprect changes */ + radeon_firevertices(radeon); + radeonUpdateScissor(ctx); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static uint32_t radeonGetLastFrame(radeonContextPtr radeon) +{ + drm_radeon_getparam_t gp; + int ret; + uint32_t frame; + + gp.param = RADEON_PARAM_LAST_FRAME; + gp.value = (int *)&frame; + ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, + ret); + exit(1); + } + + return frame; +} + +uint32_t radeonGetAge(radeonContextPtr radeon) +{ + drm_radeon_getparam_t gp; + int ret; + uint32_t age; + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&age; + ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, + ret); + exit(1); + } + + return age; +} + +static void radeonEmitIrqLocked(radeonContextPtr radeon) +{ + drm_radeon_irq_emit_t ie; + int ret; + + ie.irq_seq = &radeon->iw.irq_seq; + ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT, + &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, + ret); + exit(1); + } +} + +static void radeonWaitIrq(radeonContextPtr radeon) +{ + int ret; + + do { + ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT, + &radeon->iw, sizeof(radeon->iw)); + } while (ret && (errno == EINTR || errno == EBUSY)); + + if (ret) { + fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, + ret); + exit(1); + } +} + +static void radeonWaitForFrameCompletion(radeonContextPtr radeon) +{ + drm_radeon_sarea_t *sarea = radeon->sarea; + + if (radeon->do_irqs) { + if (radeonGetLastFrame(radeon) < sarea->last_frame) { + if (!radeon->irqsEmitted) { + while (radeonGetLastFrame(radeon) < + sarea->last_frame) ; + } else { + UNLOCK_HARDWARE(radeon); + radeonWaitIrq(radeon); + LOCK_HARDWARE(radeon); + } + radeon->irqsEmitted = 10; + } + + if (radeon->irqsEmitted) { + radeonEmitIrqLocked(radeon); + radeon->irqsEmitted--; + } + } else { + while (radeonGetLastFrame(radeon) < sarea->last_frame) { + UNLOCK_HARDWARE(radeon); + if (radeon->do_usleeps) + DO_USLEEP(1); + LOCK_HARDWARE(radeon); + } + } +} + +/* wait for idle */ +void radeonWaitForIdleLocked(radeonContextPtr radeon) +{ + int ret; + int i = 0; + + do { + ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); + if (ret) + DO_USLEEP(1); + } while (ret && ++i < 100); + + if (ret < 0) { + UNLOCK_HARDWARE(radeon); + fprintf(stderr, "Error: R300 timed out... exiting\n"); + exit(-1); + } +} + +static void radeonWaitForIdle(radeonContextPtr radeon) +{ + LOCK_HARDWARE(radeon); + radeonWaitForIdleLocked(radeon); + UNLOCK_HARDWARE(radeon); +} + + +/* Copy the back color buffer to the front color buffer. + */ +void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, + const drm_clip_rect_t *rect) +{ + radeonContextPtr rmesa; + GLint nbox, i, ret; + GLboolean missed_target; + int64_t ust; + __DRIscreenPrivate *psp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); + } + + radeon_firevertices(rmesa); + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + radeonWaitForFrameCompletion( rmesa ); + if (!rect) + { + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, & missed_target ); + LOCK_HARDWARE( rmesa ); + } + + nbox = dPriv->numClipRects; /* must be in locked region */ + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t *b = rmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + + *b = box[i]; + + if (rect) + { + if (rect->x1 > b->x1) + b->x1 = rect->x1; + if (rect->y1 > b->y1) + b->y1 = rect->y1; + if (rect->x2 < b->x2) + b->x2 = rect->x2; + if (rect->y2 < b->y2) + b->y2 = rect->y2; + + if (b->x1 >= b->x2 || b->y1 >= b->y2) + continue; + } + + b++; + n++; + } + rmesa->sarea->nbox = n; + + if (!n) + continue; + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); + + if ( ret ) { + fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); + UNLOCK_HARDWARE( rmesa ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + if (!rect) + { + psp = dPriv->driScreenPriv; + rmesa->swap_count++; + (*psp->systemTime->getUST)( & ust ); + if ( missed_target ) { + rmesa->swap_missed_count++; + rmesa->swap_missed_ust = ust - rmesa->swap_ust; + } + + rmesa->swap_ust = ust; + rmesa->hw.all_dirty = GL_TRUE; + + } +} + +void radeonPageFlip( __DRIdrawablePrivate *dPriv ) +{ + radeonContextPtr rmesa; + GLint ret; + GLboolean missed_target; + __DRIscreenPrivate *psp; + struct radeon_renderbuffer *rrb; + GLframebuffer *fb = dPriv->driverPrivate; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + + psp = dPriv->driScreenPriv; + + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage); + } + + radeon_firevertices(rmesa); + + LOCK_HARDWARE( rmesa ); + + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(rmesa); + usleep(10000); /* throttle invisible client 10ms */ + return; + } + + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t *b = rmesa->sarea->boxes; + b[0] = box[0]; + rmesa->sarea->nbox = 1; + + /* Throttle the frame rate -- only allow a few pending swap buffers + * request at a time. + */ + radeonWaitForFrameCompletion( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, & missed_target ); + if ( missed_target ) { + rmesa->swap_missed_count++; + (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); + } + LOCK_HARDWARE( rmesa ); + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); + exit( 1 ); + } + + rmesa->swap_count++; + (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); + + /* Get ready for drawing next frame. Update the renderbuffers' + * flippedOffset/Pitch fields so we draw into the right place. + */ + driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, + rmesa->sarea->pfCurrentPage); + + rmesa->state.color.rrb = rrb; + + if (rmesa->vtbl.update_draw_buffer) + rmesa->vtbl.update_draw_buffer(rmesa->glCtx); +} + + +/** + * Swap front and back buffer. + */ +void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + radeonContextPtr radeon; + GLcontext *ctx; + + radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = radeon->glCtx; + + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ + if (radeon->doPageFlip) { + radeonPageFlip(dPriv); + } else { + radeonCopyBuffer(dPriv, NULL); + } + } + } else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "%s: drawable has no context!", + __FUNCTION__); + } +} + +void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h ) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + radeonContextPtr radeon; + GLcontext *ctx; + + radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = radeon->glCtx; + + if (ctx->Visual.doubleBufferMode) { + drm_clip_rect_t rect; + rect.x1 = x + dPriv->x; + rect.y1 = (dPriv->h - y - h) + dPriv->y; + rect.x2 = rect.x1 + w; + rect.y2 = rect.y1 + h; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + radeonCopyBuffer(dPriv, &rect); + } + } else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "%s: drawable has no context!", + __FUNCTION__); + } +} + + +static void radeon_print_state_atom( struct radeon_state_atom *state ) +{ + int i; + + fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); + + if (RADEON_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < state->cmd_size ; i++) + fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); + +} + +static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) +{ + BATCH_LOCALS(radeon); + struct radeon_state_atom *atom; + int dwords; + + if (radeon->vtbl.pre_emit_atoms) + radeon->vtbl.pre_emit_atoms(radeon); + + /* Emit actual atoms */ + foreach(atom, &radeon->hw.atomlist) { + if ((atom->dirty || radeon->hw.all_dirty) == dirty) { + dwords = (*atom->check) (radeon->glCtx, atom); + if (dwords) { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + radeon_print_state_atom(atom); + } + if (atom->emit) { + (*atom->emit)(radeon->glCtx, atom); + } else { + BEGIN_BATCH_NO_AUTOSTATE(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + } + atom->dirty = GL_FALSE; + } else { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + fprintf(stderr, " skip state %s\n", + atom->name); + } + } + } + } + + COMMIT_BATCH(); +} + +void radeonEmitState(radeonContextPtr radeon) +{ + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->vtbl.pre_emit_state) + radeon->vtbl.pre_emit_state(radeon); + + /* this code used to return here but now it emits zbs */ + if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) + return; + + /* To avoid going across the entire set of states multiple times, just check + * for enough space for the case of emitting all state, and inline the + * radeonAllocCmdBuf code here without all the checks. + */ + rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); + + if (!radeon->cmdbuf.cs->cdw) { + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin reemit state\n"); + + radeonEmitAtoms(radeon, GL_FALSE); + } + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin dirty state\n"); + + radeonEmitAtoms(radeon, GL_TRUE); + radeon->hw.is_dirty = GL_FALSE; + radeon->hw.all_dirty = GL_FALSE; + +} + + +void radeonFlush(GLcontext *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->dma.flush) + radeon->dma.flush( ctx ); + + radeonEmitState(radeon); + + if (radeon->cmdbuf.cs->cdw) + rcommonFlushCmdBuf(radeon, __FUNCTION__); +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +void radeonFinish(GLcontext * ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + + radeonFlush(ctx); + + if (radeon->radeonScreen->kernel_mm) { + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + struct radeon_renderbuffer *rrb; + rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; + if (rrb->bo) + radeon_bo_wait(rrb->bo); + } + } else if (radeon->do_irqs) { + LOCK_HARDWARE(radeon); + radeonEmitIrqLocked(radeon); + UNLOCK_HARDWARE(radeon); + radeonWaitIrq(radeon); + } else { + radeonWaitForIdle(radeon); + } +} + +/* cmdbuffer */ +/** + * Send the current command buffer via ioctl to the hardware. + */ +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) +{ + int ret = 0; + + if (rmesa->cmdbuf.flushing) { + fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); + exit(-1); + } + rmesa->cmdbuf.flushing = 1; + if (rmesa->cmdbuf.cs->cdw) { + ret = radeon_cs_emit(rmesa->cmdbuf.cs); + rmesa->hw.all_dirty = GL_TRUE; + } + radeon_cs_erase(rmesa->cmdbuf.cs); + rmesa->cmdbuf.flushing = 0; + return ret; +} + +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) +{ + int ret; + + radeonReleaseDmaRegion(rmesa); + + LOCK_HARDWARE(rmesa); + ret = rcommonFlushCmdBufLocked(rmesa, caller); + UNLOCK_HARDWARE(rmesa); + + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + _mesa_exit(ret); + } + + return ret; +} + +/** + * Make sure that enough space is available in the command buffer + * by flushing if necessary. + * + * \param dwords The number of dwords we need to be free on the command buffer + */ +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) +{ + if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || + radeon_cs_need_flush(rmesa->cmdbuf.cs)) { + rcommonFlushCmdBuf(rmesa, caller); + } +} + +void rcommonInitCmdBuf(radeonContextPtr rmesa) +{ + GLuint size; + /* Initialize command buffer */ + size = 256 * driQueryOptioni(&rmesa->optionCache, + "command_buffer_size"); + if (size < 2 * rmesa->hw.max_state_size) { + size = 2 * rmesa->hw.max_state_size + 65535; + } + if (size > 64 * 256) + size = 64 * 256; + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { + fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", + sizeof(drm_r300_cmd_header_t)); + fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", + sizeof(drm_radeon_cmd_buffer_t)); + fprintf(stderr, + "Allocating %d bytes command buffer (max state is %d bytes)\n", + size * 4, rmesa->hw.max_state_size * 4); + } + + if (rmesa->radeonScreen->kernel_mm) { + int fd = rmesa->radeonScreen->driScreen->fd; + rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); + } else { + rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); + } + if (rmesa->cmdbuf.csm == NULL) { + /* FIXME: fatal error */ + return; + } + rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); + assert(rmesa->cmdbuf.cs != NULL); + rmesa->cmdbuf.size = size; + + if (!rmesa->radeonScreen->kernel_mm) { + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); + } else { + struct drm_radeon_gem_info mminfo; + + if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) + { + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_size); + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); + } + } + +} +/** + * Destroy the command buffer + */ +void rcommonDestroyCmdBuf(radeonContextPtr rmesa) +{ + radeon_cs_destroy(rmesa->cmdbuf.cs); + if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { + radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); + } else { + radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); + } +} + +void rcommonBeginBatch(radeonContextPtr rmesa, int n, + int dostate, + const char *file, + const char *function, + int line) +{ + rcommonEnsureCmdBufSpace(rmesa, n, function); + if (!rmesa->cmdbuf.cs->cdw && dostate) { + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "Reemit state after flush (from %s)\n", function); + radeonEmitState(rmesa); + } + radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); +} + + + diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h new file mode 100644 index 0000000000..cc9d579ea1 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -0,0 +1,56 @@ +#ifndef COMMON_MISC_H +#define COMMON_MISC_H + +#include "radeon_common_context.h" +#include "radeon_buffer.h" +#include "radeon_dma.h" +#include "radeon_texture.h" + +void radeonRecalcScissorRects(radeonContextPtr radeon); +void radeonSetCliprects(radeonContextPtr radeon); +void radeonUpdateScissor( GLcontext *ctx ); +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); + +void radeonWaitForIdleLocked(radeonContextPtr radeon); +extern uint32_t radeonGetAge(radeonContextPtr radeon); +void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, + const drm_clip_rect_t *rect); +void radeonPageFlip( __DRIdrawablePrivate *dPriv ); +void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); +void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h ); + +void radeonUpdatePageFlipping(radeonContextPtr rmesa); + +void radeonFlush(GLcontext *ctx); +void radeonFinish(GLcontext * ctx); +void radeonEmitState(radeonContextPtr radeon); + +static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + rrb = rmesa->state.depth.rrb; + if (!rrb) + return NULL; + + return rrb; +} + +static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; + + rrb = rmesa->state.color.rrb; + if (rmesa->radeonScreen->driScreen->dri2.enabled) { + rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + } + if (!rrb) + return NULL; + return rrb; +} + +#include "radeon_cmdbuf.h" + + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c new file mode 100644 index 0000000000..8acde2b90c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -0,0 +1,584 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "radeon_common.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#include "utils.h" +#include "drirenderbuffer.h" +#include "vblank.h" + +#define DRIVER_DATE "20090101" + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0); +#endif + +/* Return various strings for glGetString(). + */ +static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + if (IS_R300_CLASS(radeon->radeonScreen)) + return (GLubyte *) "DRI R300 Project"; + else + return (GLubyte *) "Tungsten Graphics, Inc."; + + case GL_RENDERER: + { + unsigned offset; + GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : + radeon->radeonScreen->AGPMode; + const char* chipname; + + if (IS_R300_CLASS(radeon->radeonScreen)) + chipname = "R300"; + else if (IS_R200_CLASS(radeon->radeonScreen)) + chipname = "R200"; + else + chipname = "R100"; + + offset = driGetRendererString(buffer, chipname, DRIVER_DATE, + agp_mode); + + if (IS_R300_CLASS(radeon->radeonScreen)) { + sprintf(&buffer[offset], " %sTCL", + (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) + ? "" : "NO-"); + } else { + sprintf(&buffer[offset], " %sTCL", + !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) + ? "" : "NO-"); + } + + if (radeon->radeonScreen->driScreen->dri2.enabled) + strcat(buffer, " DRI2"); + + return (GLubyte *) buffer; + } + + default: + return NULL; + } +} + +/* Initialize the driver's misc functions. + */ +static void radeonInitDriverFuncs(struct dd_function_table *functions) +{ + functions->GetString = radeonGetString; +} + +/** + * Create and initialize all common fields of the context, + * including the Mesa context itself. + */ +GLboolean radeonInitContext(radeonContextPtr radeon, + struct dd_function_table* functions, + const __GLcontextModes * glVisual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); + GLcontext* ctx; + GLcontext* shareCtx; + int fthrottle_mode; + + /* Fill in additional standard functions. */ + radeonInitDriverFuncs(functions); + + radeon->radeonScreen = screen; + /* Allocate and initialize the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + radeon->glCtx = _mesa_create_context(glVisual, shareCtx, + functions, (void *)radeon); + if (!radeon->glCtx) + return GL_FALSE; + + ctx = radeon->glCtx; + driContextPriv->driverPrivate = radeon; + + /* DRI fields */ + radeon->dri.context = driContextPriv; + radeon->dri.screen = sPriv; + radeon->dri.drawable = NULL; + radeon->dri.readable = NULL; + radeon->dri.hwContext = driContextPriv->hHWContext; + radeon->dri.hwLock = &sPriv->pSAREA->lock; + radeon->dri.fd = sPriv->fd; + radeon->dri.drmMinor = sPriv->drm_version.minor; + + radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + + screen->sarea_priv_offset); + + /* Setup IRQs */ + fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); + radeon->iw.irq_seq = -1; + radeon->irqsEmitted = 0; + radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && + radeon->radeonScreen->irq); + + radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + if (!radeon->do_irqs) + fprintf(stderr, + "IRQ's not enabled, falling back to %s: %d %d\n", + radeon->do_usleeps ? "usleeps" : "busy waits", + fthrottle_mode, radeon->radeonScreen->irq); + + (*sPriv->systemTime->getUST) (&radeon->swap_ust); + + return GL_TRUE; +} + +/** + * Cleanup common context fields. + * Called by r200DestroyContext/r300DestroyContext + */ +void radeonCleanupContext(radeonContextPtr radeon) +{ + FILE *track; + struct radeon_renderbuffer *rb; + GLframebuffer *fb; + + /* free the Mesa context */ + _mesa_destroy_context(radeon->glCtx); + + fb = (void*)radeon->dri.drawable->driverPrivate; + rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + fb = (void*)radeon->dri.readable->driverPrivate; + rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + + /* _mesa_destroy_context() might result in calls to functions that + * depend on the DriverCtx, so don't set it to NULL before. + * + * radeon->glCtx->DriverCtx = NULL; + */ + + + + /* free the option cache */ + driDestroyOptionCache(&radeon->optionCache); + + rcommonDestroyCmdBuf(radeon); + + if (radeon->state.scissor.pClipRects) { + FREE(radeon->state.scissor.pClipRects); + radeon->state.scissor.pClipRects = 0; + } + track = fopen("/tmp/tracklog", "w"); + if (track) { + radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); + fclose(track); + } +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, + radeon->glCtx); + + return GL_TRUE; +} + + +static void +radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, + GLframebuffer *draw) +{ + /* if radeon->fake */ + struct radeon_renderbuffer *rb; + + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->frontOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->backOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } +} + +static void +radeon_make_renderbuffer_current(radeonContextPtr radeon, + GLframebuffer *draw) +{ + int size = 4096*4096*4; + /* if radeon->fake */ + struct radeon_renderbuffer *rb; + + if (radeon->radeonScreen->kernel_mm) { + radeon_make_kernel_renderbuffer_current(radeon, draw); + return; + } + + + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->frontOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->backOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } +} + + +void +radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +{ + unsigned int attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + struct radeon_renderbuffer *rb; + int i, count; + GLframebuffer *draw; + radeonContextPtr radeon; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); + + draw = drawable->driverPrivate; + screen = context->driScreenPriv; + radeon = (radeonContextPtr) context->driverPrivate; + i = 0; + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_DEPTH; + } + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + /* set one cliprect to cover the whole drawable */ + drawable->x = 0; + drawable->y = 0; + drawable->backX = 0; + drawable->backY = 0; + drawable->numClipRects = 1; + drawable->pClipRects[0].x1 = 0; + drawable->pClipRects[0].y1 = 0; + drawable->pClipRects[0].x2 = drawable->w; + drawable->pClipRects[0].y2 = drawable->h; + drawable->numBackClipRects = 1; + drawable->pBackClipRects[0].x1 = 0; + drawable->pBackClipRects[0].y1 = 0; + drawable->pBackClipRects[0].x2 = drawable->w; + drawable->pBackClipRects[0].y2 = drawable->h; + for (i = 0; i < count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + if (rb->bo == NULL) { + fprintf(stderr, "failled to attach front %d\n", + buffers[i].name); + } + break; + case __DRI_BUFFER_BACK_LEFT: + rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_DEPTH: + rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_STENCIL: + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + } + radeon = (radeonContextPtr) context->driverPrivate; + driUpdateFramebufferSize(radeon->glCtx, drawable); +} + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + radeonContextPtr radeon; + GLframebuffer *dfb, *rfb; + + if (!driContextPriv) { + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx is null\n", __FUNCTION__); + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + radeon = (radeonContextPtr) driContextPriv->driverPrivate; + dfb = driDrawPriv->driverPrivate; + rfb = driReadPriv->driverPrivate; + + if (driContextPriv->driScreenPriv->dri2.enabled) { + radeon_update_renderbuffers(driContextPriv, driDrawPriv); + if (driDrawPriv != driReadPriv) + radeon_update_renderbuffers(driContextPriv, driReadPriv); + radeon->state.color.rrb = + (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + radeon->state.depth.rrb = + (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; + } else { + radeon_make_renderbuffer_current(radeon, dfb); + } + + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); + + driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); + if (driReadPriv != driDrawPriv) + driUpdateFramebufferSize(radeon->glCtx, driReadPriv); + + + + _mesa_make_current(radeon->glCtx, dfb, rfb); + + if (radeon->dri.drawable != driDrawPriv) { + if (driDrawPriv->swap_interval == (unsigned)-1) { + driDrawPriv->vblFlags = + (radeon->radeonScreen->irq != 0) + ? driGetDefaultVBlankFlags(&radeon-> + optionCache) + : VBLANK_FLAG_NO_IRQ; + + driDrawableInitVBlank(driDrawPriv); + } + } + + radeon->dri.readable = driReadPriv; + + if (radeon->dri.drawable != driDrawPriv || + radeon->lastStamp != driDrawPriv->lastStamp) { + radeon->dri.drawable = driDrawPriv; + + radeonSetCliprects(radeon); + radeon->vtbl.update_viewport_offset(radeon->glCtx); + } + + _mesa_update_state(radeon->glCtx); + + if (!driContextPriv->driScreenPriv->dri2.enabled) { + radeonUpdatePageFlipping(radeon); + } + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "End %s\n", __FUNCTION__); + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h new file mode 100644 index 0000000000..b88aeab051 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -0,0 +1,513 @@ + +#ifndef COMMON_CONTEXT_H +#define COMMON_CONTEXT_H + +#include "main/mm.h" +#include "math/m_vector.h" +#include "texmem.h" +#include "tnl/t_context.h" +#include "main/colormac.h" + +#include "radeon_screen.h" +#include "radeon_drm.h" +#include "dri_util.h" +#include "tnl/t_vertex.h" + +/* This union is used to avoid warnings/miscompilation + with float to uint32_t casts due to strict-aliasing */ +typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + + +#define TEX_0 0x1 +#define TEX_1 0x2 +#define TEX_2 0x4 +#define TEX_3 0x8 +#define TEX_4 0x10 +#define TEX_5 0x20 + +/* Rasterizing fallbacks */ +/* See correponding strings in r200_swtcl.c */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_STENCIL 0x0004 +#define RADEON_FALLBACK_RENDER_MODE 0x0008 +#define RADEON_FALLBACK_BLEND_EQ 0x0010 +#define RADEON_FALLBACK_BLEND_FUNC 0x0020 +#define RADEON_FALLBACK_DISABLE 0x0040 +#define RADEON_FALLBACK_BORDER_MODE 0x0080 + +#define R200_FALLBACK_TEXTURE 0x01 +#define R200_FALLBACK_DRAW_BUFFER 0x02 +#define R200_FALLBACK_STENCIL 0x04 +#define R200_FALLBACK_RENDER_MODE 0x08 +#define R200_FALLBACK_DISABLE 0x10 +#define R200_FALLBACK_BORDER_MODE 0x20 + +#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ +#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ +#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ +#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ +#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ +#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ +#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ +#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ +#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ + +/* The blit width for texture uploads + */ +#define BLIT_WIDTH_BYTES 1024 + +/* Use the templated vertex format: + */ +#define COLOR_IS_RGBA +#define TAG(x) radeon##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +struct radeon_colorbuffer_state { + GLuint clear; + int roundEnable; + struct radeon_renderbuffer *rrb; +}; + +struct radeon_depthbuffer_state { + GLuint clear; + GLfloat scale; + struct radeon_renderbuffer *rrb; +}; + +struct radeon_scissor_state { + drm_clip_rect_t rect; + GLboolean enabled; + + GLuint numClipRects; /* Cliprects active */ + GLuint numAllocedClipRects; /* Cliprects available */ + drm_clip_rect_t *pClipRects; +}; + +struct radeon_stencilbuffer_state { + GLboolean hwBuffer; + GLuint clear; /* rb3d_stencilrefmask value */ +}; + +struct radeon_stipple_state { + GLuint mask[32]; +}; + +struct radeon_state_atom { + struct radeon_state_atom *next, *prev; + const char *name; /* for debug */ + int cmd_size; /* size in bytes */ + GLuint idx; + GLuint is_tcl; + GLuint *cmd; /* one or more cmd's */ + GLuint *lastcmd; /* one or more cmd's */ + GLboolean dirty; /* dirty-mark in emit_state_list */ + int (*check) (GLcontext *, struct radeon_state_atom *atom); /* is this state active? */ + void (*emit) (GLcontext *, struct radeon_state_atom *atom); +}; + +struct radeon_hw_state { + /* Head of the linked list of state atoms. */ + struct radeon_state_atom atomlist; + int max_state_size; /* Number of bytes necessary for a full state emit. */ + GLboolean is_dirty, all_dirty; +}; + + +/* Texture related */ +typedef struct _radeon_texture_image radeon_texture_image; + +struct _radeon_texture_image { + struct gl_texture_image base; + + /** + * If mt != 0, the image is stored in hardware format in the + * given mipmap tree. In this case, base.Data may point into the + * mapping of the buffer object that contains the mipmap tree. + * + * If mt == 0, the image is stored in normal memory pointed to + * by base.Data. + */ + struct _radeon_mipmap_tree *mt; + struct radeon_bo *bo; + + int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ + int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ +}; + + +static INLINE radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) +{ + return (radeon_texture_image*)image; +} + + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +#define RADEON_TXO_MICRO_TILE (1 << 3) + +/* Texture object in locally shared texture space. + */ +struct radeon_tex_obj { + // driTextureObject base; + struct gl_texture_object base; + struct _radeon_mipmap_tree *mt; + + /** + * This is true if we've verified that the mipmap tree above is complete + * and so on. + */ + GLboolean validated; + + GLuint override_offset; + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint tile_bits; /* hw texture tile bits used on this texture */ + struct radeon_bo *bo; + + GLuint bufAddr; /* Offset to start of locally + shared texture block */ + + GLuint dirty_state; /* Flags (1 per texunit) for + whether or not this texobj + has dirty hardware state + (pp_*) that needs to be + brought into the + texunit. */ + + drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; + /* Six, for the cube faces */ + + + + GLuint pp_txfilter; /* hardware register values */ + GLuint pp_txformat; + GLuint pp_txformat_x; + GLuint pp_txoffset; /* Image location in texmem. + All cube faces follow. */ + GLuint pp_txsize; /* npot only */ + GLuint pp_txpitch; /* npot only */ + GLuint pp_border_color; + GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ + + GLuint pp_txfilter_1; /* r300 */ + + GLboolean border_fallback; + + +}; + +static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) +{ + return (radeonTexObj*)texObj; +} + +/* Need refcounting on dma buffers: + */ +struct radeon_dma_buffer { + int refcount; /* the number of retained regions in buf */ + drmBufPtr buf; +}; + +struct radeon_aos { + struct radeon_bo *bo; /** Buffer object where vertex data is stored */ + int offset; /** Offset into buffer object, in bytes */ + int components; /** Number of components per vertex */ + int stride; /** Stride in dwords (may be 0 for repeating) */ + int count; /** Number of vertices */ +}; + +struct radeon_dma { + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ + int current_used; /** Number of bytes allocated and forgotten about */ + int current_vertexptr; /** End of active vertex region */ + + /** + * If current_vertexptr != current_used then flush must be non-zero. + * flush must be called before non-active vertex allocations can be + * performed. + */ + void (*flush) (GLcontext *); + + /* Number of "in-flight" DMA buffers, i.e. the number of buffers + * for which a DISCARD command is currently queued in the command buffer +. + */ + GLuint nr_released_bufs; +}; + +/* radeon_swtcl.c + */ +struct radeon_swtcl_info { + + GLuint RenderIndex; + GLuint vertex_size; + GLubyte *verts; + + /* Fallback rasterization functions + */ + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + +}; + +struct radeon_ioctl { + GLuint vertex_offset; + struct radeon_bo *bo; + GLuint vertex_size; +}; + +#define RADEON_MAX_PRIMS 64 + +struct radeon_prim { + GLuint start; + GLuint end; + GLuint prim; +}; + +static INLINE GLuint radeonPackColor(GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (cpp) { + case 2: + return PACK_COLOR_565(r, g, b); + case 4: + return PACK_COLOR_8888(a, r, g, b); + default: + return 0; + } +} + +#define MAX_CMD_BUF_SZ (16*1024) + +#define MAX_DMA_BUF_SZ (64*1024) + +struct radeon_store { + GLuint statenr; + GLuint primnr; + char cmd_buf[MAX_CMD_BUF_SZ]; + int cmd_used; + int elts_start; +}; + +struct radeon_dri_mirror { + __DRIcontextPrivate *context; /* DRI context */ + __DRIscreenPrivate *screen; /* DRI screen */ + + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *drawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *readable; + + drm_context_t hwContext; + drm_hw_lock_t *hwLock; + int fd; + int drmMinor; +}; + +#define DEBUG_TEXTURE 0x001 +#define DEBUG_STATE 0x002 +#define DEBUG_IOCTL 0x004 +#define DEBUG_PRIMS 0x008 +#define DEBUG_VERTS 0x010 +#define DEBUG_FALLBACKS 0x020 +#define DEBUG_VFMT 0x040 +#define DEBUG_CODEGEN 0x080 +#define DEBUG_VERBOSE 0x100 +#define DEBUG_DRI 0x200 +#define DEBUG_DMA 0x400 +#define DEBUG_SANITY 0x800 +#define DEBUG_SYNC 0x1000 +#define DEBUG_PIXEL 0x2000 +#define DEBUG_MEMORY 0x4000 + + + +typedef void (*radeon_tri_func) (radeonContextPtr, + radeonVertex *, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_line_func) (radeonContextPtr, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); + +struct radeon_state { + struct radeon_colorbuffer_state color; + struct radeon_depthbuffer_state depth; + struct radeon_scissor_state scissor; + struct radeon_stencilbuffer_state stencil; +}; + +/** + * This structure holds the command buffer while it is being constructed. + * + * The first batch of commands in the buffer is always the state that needs + * to be re-emitted when the context is lost. This batch can be skipped + * otherwise. + */ +struct radeon_cmdbuf { + struct radeon_cs_manager *csm; + struct radeon_cs *cs; + int size; /** # of dwords total */ + unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ +}; + +struct radeon_context { + GLcontext *glCtx; + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + + /* Texture object bookkeeping + */ + unsigned nr_heaps; + driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; + driTextureObject swapped; + int texture_depth; + float initialMaxAnisotropy; + + struct radeon_dma dma; + struct radeon_hw_state hw; + /* Rasterization and vertex state: + */ + GLuint TclFallback; + GLuint Fallback; + GLuint NewGLState; + DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ + + /* Page flipping */ + GLuint doPageFlip; + + /* Drawable, cliprect and scissor information */ + GLuint numClipRects; /* Cliprects for the draw buffer */ + drm_clip_rect_t *pClipRects; + unsigned int lastStamp; + GLboolean lost_context; + drm_radeon_sarea_t *sarea; /* Private SAREA data */ + + /* Mirrors of some DRI state */ + struct radeon_dri_mirror dri; + + /* Busy waiting */ + GLuint do_usleeps; + GLuint do_irqs; + GLuint irqsEmitted; + drm_radeon_irq_wait_t iw; + + /* buffer swap */ + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + /* Derived state - for r300 only */ + struct radeon_state state; + + struct radeon_swtcl_info swtcl; + /* Configuration cache + */ + driOptionCache optionCache; + + struct radeon_cmdbuf cmdbuf; + + struct { + void (*get_lock)(radeonContextPtr radeon); + void (*update_viewport_offset)(GLcontext *ctx); + void (*update_draw_buffer)(GLcontext *ctx); + void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); + void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); + void (*pre_emit_atoms)(radeonContextPtr rmesa); + void (*pre_emit_state)(radeonContextPtr rmesa); + } vtbl; +}; + +#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) + +/** + * This function takes a float and packs it into a uint32_t + */ +static INLINE uint32_t radeonPackFloat32(float fl) +{ + union { + float fl; + uint32_t u; + } u; + + u.fl = fl; + return u.u; +} + +/* This is probably wrong for some values, I need to test this + * some more. Range checking would be a good idea also.. + * + * But it works for most things. I'll fix it later if someone + * else with a better clue doesn't + */ +static INLINE uint32_t radeonPackFloat24(float f) +{ + float mantissa; + int exponent; + uint32_t float24 = 0; + + if (f == 0.0) + return 0; + + mantissa = frexpf(f, &exponent); + + /* Handle -ve */ + if (mantissa < 0) { + float24 |= (1 << 23); + mantissa = mantissa * -1.0; + } + /* Handle exponent, bias of 63 */ + exponent += 62; + float24 |= (exponent << 16); + /* Kill 7 LSB of mantissa */ + float24 |= (radeonPackFloat32(mantissa) & 0x7FFFFF) >> 7; + + return float24; +} + +GLboolean radeonInitContext(radeonContextPtr radeon, + struct dd_function_table* functions, + const __GLcontextModes * glVisual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +void radeonCleanupContext(radeonContextPtr radeon); +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); +void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); +GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 + +#if DO_DEBUG +extern int RADEON_DEBUG; +#else +#define RADEON_DEBUG 0 +#endif + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index b25f036c44..0296cffc20 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -53,8 +53,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drivers/common/driverfuncs.h" +#include "radeon_common.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_span.h" @@ -77,36 +77,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ -/* Return various strings for glGetString(). - */ -static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - static char buffer[128]; - unsigned offset; - GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : - rmesa->radeon.radeonScreen->AGPMode; - - switch ( name ) { - case GL_VENDOR: - return (GLubyte *)"Tungsten Graphics, Inc."; - - case GL_RENDERER: - offset = driGetRendererString( buffer, "Radeon", DRIVER_DATE, - agp_mode ); - - sprintf( & buffer[ offset ], " %sTCL", - !(rmesa->radeon.TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) - ? "" : "NO-" ); - - return (GLubyte *)buffer; - - default: - return NULL; - } -} - - /* Extension strings exported by the R100 driver. */ const struct dri_extension card_extensions[] = @@ -163,15 +133,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = { NULL, }; - - -/* Initialize the driver's misc functions. - */ -static void radeonInitDriverFuncs( struct dd_function_table *functions ) -{ - functions->GetString = radeonGetString; -} - static const struct dri_debug_control debug_control[] = { { "fall", DEBUG_FALLBACKS }, @@ -292,7 +253,6 @@ radeonCreateContext( const __GLcontextModes *glVisual, * (the texture functions are especially important) */ _mesa_init_driver_functions( &functions ); - radeonInitDriverFuncs( &functions ); radeonInitTextureFuncs( &functions ); if (!radeonInitContext(&rmesa->radeon, &functions, diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index d05e47f16e..2efabd1f55 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -53,8 +53,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "radeon_screen.h" -#include "common_context.h" -#include "common_misc.h" +#include "radeon_common.h" struct r100_context; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index fbb93a8ba1..2db3f7a68d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -31,8 +31,6 @@ */ #include - -#include "common_context.h" #include "radeon_cs.h" #include "radeon_cs_legacy.h" #include "radeon_bo_legacy.h" @@ -234,7 +232,7 @@ static int cs_process_relocs(struct radeon_cs *cs) } cs->packets[relocs[i].indices[j]] += soffset; if (cs->packets[relocs[i].indices[j]] >= eoffset) { - radeon_bo_debug(relocs[i].base.bo, 12); + /* radeon_bo_debug(relocs[i].base.bo, 12); */ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", relocs[i].base.bo, soffset, eoffset); fprintf(stderr, "above end: %p 0x%08X 0x%08X\n", diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index 4da2479eee..19d904174f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -33,7 +33,7 @@ #define RADEON_CS_LEGACY_H #include "radeon_cs.h" -#include "common_context.h" +#include "radeon_common.h" struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c new file mode 100644 index 0000000000..393b12182d --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -0,0 +1,323 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "radeon_common.h" + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ + : "0" (nr), \ + "D" ((long)dst), \ + "S" ((long)src) ); \ +} while (0) +#else +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int j; \ + for ( j = 0 ; j < nr ; j++ ) \ + dst[j] = ((int *)src)[j]; \ + dst += nr; \ +} while (0) +#endif + +static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 4) + COPY_DWORDS(out, data, count); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out++; + data += stride; + } +} + +void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 8) + COPY_DWORDS(out, data, count * 2); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out += 2; + data += stride; + } +} + +void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 12) { + COPY_DWORDS(out, data, count * 3); + } + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out += 3; + data += stride; + } +} + +static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 16) + COPY_DWORDS(out, data, count * 4); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out[3] = *(int *)(data + 12); + out += 4; + data += stride; + } +} + +void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, + GLvoid * data, int size, int stride, int count) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + uint32_t *out; + + if (stride == 0) { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); + count = 1; + aos->stride = 0; + } else { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); + aos->stride = size; + } + + aos->components = size; + aos->count = count; + + out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + switch (size) { + case 1: radeonEmitVec4(out, data, stride, count); break; + case 2: radeonEmitVec8(out, data, stride, count); break; + case 3: radeonEmitVec12(out, data, stride, count); break; + case 4: radeonEmitVec16(out, data, stride, count); break; + default: + assert(0); + break; + } +} + +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) +{ + struct radeon_cs_space_check bos[1]; + int flushed = 0, ret; + + size = MAX2(size, MAX_DMA_BUF_SZ * 16); + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) { + rmesa->dma.flush(rmesa->glCtx); + } + + if (rmesa->dma.nr_released_bufs > 4) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + rmesa->dma.nr_released_bufs = 0; + } + + if (rmesa->dma.current) { + radeon_bo_unmap(rmesa->dma.current); + radeon_bo_unref(rmesa->dma.current); + rmesa->dma.current = 0; + } + +again_alloc: + rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, + 0, size, 4, RADEON_GEM_DOMAIN_GTT, + 0); + + if (!rmesa->dma.current) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + rmesa->dma.nr_released_bufs = 0; + goto again_alloc; + } + + rmesa->dma.current_used = 0; + rmesa->dma.current_vertexptr = 0; + + bos[0].bo = rmesa->dma.current; + bos[0].read_domains = RADEON_GEM_DOMAIN_GTT; + bos[0].write_domain =0 ; + bos[0].new_accounted = 0; + + ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) { + fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen"); + assert(0); + } else if (ret == RADEON_CS_SPACE_FLUSH) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + if (flushed) { + fprintf(stderr,"flushed but still no space\n"); + assert(0); + } + flushed = 1; + goto again_alloc; + } + radeon_bo_map(rmesa->dma.current, 1); +} + +/* Allocates a region from rmesa->dma.current. If there isn't enough + * space in current, grab a new buffer (and discard what was left of current) + */ +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); + + if (rmesa->dma.flush) + rmesa->dma.flush(rmesa->glCtx); + + assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); + + alignment--; + rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; + + if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) + radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); + + *poffset = rmesa->dma.current_used; + *pbo = rmesa->dma.current; + radeon_bo_ref(*pbo); + + /* Always align to at least 16 bytes */ + rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; + + assert(rmesa->dma.current_used <= rmesa->dma.current->size); +} + +void radeonReleaseDmaRegion(radeonContextPtr rmesa) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current); + if (rmesa->dma.current) { + rmesa->dma.nr_released_bufs++; + radeon_bo_unmap(rmesa->dma.current); + radeon_bo_unref(rmesa->dma.current); + } + rmesa->dma.current = NULL; +} + + +/* Flush vertices in the current dma region. + */ +void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_dma *dma = &rmesa->dma; + + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + dma->flush = NULL; + + if (dma->current) { + GLuint current_offset = dma->current_used; + + assert (dma->current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + dma->current_vertexptr); + + if (dma->current_used != dma->current_vertexptr) { + dma->current_used = dma->current_vertexptr; + + rmesa->vtbl.swtcl_flush(ctx, current_offset); + } + rmesa->swtcl.numverts = 0; + } +} +/* Alloc space in the current dma region. + */ +void * +rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + void *head; + + if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) { + radeonRefillCurrentDmaRegion(rmesa, bytes); + } + + if (!rmesa->dma.flush) { + rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + rmesa->dma.flush = rcommon_flush_last_swtcl_prim; + } + + ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); + ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); + ASSERT( rmesa->dma.current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current_vertexptr ); + + head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr); + rmesa->dma.current_vertexptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.h b/src/mesa/drivers/dri/radeon/radeon_dma.h new file mode 100644 index 0000000000..cee3744fed --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_dma.h @@ -0,0 +1,51 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef RADEON_DMA_H +#define RADEON_DMA_H + +void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count); +void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); + +void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, + GLvoid * data, int size, int stride, int count); + +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment); +void radeonReleaseDmaRegion(radeonContextPtr rmesa); + +void rcommon_flush_last_swtcl_prim(GLcontext *ctx); + +void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index d0cd9ce7a6..99b1ef332f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "radeon_context.h" -#include "common_cmdbuf.h" +#include "radeon_common.h" #include "radeon_cs.h" #include "radeon_state.h" #include "radeon_ioctl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c new file mode 100644 index 0000000000..9a7e76b245 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -0,0 +1,124 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Keith Whitwell + * Kevin E. Martin + */ + +#include "main/glheader.h" +#include "main/mtypes.h" +#include "main/colormac.h" +#include "dri_util.h" +#include "radeon_screen.h" +#include "radeon_common.h" +#include "radeon_lock.h" +#include "drirenderbuffer.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +/* Turn on/off page flipping according to the flags in the sarea: + */ +void radeonUpdatePageFlipping(radeonContextPtr rmesa) +{ + int use_back; + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + GLframebuffer *fb = drawable->driverPrivate; + + rmesa->doPageFlip = rmesa->sarea->pfState; + if (rmesa->glCtx->WinSysDrawBuffer) { + rmesa->vtbl.update_draw_buffer(rmesa->glCtx); + } + + use_back = rmesa->glCtx->DrawBuffer ? + (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == + BUFFER_BACK_LEFT) : 1; + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if (use_back) + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + else + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + + rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; +} + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock(radeonContextPtr rmesa, GLuint flags) +{ + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; + drm_radeon_sarea_t *sarea = rmesa->sarea; + + assert(drawable != NULL); + + drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); + } + + if (rmesa->lastStamp != drawable->lastStamp) { + radeonUpdatePageFlipping(rmesa); + radeonSetCliprects(rmesa); + rmesa->vtbl.update_viewport_offset(rmesa->glCtx); + driUpdateFramebufferSize(rmesa->glCtx, drawable); + } + + rmesa->vtbl.get_lock(rmesa); + + rmesa->lost_context = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index f2d17a54d4..f5ebb8dd54 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -39,9 +39,82 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin */ -#ifndef __RADEON_LOCK_H__ -#define __RADEON_LOCK_H__ +#ifndef COMMON_LOCK_H +#define COMMON_LOCK_H -#include "common_lock.h" +#include "main/colormac.h" +#include "radeon_screen.h" +#include "radeon_common.h" -#endif /* __RADEON_LOCK_H__ */ +extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); + +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 + +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( (rmesa), 0 ); \ + } \ + DEBUG_LOCK(); \ + } while (0) + +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_UNLOCK( (rmesa)->dri.fd, \ + (rmesa)->dri.hwLock, \ + (rmesa)->dri.hwContext ); \ + DEBUG_RESET(); \ + } \ + } while (0) + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 875e5e5aee..43dfa48aa7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -28,7 +28,7 @@ #ifndef __RADEON_MIPMAP_TREE_H_ #define __RADEON_MIPMAP_TREE_H_ -#include "common_context.h" +#include "radeon_common.h" typedef struct _radeon_mipmap_tree radeon_mipmap_tree; typedef struct _radeon_mipmap_level radeon_mipmap_level; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 7397218fb6..7f0d526ed2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -47,7 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" #include "radeon_screen.h" #include "radeon_buffer.h" -#include "common_misc.h" +#include "radeon_common.h" #include "radeon_span.h" #if !RADEON_COMMON #include "radeon_context.h" @@ -362,7 +362,7 @@ static const __DRItexBufferExtension r300TexBufferExtension = { }; #endif -int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) +static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) { screen->chip_flags = 0; switch ( device_id ) { diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index bd613f4779..ebd18a1634 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -43,14 +43,154 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "swrast/swrast.h" -#include "common_context.h" -#include "common_misc.h" +#include "radeon_common.h" +#include "radeon_lock.h" #include "radeon_span.h" #include "radeon_buffer.h" #define DBG 0 +static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 5; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 5) << 11; + offset += ((x & 31) >> 2) << 5; + offset += (x & 3) << 2; + } else { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 3) << 5; + offset += (x & 7) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 1; + } else { + nmacroblkpl = rrb->pitch >> 7; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 7) << 11; + offset += ((x & 127) >> 4) << 5; + offset += (x & 15) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 4) << 5; + offset += (x & 15) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint microblkxs; + GLint macroblkxs; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + microblkxs = 16 / rrb->cpp; + macroblkxs = 128 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } else { + microblkxs = 32 / rrb->cpp; + macroblkxs = 256 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } else { + microblkxs = 32 / rrb->cpp; + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } + return &ptr[offset]; +} + + /* * Note that all information needed to access pixels in a renderbuffer * should be obtained through the gl_renderbuffer parameter, not per-context @@ -215,6 +355,88 @@ do { \ #define TAG(x) radeon##x##_z24_s8 #include "stenciltmp.h" + +static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) +{ + struct radeon_renderbuffer *rrb = (void*)rb; + int r; + + if (rrb->bo) { + r = radeon_bo_map(rrb->bo, write); + if (r) { + fprintf(stderr, "(%s) error(%d) mapping buffer.\n", + __FUNCTION__, r); + } + } +} + +static void unmap_buffer(struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = (void*)rb; + + if (rrb->bo) { + radeon_bo_unmap(rrb->bo); + } +} + +static void radeonSpanRenderStart(GLcontext * ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int i; + + radeon_firevertices(rmesa); + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); + } + + /* color draw buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); + } + + map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); + + if (ctx->DrawBuffer->_DepthBuffer) { + map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); + } + if (ctx->DrawBuffer->_StencilBuffer) + map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); + + /* The locking and wait for idle should really only be needed in classic mode. + * In a future memory manager based implementation, this should become + * unnecessary due to the fact that mapping our buffers, textures, etc. + * should implicitly wait for any previous rendering commands that must + * be waited on. */ + LOCK_HARDWARE(rmesa); + radeonWaitForIdleLocked(rmesa); +} + +static void radeonSpanRenderFinish(GLcontext * ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int i; + _swrast_flush(ctx); + UNLOCK_HARDWARE(rmesa); + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); + } + + /* color draw buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) + unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); + + unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); + + if (ctx->DrawBuffer->_DepthBuffer) + unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (ctx->DrawBuffer->_StencilBuffer) + unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); +} + void radeonInitSpanFuncs(GLcontext * ctx) { struct swrast_device_driver *swdd = diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 7f90bc8090..86d872030b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -47,7 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_tcl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 1cfb539e71..a397c0824f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -38,7 +38,6 @@ #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_cs.h" #include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index 995ab2099e..af933a35f2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_swtcl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index 7281800ce2..5887ab355d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -42,8 +42,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" +#include "radeon_common.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_state.h" #include "radeon_ioctl.h" #include "radeon_tex.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c new file mode 100644 index 0000000000..beb21e7b43 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/mipmap.h" +#include "main/texformat.h" +#include "main/texstore.h" +#include "main/teximage.h" +#include "main/texobj.h" + +#include "xmlpool.h" /* for symbolic values of enum-type options */ + +#include "radeon_common.h" + +#include "radeon_mipmap_tree.h" + +/* textures */ +/** + * Allocate an empty texture image object. + */ +struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) +{ + return CALLOC(sizeof(radeon_texture_image)); +} + +/** + * Free memory associated with this texture image. + */ +void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) +{ + radeon_texture_image* image = get_radeon_texture_image(timage); + + if (image->mt) { + radeon_miptree_unreference(image->mt); + image->mt = 0; + assert(!image->base.Data); + } else { + _mesa_free_texture_image_data(ctx, timage); + } + if (image->bo) { + radeon_bo_unref(image->bo); + image->bo = NULL; + } + if (timage->Data) { + _mesa_free_texmemory(timage->Data); + timage->Data = NULL; + } +} + +/* Set Data pointer and additional data for mapped texture image */ +static void teximage_set_map_data(radeon_texture_image *image) +{ + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + + image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; + image->base.RowStride = lvl->rowstride / image->mt->bpp; +} + + +/** + * Map a single texture image for glTexImage and friends. + */ +void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) +{ + if (image->mt) { + assert(!image->base.Data); + + radeon_bo_map(image->mt->bo, write_enable); + teximage_set_map_data(image); + } +} + + +void radeon_teximage_unmap(radeon_texture_image *image) +{ + if (image->mt) { + assert(image->base.Data); + + image->base.Data = 0; + radeon_bo_unmap(image->mt->bo); + } +} + +/** + * Map a validated texture for reading during software rendering. + */ +void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + int face, level; + + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) + return; + + radeon_bo_map(t->mt->bo, GL_FALSE); + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); + } +} + +void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + int face, level; + + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) + return; + + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + texObj->Image[face][level]->Data = 0; + } + radeon_bo_unmap(t->mt->bo); +} + +GLuint radeon_face_for_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + default: + return 0; + } +} + +/** + * Wraps Mesa's implementation to ensure that the base level image is mapped. + * + * This relies on internal details of _mesa_generate_mipmap, in particular + * the fact that the memory for recreated texture images is always freed. + */ +static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int i, face; + + + _mesa_generate_mipmap(ctx, target, texObj); + + for (face = 0; face < nr_faces; face++) { + for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { + radeon_texture_image *image; + + image = get_radeon_texture_image(texObj->Image[face][i]); + + if (image == NULL) + break; + + image->mtlevel = i; + image->mtface = face; + + radeon_miptree_unreference(image->mt); + image->mt = NULL; + } + } + +} + +void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) +{ + GLuint face = radeon_face_for_target(target); + radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); + + radeon_teximage_map(baseimage, GL_FALSE); + radeon_generate_mipmap(ctx, target, texObj); + radeon_teximage_unmap(baseimage); +} + + +/* try to find a format which will only need a memcopy */ +static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, + GLenum srcFormat, + GLenum srcType) +{ + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *)&ui); + + /* r100 can only do this */ + if (IS_R100_CLASS(rmesa->radeonScreen)) + return _dri_texformat_argb8888; + + if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { + return &_mesa_texformat_rgba8888; + } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { + return &_mesa_texformat_rgba8888_rev; + } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8)) { + return &_mesa_texformat_argb8888_rev; + } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { + return &_mesa_texformat_argb8888; + } else + return _dri_texformat_argb8888; +} + +const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + const GLboolean do32bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); + const GLboolean force16bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); + (void)format; + +#if 0 + fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", + _mesa_lookup_enum_by_nr(internalFormat), internalFormat, + _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); + fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); +#endif + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + switch (type) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? _dri_texformat_argb8888 : + _dri_texformat_argb1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _dri_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _dri_texformat_argb1555; + default: + return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) : + _dri_texformat_argb4444; + } + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _dri_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _dri_texformat_argb1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return _dri_texformat_rgb565; + default: + return do32bpt ? _dri_texformat_argb8888 : + _dri_texformat_rgb565; + } + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return !force16bpt ? + radeonChoose8888TexFormat(rmesa, format,type) : + _dri_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return _dri_texformat_argb4444; + + case GL_RGB5_A1: + return _dri_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return !force16bpt ? _dri_texformat_argb8888 : + _dri_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return _dri_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return _dri_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return _dri_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return _dri_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return _dri_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + case GL_ALPHA16F_ARB: + return &_mesa_texformat_alpha_float16; + case GL_ALPHA32F_ARB: + return &_mesa_texformat_alpha_float32; + case GL_LUMINANCE16F_ARB: + return &_mesa_texformat_luminance_float16; + case GL_LUMINANCE32F_ARB: + return &_mesa_texformat_luminance_float32; + case GL_LUMINANCE_ALPHA16F_ARB: + return &_mesa_texformat_luminance_alpha_float16; + case GL_LUMINANCE_ALPHA32F_ARB: + return &_mesa_texformat_luminance_alpha_float32; + case GL_INTENSITY16F_ARB: + return &_mesa_texformat_intensity_float16; + case GL_INTENSITY32F_ARB: + return &_mesa_texformat_intensity_float32; + case GL_RGB16F_ARB: + return &_mesa_texformat_rgba_float16; + case GL_RGB32F_ARB: + return &_mesa_texformat_rgba_float32; + case GL_RGBA16F_ARB: + return &_mesa_texformat_rgba_float16; + case GL_RGBA32F_ARB: + return &_mesa_texformat_rgba_float32; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: +#if 0 + switch (type) { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + return &_mesa_texformat_z16; + case GL_UNSIGNED_INT: + return &_mesa_texformat_z32; + case GL_UNSIGNED_INT_24_8_EXT: + default: + return &_mesa_texformat_z24_s8; + } +#else + return &_mesa_texformat_z16; +#endif + + default: + _mesa_problem(ctx, + "unexpected internalFormat 0x%x in r300ChooseTextureFormat", + (int)internalFormat); + return NULL; + } + + return NULL; /* never get here */ +} + +/** + * All glTexImage calls go through this function. + */ +static void radeon_teximage( + GLcontext *ctx, int dims, + GLint face, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLsizei imageSize, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + int compressed) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj* t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + radeon_firevertices(rmesa); + + t->validated = GL_FALSE; + + /* Choose and fill in the texture format for this image */ + texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type); + _mesa_set_fetch_functions(texImage, dims); + + if (texImage->TexFormat->TexelBytes == 0) { + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } else { + texImage->IsCompressed = GL_FALSE; + texImage->CompressedSize = 0; + } + + /* Allocate memory for image */ + radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ + + if (!t->mt) + radeon_try_alloc_miptree(rmesa, t, texImage, face, level); + if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { + image->mt = t->mt; + image->mtlevel = level - t->mt->firstLevel; + image->mtface = face; + radeon_miptree_reference(t->mt); + } else { + int size; + if (texImage->IsCompressed) { + size = texImage->CompressedSize; + } else { + size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; + } + texImage->Data = _mesa_alloc_texmemory(size); + } + + /* Upload texture image; note that the spec allows pixels to be NULL */ + if (compressed) { + pixels = _mesa_validate_pbo_compressed_teximage( + ctx, imageSize, pixels, packing, "glCompressedTexImage"); + } else { + pixels = _mesa_validate_pbo_teximage( + ctx, dims, width, height, depth, + format, type, pixels, packing, "glTexImage"); + } + + if (pixels) { + radeon_teximage_map(image, GL_TRUE); + + if (compressed) { + memcpy(texImage->Data, pixels, imageSize); + } else { + GLuint dstRowStride; + if (image->mt) { + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + dstRowStride = lvl->rowstride; + } else { + dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; + } + if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + } + + /* SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + radeon_generate_mipmap(ctx, texObj->Target, texObj); + } + + if (pixels) + radeon_teximage_unmap(image); + + _mesa_unmap_teximage_pbo(ctx, packing); + + +} + +void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) + +{ + GLuint face = radeon_face_for_target(target); + + radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLuint face = radeon_face_for_target(target); + + radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + imageSize, 0, 0, data, 0, texObj, texImage, 1); +} + +void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +/** + * Update a subregion of the given texture image. + */ +static void radeon_texsubimage(GLcontext* ctx, int dims, int level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + int compressed) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj* t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + radeon_firevertices(rmesa); + + t->validated = GL_FALSE; + pixels = _mesa_validate_pbo_teximage(ctx, dims, + width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); + + if (pixels) { + GLint dstRowStride; + radeon_teximage_map(image, GL_TRUE); + + if (image->mt) { + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + dstRowStride = lvl->rowstride; + } else { + dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; + } + + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); + + + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + radeon_generate_mipmap(ctx, texObj->Target, texObj); + } + radeon_teximage_unmap(image); + + _mesa_unmap_teximage_pbo(ctx, packing); + + +} + +void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, + format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, + 1, format, type, pixels, packing, texObj, texImage, + 0); +} + +void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + format, 0, data, 0, texObj, texImage, 1); +} + + +void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels, packing, texObj, texImage, 0); +} + +static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, + GLuint numrows, GLuint rowsize) +{ + assert(rowsize <= dststride); + assert(rowsize <= srcstride); + + if (rowsize == srcstride && rowsize == dststride) { + memcpy(dst, src, numrows*rowsize); + } else { + GLuint i; + for(i = 0; i < numrows; ++i) { + memcpy(dst, src, rowsize); + dst += dststride; + src += srcstride; + } + } +} + + +/** + * Ensure that the given image is stored in the given miptree from now on. + */ +static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) +{ + radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; + unsigned char *dest; + + assert(image->mt != mt); + assert(dstlvl->width == image->base.Width); + assert(dstlvl->height == image->base.Height); + assert(dstlvl->depth == image->base.Depth); + + + radeon_bo_map(mt->bo, GL_TRUE); + dest = mt->bo->ptr + dstlvl->faces[face].offset; + + if (image->mt) { + /* Format etc. should match, so we really just need a memcpy(). + * In fact, that memcpy() could be done by the hardware in many + * cases, provided that we have a proper memory manager. + */ + radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + + assert(srclvl->size == dstlvl->size); + assert(srclvl->rowstride == dstlvl->rowstride); + + radeon_bo_map(image->mt->bo, GL_FALSE); + + memcpy(dest, + image->mt->bo->ptr + srclvl->faces[face].offset, + dstlvl->size); + radeon_bo_unmap(image->mt->bo); + + radeon_miptree_unreference(image->mt); + } else { + uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; + +// if (mt->tilebits) +// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); + + copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, + image->base.Height * image->base.Depth, srcrowstride); + + _mesa_free_texmemory(image->base.Data); + image->base.Data = 0; + } + + radeon_bo_unmap(mt->bo); + + image->mt = mt; + image->mtface = face; + image->mtlevel = level; + radeon_miptree_reference(image->mt); +} + +int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); + int face, level; + + if (t->validated || t->image_override) + return GL_TRUE; + + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); + + if (baseimage->base.Border > 0) + return GL_FALSE; + + /* Ensure a matching miptree exists. + * + * Differing mipmap trees can result when the app uses TexImage to + * change texture dimensions. + * + * Prefer to use base image's miptree if it + * exists, since that most likely contains more valid data (remember + * that the base level is usually significantly larger than the rest + * of the miptree, so cubemaps are the only possible exception). + */ + if (baseimage->mt && + baseimage->mt != t->mt && + radeon_miptree_matches_texture(baseimage->mt, &t->base)) { + radeon_miptree_unreference(t->mt); + t->mt = baseimage->mt; + radeon_miptree_reference(t->mt); + } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { + radeon_miptree_unreference(t->mt); + t->mt = 0; + } + + if (!t->mt) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, " Allocate new miptree\n"); + radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); + if (!t->mt) { + _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); + return GL_FALSE; + } + } + + /* Ensure all images are stored in the single main miptree */ + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { + radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); + if (t->mt == image->mt) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "OK\n"); + continue; + } + + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "migrating\n"); + migrate_image_to_miptree(t->mt, image, face, level); + } + } + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h new file mode 100644 index 0000000000..ff0e1d061e --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_TEXTURE_H +#define RADEON_TEXTURE_H +struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); +void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); + +void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); +void radeon_teximage_unmap(radeon_texture_image *image); +void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); +void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); +void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); +int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); +GLuint radeon_face_for_target(GLenum target); +const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type); + +void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +#endif -- cgit v1.2.3 From dc8a707c672918b88dd4135930bef60ed148d8ce Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Feb 2009 23:52:51 +1000 Subject: radeon/r200/r300: make build with out libdrm_radeon installed for now --- src/mesa/drivers/dri/r200/Makefile | 2 +- src/mesa/drivers/dri/r200/r200_ioctl.h | 2 +- src/mesa/drivers/dri/r200/r200_state.c | 3 +- src/mesa/drivers/dri/r200/r200_swtcl.c | 1 - src/mesa/drivers/dri/r300/Makefile | 2 +- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 4 +- src/mesa/drivers/dri/r300/r300_cmdbuf.h | 1 - src/mesa/drivers/dri/r300/r300_context.c | 2 +- src/mesa/drivers/dri/r300/r300_context.h | 1 - src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_texstate.c | 2 - src/mesa/drivers/dri/radeon/radeon_bo_drm.h | 179 +++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 4 +- src/mesa/drivers/dri/radeon/radeon_bo_legacy.h | 1 - src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h | 35 ++++ src/mesa/drivers/dri/radeon/radeon_buffer.h | 49 ----- src/mesa/drivers/dri/radeon/radeon_cmdbuf.h | 2 +- src/mesa/drivers/dri/radeon/radeon_common.c | 8 +- src/mesa/drivers/dri/radeon/radeon_common.h | 1 - .../drivers/dri/radeon/radeon_common_context.h | 16 ++ src/mesa/drivers/dri/radeon/radeon_cs_drm.h | 198 +++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 5 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 1 - src/mesa/drivers/dri/radeon/radeon_ioctl.c | 1 - src/mesa/drivers/dri/radeon/radeon_ioctl.h | 2 +- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c | 2 - src/mesa/drivers/dri/radeon/radeon_screen.c | 5 +- src/mesa/drivers/dri/radeon/radeon_screen.h | 1 - src/mesa/drivers/dri/radeon/radeon_span.c | 2 - src/mesa/drivers/dri/radeon/radeon_span.h | 2 - src/mesa/drivers/dri/radeon/radeon_state_init.c | 1 - 31 files changed, 442 insertions(+), 94 deletions(-) create mode 100644 src/mesa/drivers/dri/radeon/radeon_bo_drm.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h delete mode 100644 src/mesa/drivers/dri/radeon/radeon_buffer.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_cs_drm.h (limited to 'src/mesa/drivers/dri/radeon/radeon_cs_legacy.h') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 4f626c0584..7b5fe95577 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -62,9 +62,9 @@ COMMON_SYMLINKS = \ radeon_cs_legacy.c \ radeon_bo_legacy.h \ radeon_cs_legacy.h \ + radeon_bocs_wrapper.h \ radeon_span.h \ radeon_span.c \ - radeon_buffer.h \ radeon_lock.c \ radeon_lock.h \ radeon_common.c \ diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index 777fdc38a5..950478e762 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "radeon_dri.h" -#include "radeon_cs_legacy.h" +#include "radeon_bocs_wrapper.h" #include "xf86drm.h" #include "drm.h" diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 84b0d90c69..559985bc3f 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -47,8 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" -#include "radeon_buffer.h" -#include "radeon_cs.h" +#include "radeon_common.h" #include "radeon_mipmap_tree.h" #include "r200_context.h" #include "r200_ioctl.h" diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index df786561e1..b006409987 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -48,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "radeon_bo.h" #include "r200_context.h" #include "r200_ioctl.h" #include "r200_state.h" diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index e9264ce77a..20ee195fe7 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -75,11 +75,11 @@ COMMON_SYMLINKS = \ radeon_screen.h \ radeon_span.h \ radeon_span.c \ - radeon_buffer.h \ radeon_bo_legacy.c \ radeon_cs_legacy.c \ radeon_bo_legacy.h \ radeon_cs_legacy.h \ + radeon_bocs_wrapper.h \ radeon_lock.c \ radeon_lock.h \ radeon_common.c \ diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index d6acb39d9f..29b2c2eb25 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -44,17 +44,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drm.h" #include "radeon_drm.h" -#include "radeon_buffer.h" #include "r300_context.h" #include "r300_ioctl.h" #include "radeon_reg.h" #include "r300_reg.h" #include "r300_cmdbuf.h" #include "r300_emit.h" +#include "radeon_bocs_wrapper.h" #include "radeon_mipmap_tree.h" #include "r300_state.h" -#include "radeon_cs_legacy.h" -#include "radeon_cs_gem.h" #include "radeon_reg.h" #define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index ab5d50f58e..b7798eb97b 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -37,7 +37,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define __R300_CMDBUF_H__ #include "r300_context.h" -#include "radeon_cs.h" extern void r300InitCmdBuf(r300ContextPtr r300); extern void r300DestroyCmdBuf(r300ContextPtr r300); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index e4dc37debc..449252a930 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -63,7 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_tex.h" #include "r300_emit.h" #include "r300_swtcl.h" -#include "radeon_bo_legacy.h" +#include "radeon_bocs_wrapper.h" #include "vblank.h" diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 0be3657249..6d3472722d 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -43,7 +43,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri_util.h" #include "texmem.h" #include "radeon_common.h" -#include "radeon_bo.h" #include "main/macros.h" #include "main/mtypes.h" diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 4258a61000..fe58ac00a8 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vbo/vbo.h" #include "tnl/tnl.h" -#include "radeon_buffer.h" #include "r300_context.h" #include "r300_ioctl.h" #include "r300_state.h" diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 50ecc570bd..e5afff0d61 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -48,10 +48,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_ioctl.h" #include "radeon_mipmap_tree.h" -#include "radeon_cs.h" #include "r300_tex.h" #include "r300_reg.h" -#include "radeon_buffer.h" #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \ || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \ diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h new file mode 100644 index 0000000000..3cabdfc4e8 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h @@ -0,0 +1,179 @@ +/* + * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse + */ +#ifndef RADEON_BO_H +#define RADEON_BO_H + +#include +#include +#include "radeon_track.h" + +/* bo object */ +#define RADEON_BO_FLAGS_MACRO_TILE 1 +#define RADEON_BO_FLAGS_MICRO_TILE 2 + +struct radeon_bo_manager; + +struct radeon_bo { + uint32_t alignment; + uint32_t handle; + uint32_t size; + uint32_t domains; + uint32_t flags; + unsigned cref; +#ifdef RADEON_BO_TRACK + struct radeon_track *track; +#endif + void *ptr; + struct radeon_bo_manager *bom; + uint32_t space_accounted; +}; + +/* bo functions */ +struct radeon_bo_funcs { + struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom, + uint32_t handle, + uint32_t size, + uint32_t alignment, + uint32_t domains, + uint32_t flags); + void (*bo_ref)(struct radeon_bo *bo); + struct radeon_bo *(*bo_unref)(struct radeon_bo *bo); + int (*bo_map)(struct radeon_bo *bo, int write); + int (*bo_unmap)(struct radeon_bo *bo); + int (*bo_wait)(struct radeon_bo *bo); +}; + +struct radeon_bo_manager { + struct radeon_bo_funcs *funcs; + int fd; + struct radeon_tracker tracker; +}; + +static inline void _radeon_bo_debug(struct radeon_bo *bo, + const char *op, + const char *file, + const char *func, + int line) +{ + fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", + op, bo, bo->handle, bo->size, bo->cref, file, func, line); +} + +static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, + uint32_t handle, + uint32_t size, + uint32_t alignment, + uint32_t domains, + uint32_t flags, + const char *file, + const char *func, + int line) +{ + struct radeon_bo *bo; + + bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); +#ifdef RADEON_BO_TRACK + if (bo) { + bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle); + radeon_track_add_event(bo->track, file, func, "open", line); + } +#endif + return bo; +} + +static inline void _radeon_bo_ref(struct radeon_bo *bo, + const char *file, + const char *func, + int line) +{ + bo->cref++; +#ifdef RADEON_BO_TRACK + radeon_track_add_event(bo->track, file, func, "ref", line); +#endif + bo->bom->funcs->bo_ref(bo); +} + +static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo, + const char *file, + const char *func, + int line) +{ + bo->cref--; +#ifdef RADEON_BO_TRACK + radeon_track_add_event(bo->track, file, func, "unref", line); + if (bo->cref <= 0) { + radeon_tracker_remove_track(&bo->bom->tracker, bo->track); + bo->track = NULL; + } +#endif + return bo->bom->funcs->bo_unref(bo); +} + +static inline int _radeon_bo_map(struct radeon_bo *bo, + int write, + const char *file, + const char *func, + int line) +{ + return bo->bom->funcs->bo_map(bo, write); +} + +static inline int _radeon_bo_unmap(struct radeon_bo *bo, + const char *file, + const char *func, + int line) +{ + return bo->bom->funcs->bo_unmap(bo); +} + +static inline int _radeon_bo_wait(struct radeon_bo *bo, + const char *file, + const char *func, + int line) +{ + return bo->bom->funcs->bo_wait(bo); +} + +#define radeon_bo_open(bom, h, s, a, d, f)\ + _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_ref(bo)\ + _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_unref(bo)\ + _radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_map(bo, w)\ + _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_unmap(bo)\ + _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_debug(bo, opcode)\ + _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_wait(bo) \ + _radeon_bo_wait(bo, __FILE__, __func__, __LINE__) + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index b7658353af..1d25887e69 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -45,9 +45,9 @@ #include "drm.h" #include "radeon_drm.h" -#include "radeon_bo.h" -#include "radeon_bo_legacy.h" #include "radeon_common.h" +#include "radeon_bocs_wrapper.h" + struct bo_legacy { struct radeon_bo base; diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h index 575979cbec..9187cd7201 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h @@ -32,7 +32,6 @@ #ifndef RADEON_BO_LEGACY_H #define RADEON_BO_LEGACY_H -#include "radeon_bo.h" #include "radeon_screen.h" void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending); diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h new file mode 100644 index 0000000000..36dea3be7b --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h @@ -0,0 +1,35 @@ +#ifndef RADEON_CS_WRAPPER_H +#define RADEON_CS_WRAPPER_H + +#ifdef HAVE_LIBDRM_RADEON + +#include "radeon_bo.h" +#include "radeon_bo_gem.h" +#include "radeon_cs.h" +#include "radeon_cs_gem.h" + +#else +/* to be used to build locally in mesa with no libdrm bits */ +#include "../radeon/radeon_bo_drm.h" +#include "../radeon/radeon_cs_drm.h" + +#define RADEON_GEM_DOMAIN_CPU 0x1 // Cached CPU domain +#define RADEON_GEM_DOMAIN_GTT 0x2 // GTT or cache flushed +#define RADEON_GEM_DOMAIN_VRAM 0x4 // VRAM domain + +static inline void *radeon_bo_manager_gem_ctor(int fd) +{ + return NULL; +} + +static inline void radeon_bo_manager_gem_dtor(void *dummy) +{ +} + + +#endif + +#include "radeon_bo_legacy.h" +#include "radeon_cs_legacy.h" + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer.h b/src/mesa/drivers/dri/radeon/radeon_buffer.h deleted file mode 100644 index 62cdfad4a0..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_buffer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software") - * to deal in the software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * them Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Adam Jackson - */ - -#ifndef RADEON_BUFFER_H -#define RADEON_BUFFER_H - -#include "radeon_bo.h" -#include "dri_util.h" - -struct radeon_renderbuffer -{ - struct gl_renderbuffer base; - struct radeon_bo *bo; - unsigned int cpp; - /* unsigned int offset; */ - unsigned int pitch; - unsigned int width; - unsigned int height; - - /* boo Xorg 6.8.2 compat */ - int has_surface; - - - __DRIdrawablePrivate *dPriv; -}; - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h index 5526934209..4b5116c474 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h +++ b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h @@ -1,7 +1,7 @@ #ifndef COMMON_CMDBUF_H #define COMMON_CMDBUF_H -#include "radeon_cs.h" +#include "radeon_bocs_wrapper.h" void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 87b6dac40b..80e8e0d86d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -63,13 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vblank.h" #include "radeon_common.h" -#include "radeon_common.h" -#include "radeon_bo.h" -#include "radeon_cs.h" -#include "radeon_bo_legacy.h" -#include "radeon_cs_legacy.h" -#include "radeon_bo_gem.h" -#include "radeon_cs_gem.h" +#include "radeon_bocs_wrapper.h" #include "radeon_drm.h" #include "radeon_mipmap_tree.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index cc9d579ea1..ead0f5551b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -2,7 +2,6 @@ #define COMMON_MISC_H #include "radeon_common_context.h" -#include "radeon_buffer.h" #include "radeon_dma.h" #include "radeon_texture.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index b88aeab051..c9be104578 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -68,6 +68,22 @@ typedef struct radeon_context *radeonContextPtr; #include "tnl_dd/t_dd_vertex.h" #undef TAG +struct radeon_renderbuffer +{ + struct gl_renderbuffer base; + struct radeon_bo *bo; + unsigned int cpp; + /* unsigned int offset; */ + unsigned int pitch; + unsigned int width; + unsigned int height; + + /* boo Xorg 6.8.2 compat */ + int has_surface; + + __DRIdrawablePrivate *dPriv; +}; + struct radeon_colorbuffer_state { GLuint clear; int roundEnable; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h new file mode 100644 index 0000000000..7cc75d4700 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h @@ -0,0 +1,198 @@ +/* + * Copyright © 2008 Nicolai Haehnle + * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Aapo Tahkola + * Nicolai Haehnle + * Jérôme Glisse + */ +#ifndef RADEON_CS_H +#define RADEON_CS_H + +#include +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_bo.h" + +struct radeon_cs_reloc { + struct radeon_bo *bo; + uint32_t read_domain; + uint32_t write_domain; + uint32_t flags; +}; + + +#define RADEON_CS_SPACE_OK 0 +#define RADEON_CS_SPACE_OP_TO_BIG 1 +#define RADEON_CS_SPACE_FLUSH 2 + +struct radeon_cs_space_check { + struct radeon_bo *bo; + uint32_t read_domains; + uint32_t write_domain; + uint32_t new_accounted; +}; + +struct radeon_cs_manager; + +struct radeon_cs { + struct radeon_cs_manager *csm; + void *relocs; + uint32_t *packets; + unsigned crelocs; + unsigned relocs_total_size; + unsigned cdw; + unsigned ndw; + int section; + unsigned section_ndw; + unsigned section_cdw; + const char *section_file; + const char *section_func; + int section_line; + +}; + +/* cs functions */ +struct radeon_cs_funcs { + struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm, + uint32_t ndw); + int (*cs_write_reloc)(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domain, + uint32_t write_domain, + uint32_t flags); + int (*cs_begin)(struct radeon_cs *cs, + uint32_t ndw, + const char *file, + const char *func, + int line); + int (*cs_end)(struct radeon_cs *cs, + const char *file, + const char *func, + int line); + int (*cs_emit)(struct radeon_cs *cs); + int (*cs_destroy)(struct radeon_cs *cs); + int (*cs_erase)(struct radeon_cs *cs); + int (*cs_need_flush)(struct radeon_cs *cs); + void (*cs_print)(struct radeon_cs *cs, FILE *file); + int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos, + int num_bo); +}; + +struct radeon_cs_manager { + struct radeon_cs_funcs *funcs; + int fd; + uint32_t vram_limit, gart_limit; + uint32_t vram_write_used, gart_write_used; + uint32_t read_used; +}; + +static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, + uint32_t ndw) +{ + return csm->funcs->cs_create(csm, ndw); +} + +static inline int radeon_cs_write_reloc(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domain, + uint32_t write_domain, + uint32_t flags) +{ + return cs->csm->funcs->cs_write_reloc(cs, + bo, + read_domain, + write_domain, + flags); +} + +static inline int radeon_cs_begin(struct radeon_cs *cs, + uint32_t ndw, + const char *file, + const char *func, + int line) +{ + return cs->csm->funcs->cs_begin(cs, ndw, file, func, line); +} + +static inline int radeon_cs_end(struct radeon_cs *cs, + const char *file, + const char *func, + int line) +{ + return cs->csm->funcs->cs_end(cs, file, func, line); +} + +static inline int radeon_cs_emit(struct radeon_cs *cs) +{ + return cs->csm->funcs->cs_emit(cs); +} + +static inline int radeon_cs_destroy(struct radeon_cs *cs) +{ + return cs->csm->funcs->cs_destroy(cs); +} + +static inline int radeon_cs_erase(struct radeon_cs *cs) +{ + return cs->csm->funcs->cs_erase(cs); +} + +static inline int radeon_cs_need_flush(struct radeon_cs *cs) +{ + return cs->csm->funcs->cs_need_flush(cs); +} + +static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) +{ + cs->csm->funcs->cs_print(cs, file); +} + +static inline int radeon_cs_space_check(struct radeon_cs *cs, + struct radeon_cs_space_check *bos, + int num_bo) +{ + return cs->csm->funcs->cs_space_check(cs, bos, num_bo); +} + +static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) +{ + + if (domain == RADEON_GEM_DOMAIN_VRAM) + cs->csm->vram_limit = limit; + else + cs->csm->gart_limit = limit; +} + +static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword) +{ + cs->packets[cs->cdw++] = dword; + if (cs->section) { + cs->section_cdw++; + } +} + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index 2db3f7a68d..0f73dec1e5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -31,10 +31,7 @@ */ #include -#include "radeon_cs.h" -#include "radeon_cs_legacy.h" -#include "radeon_bo_legacy.h" - +#include "radeon_bocs_wrapper.h" struct cs_manager_legacy { struct radeon_cs_manager base; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index 19d904174f..e177b4bafe 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -32,7 +32,6 @@ #ifndef RADEON_CS_LEGACY_H #define RADEON_CS_LEGACY_H -#include "radeon_cs.h" #include "radeon_common.h" struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 99b1ef332f..fb3a236d7c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -44,7 +44,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_common.h" -#include "radeon_cs.h" #include "radeon_state.h" #include "radeon_ioctl.h" #include "radeon_tcl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h index 6d616bf804..18805d4c57 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "radeon_lock.h" -#include "radeon_cs_legacy.h" +#include "radeon_bocs_wrapper.h" extern void radeonEmitVertexAOS( r100ContextPtr rmesa, GLuint vertex_size, diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 323726c574..c21d297b22 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -34,8 +34,6 @@ #include "main/texcompress.h" #include "main/texformat.h" -#include "radeon_buffer.h" - static GLuint radeon_compressed_texture_size(GLcontext *ctx, GLsizei width, GLsizei height, GLsizei depth, GLuint mesaFormat) diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 7f0d526ed2..e8cc3b25a8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_chipset.h" #include "radeon_macros.h" #include "radeon_screen.h" -#include "radeon_buffer.h" #include "radeon_common.h" #include "radeon_span.h" #if !RADEON_COMMON @@ -66,13 +65,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vblank.h" #include "drirenderbuffer.h" +#include "radeon_bocs_wrapper.h" + #include "GL/internal/dri_interface.h" /* Radeon configuration */ #include "xmlpool.h" -#include "radeon_bo_legacy.h" -#include "radeon_bo_gem.h" #define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \ DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \ diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 3287e125f4..1c0f5bb9bc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_reg.h" #include "drm_sarea.h" #include "xmlconfig.h" -#include "radeon_bo.h" typedef struct { diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index ebd18a1634..49ec2c378e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -47,8 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_lock.h" #include "radeon_span.h" -#include "radeon_buffer.h" - #define DBG 0 static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, diff --git a/src/mesa/drivers/dri/radeon/radeon_span.h b/src/mesa/drivers/dri/radeon/radeon_span.h index dda542c8d1..dd44ab517a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.h +++ b/src/mesa/drivers/dri/radeon/radeon_span.h @@ -42,8 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_SPAN_H__ #define __RADEON_SPAN_H__ -#include "radeon_buffer.h" - extern void radeonInitSpanFuncs(GLcontext * ctx); extern void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index a397c0824f..fc42318017 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -38,7 +38,6 @@ #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" -#include "radeon_cs.h" #include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" #include "radeon_state.h" -- cgit v1.2.3