mirror of
https://src.fedoraproject.org/rpms/mesa.git
synced 2024-11-28 11:06:25 +00:00
10618 lines
343 KiB
Diff
10618 lines
343 KiB
Diff
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
|
|
index e9144ac..7064f42 100644
|
|
--- a/src/mesa/drivers/dri/r200/Makefile
|
|
+++ b/src/mesa/drivers/dri/r200/Makefile
|
|
@@ -48,7 +48,9 @@ SYMLINKS = \
|
|
COMMON_SYMLINKS = \
|
|
radeon_chipset.h \
|
|
radeon_screen.c \
|
|
- radeon_screen.h
|
|
+ radeon_screen.h \
|
|
+ radeon_bo_legacy.h \
|
|
+ radeon_buffer.h
|
|
|
|
##### TARGETS #####
|
|
|
|
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
|
|
index 6ca9342..cbb09e6 100644
|
|
--- a/src/mesa/drivers/dri/r300/Makefile
|
|
+++ b/src/mesa/drivers/dri/r300/Makefile
|
|
@@ -21,13 +21,14 @@ COMMON_SOURCES = \
|
|
../common/dri_util.c
|
|
|
|
DRIVER_SOURCES = \
|
|
+ radeon_bo_legacy.c \
|
|
+ radeon_cs_legacy.c \
|
|
radeon_screen.c \
|
|
radeon_context.c \
|
|
radeon_ioctl.c \
|
|
radeon_lock.c \
|
|
radeon_span.c \
|
|
radeon_state.c \
|
|
- r300_mem.c \
|
|
r300_context.c \
|
|
r300_ioctl.c \
|
|
r300_cmdbuf.c \
|
|
@@ -36,6 +37,7 @@ DRIVER_SOURCES = \
|
|
r300_texmem.c \
|
|
r300_tex.c \
|
|
r300_texstate.c \
|
|
+ r300_mipmap_tree.c \
|
|
radeon_program.c \
|
|
radeon_program_alu.c \
|
|
radeon_program_pair.c \
|
|
@@ -54,7 +56,9 @@ DRIVER_SOURCES = \
|
|
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
|
|
|
|
DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \
|
|
- -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300
|
|
+ -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \
|
|
+# -DRADEON_BO_TRACK \
|
|
+ -Wall
|
|
|
|
SYMLINKS = \
|
|
server/radeon_dri.c \
|
|
@@ -68,7 +72,14 @@ COMMON_SYMLINKS = \
|
|
radeon_chipset.h \
|
|
radeon_screen.c \
|
|
radeon_screen.h \
|
|
- radeon_span.h
|
|
+ radeon_span.h \
|
|
+ radeon_buffer.h \
|
|
+ radeon_bo_legacy.c \
|
|
+ radeon_cs_legacy.c \
|
|
+ radeon_bo_legacy.h \
|
|
+ radeon_cs_legacy.h
|
|
+
|
|
+DRI_LIB_DEPS += -ldrm_radeon
|
|
|
|
##### TARGETS #####
|
|
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
|
|
index c9e1dfe..4eac518 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
|
|
@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "drm.h"
|
|
#include "radeon_drm.h"
|
|
|
|
+#include "radeon_buffer.h"
|
|
#include "radeon_ioctl.h"
|
|
#include "r300_context.h"
|
|
#include "r300_ioctl.h"
|
|
@@ -51,62 +52,41 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_reg.h"
|
|
#include "r300_cmdbuf.h"
|
|
#include "r300_emit.h"
|
|
+#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
|
|
|
|
+/** # of dwords reserved for additional instructions that may need to be written
|
|
+ * during flushing.
|
|
+ */
|
|
+#define SPACE_FOR_FLUSHING 4
|
|
+
|
|
/**
|
|
* Send the current command buffer via ioctl to the hardware.
|
|
*/
|
|
int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller)
|
|
{
|
|
- int ret;
|
|
- int i;
|
|
- drm_radeon_cmd_buffer_t cmd;
|
|
- int start;
|
|
-
|
|
- if (r300->radeon.lost_context) {
|
|
- start = 0;
|
|
- r300->radeon.lost_context = GL_FALSE;
|
|
- } else
|
|
- start = r300->cmdbuf.count_reemit;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL) {
|
|
- fprintf(stderr, "%s from %s - %i cliprects\n",
|
|
- __FUNCTION__, caller, r300->radeon.numClipRects);
|
|
-
|
|
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE)
|
|
- for (i = start; i < r300->cmdbuf.count_used; ++i)
|
|
- fprintf(stderr, "%d: %08x\n", i,
|
|
- r300->cmdbuf.cmd_buf[i]);
|
|
- }
|
|
-
|
|
- cmd.buf = (char *)(r300->cmdbuf.cmd_buf + start);
|
|
- cmd.bufsz = (r300->cmdbuf.count_used - start) * 4;
|
|
-
|
|
- if (r300->radeon.state.scissor.enabled) {
|
|
- cmd.nbox = r300->radeon.state.scissor.numClipRects;
|
|
- cmd.boxes =
|
|
- (drm_clip_rect_t *) r300->radeon.state.scissor.pClipRects;
|
|
- } else {
|
|
- cmd.nbox = r300->radeon.numClipRects;
|
|
- cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects;
|
|
- }
|
|
-
|
|
- ret = drmCommandWrite(r300->radeon.dri.fd,
|
|
- DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
|
|
+ int ret = 0;
|
|
|
|
- if (RADEON_DEBUG & DEBUG_SYNC) {
|
|
- fprintf(stderr, "Syncing in %s (from %s)\n\n",
|
|
- __FUNCTION__, caller);
|
|
- radeonWaitForIdleLocked(&r300->radeon);
|
|
+ if (r300->cmdbuf.flushing) {
|
|
+ fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n");
|
|
+ exit(-1);
|
|
}
|
|
-
|
|
- r300->dma.nr_released_bufs = 0;
|
|
- r300->cmdbuf.count_used = 0;
|
|
- r300->cmdbuf.count_reemit = 0;
|
|
-
|
|
+ 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;
|
|
}
|
|
|
|
@@ -115,9 +95,7 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller)
|
|
int ret;
|
|
|
|
LOCK_HARDWARE(&r300->radeon);
|
|
-
|
|
ret = r300FlushCmdBufLocked(r300, caller);
|
|
-
|
|
UNLOCK_HARDWARE(&r300->radeon);
|
|
|
|
if (ret) {
|
|
@@ -128,13 +106,42 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char *caller)
|
|
return ret;
|
|
}
|
|
|
|
-static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *state)
|
|
+/**
|
|
+ * 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) {
|
|
+ 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);
|
|
+}
|
|
+
|
|
+static void r300PrintStateAtom(r300ContextPtr r300,
|
|
+ struct r300_state_atom *state)
|
|
{
|
|
int i;
|
|
int dwords = (*state->check) (r300, state);
|
|
|
|
- fprintf(stderr, " emit %s %d/%d\n", state->name, dwords,
|
|
- state->cmd_size);
|
|
+ fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
|
|
|
|
if (RADEON_DEBUG & DEBUG_VERBOSE) {
|
|
for (i = 0; i < dwords; i++) {
|
|
@@ -152,33 +159,18 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat
|
|
*/
|
|
static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
|
|
{
|
|
+ BATCH_LOCALS(r300);
|
|
struct r300_state_atom *atom;
|
|
- uint32_t *dest;
|
|
int dwords;
|
|
|
|
- dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used;
|
|
-
|
|
- /* Emit WAIT */
|
|
- *dest = cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN);
|
|
- dest++;
|
|
- r300->cmdbuf.count_used++;
|
|
-
|
|
- /* Emit cache flush */
|
|
- *dest = cmdpacket0(R300_TX_INVALTAGS, 1);
|
|
- dest++;
|
|
- r300->cmdbuf.count_used++;
|
|
-
|
|
- *dest = R300_TX_FLUSH;
|
|
- dest++;
|
|
- r300->cmdbuf.count_used++;
|
|
-
|
|
- /* Emit END3D */
|
|
- *dest = cmdpacify();
|
|
- dest++;
|
|
- r300->cmdbuf.count_used++;
|
|
+ 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);
|
|
+ END_BATCH();
|
|
+ end_3d(r300);
|
|
|
|
/* Emit actual atoms */
|
|
-
|
|
foreach(atom, &r300->hw.atomlist) {
|
|
if ((atom->dirty || r300->hw.all_dirty) == dirty) {
|
|
dwords = (*atom->check) (r300, atom);
|
|
@@ -186,9 +178,13 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
|
|
if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
|
|
r300PrintStateAtom(r300, atom);
|
|
}
|
|
- memcpy(dest, atom->cmd, dwords * 4);
|
|
- dest += dwords;
|
|
- r300->cmdbuf.count_used += dwords;
|
|
+ if (atom->emit) {
|
|
+ (*atom->emit)(r300, 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) {
|
|
@@ -198,6 +194,8 @@ static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
|
|
}
|
|
}
|
|
}
|
|
+
|
|
+ COMMIT_BATCH();
|
|
}
|
|
|
|
/**
|
|
@@ -211,39 +209,208 @@ void r300EmitState(r300ContextPtr r300)
|
|
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS))
|
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
|
|
- if (r300->cmdbuf.count_used && !r300->hw.is_dirty
|
|
- && !r300->hw.all_dirty)
|
|
+ if (r300->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, and inline the
|
|
- * r300AllocCmdBuf code here without all the checks.
|
|
+ * for enough space for the case of emitting all state.
|
|
*/
|
|
r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__);
|
|
|
|
- if (!r300->cmdbuf.count_used) {
|
|
+ if (!r300->cmdbuf.cs->cdw) {
|
|
if (RADEON_DEBUG & DEBUG_STATE)
|
|
fprintf(stderr, "Begin reemit state\n");
|
|
|
|
r300EmitAtoms(r300, GL_FALSE);
|
|
- r300->cmdbuf.count_reemit = r300->cmdbuf.count_used;
|
|
}
|
|
|
|
if (RADEON_DEBUG & DEBUG_STATE)
|
|
fprintf(stderr, "Begin dirty state\n");
|
|
|
|
r300EmitAtoms(r300, GL_TRUE);
|
|
-
|
|
- assert(r300->cmdbuf.count_used < r300->cmdbuf.size);
|
|
-
|
|
r300->hw.is_dirty = GL_FALSE;
|
|
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->kernel_mm) {
|
|
+ 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)
|
|
|
|
+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->kernel_mm) {
|
|
+ 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]);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void emit_r500fp(r300ContextPtr r300, struct r300_state_atom * atom)
|
|
+{
|
|
+ BATCH_LOCALS(r300);
|
|
+ drm_r300_cmd_header_t cmd;
|
|
+ uint32_t addr, ndw, i, sz;
|
|
+ int type, clamp, stride;
|
|
+
|
|
+ if (!r300->radeon.radeonScreen->kernel_mm) {
|
|
+ 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];
|
|
+ sz = cmd.r500fp.count;
|
|
+ addr = ((cmd.r500fp.adrhi_flags & 1) << 8) | cmd.r500fp.adrlo;
|
|
+ type = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
|
|
+ clamp = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
|
|
+
|
|
+ addr |= (type << 16);
|
|
+ addr |= (clamp << 17);
|
|
+
|
|
+ stride = type ? 4 : 6;
|
|
+
|
|
+ ndw = sz * stride;
|
|
+ if (ndw) {
|
|
+
|
|
+ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0));
|
|
+ OUT_BATCH(addr);
|
|
+ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_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, r300->hw.tex.offset.cmd);
|
|
+
|
|
+ if (numtmus) {
|
|
+ int i;
|
|
+
|
|
+ for(i = 0; i < numtmus; ++i) {
|
|
+ BEGIN_BATCH(2);
|
|
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
|
|
+ r300TexObj *t = r300->hw.textures[i];
|
|
+ if (t && !t->image_override) {
|
|
+ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
|
|
+ RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
|
+ } else if (!t) {
|
|
+ OUT_BATCH(r300->radeon.radeonScreen->texOffset[0]);
|
|
+ } else {
|
|
+ if (t->bo) {
|
|
+ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0,
|
|
+ RADEON_GEM_DOMAIN_VRAM, 0, 0);
|
|
+ } else {
|
|
+ OUT_BATCH(t->override_offset);
|
|
+ }
|
|
+ }
|
|
+ END_BATCH();
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+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 || !rrb->bo) {
|
|
+ fprintf(stderr, "no rrb\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ cbpitch = (rrb->pitch / rrb->cpp);
|
|
+ if (rrb->cpp == 4)
|
|
+ cbpitch |= R300_COLOR_FORMAT_ARGB8888;
|
|
+ else
|
|
+ cbpitch |= R300_COLOR_FORMAT_RGB565;
|
|
+
|
|
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
|
|
+ cbpitch |= R300_COLOR_TILE_ENABLE;
|
|
+
|
|
+ BEGIN_BATCH(4);
|
|
+ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
|
|
+ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1);
|
|
+ OUT_BATCH(cbpitch);
|
|
+ END_BATCH();
|
|
+}
|
|
+
|
|
+static void emit_zb_offset(r300ContextPtr r300, struct r300_state_atom * atom)
|
|
+{
|
|
+ BATCH_LOCALS(r300);
|
|
+ struct radeon_renderbuffer *rrb;
|
|
+ uint32_t zbpitch;
|
|
+
|
|
+ rrb = r300->radeon.state.depth_buffer;
|
|
+ if (!rrb)
|
|
+ return;
|
|
+
|
|
+ zbpitch = (rrb->pitch / rrb->cpp);
|
|
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
|
|
+ zbpitch |= R300_DEPTHMACROTILE_ENABLE;
|
|
+ }
|
|
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
|
|
+ zbpitch |= R300_DEPTHMICROTILE_TILED;
|
|
+ }
|
|
+
|
|
+ BEGIN_BATCH(4);
|
|
+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
|
|
+ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, zbpitch);
|
|
+ END_BATCH();
|
|
+}
|
|
+
|
|
static int check_always(r300ContextPtr r300, struct r300_state_atom *atom)
|
|
{
|
|
return atom->cmd_size;
|
|
@@ -252,27 +419,33 @@ 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;
|
|
}
|
|
|
|
-static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom)
|
|
+int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom)
|
|
{
|
|
int cnt;
|
|
+
|
|
cnt = r500fp_count(atom->cmd);
|
|
return cnt ? (cnt * 6) + 1 : 0;
|
|
}
|
|
|
|
-static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom)
|
|
+int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom)
|
|
{
|
|
int cnt;
|
|
+
|
|
cnt = r500fp_count(atom->cmd);
|
|
return cnt ? (cnt * 4) + 1 : 0;
|
|
}
|
|
@@ -318,92 +491,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) |
|
|
@@ -412,133 +585,146 @@ 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);
|
|
+ r300->hw.r500fp.emit = emit_r500fp;
|
|
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);
|
|
+ r300->hw.r500fp_const.emit = emit_r500fp;
|
|
} 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.cmd[R300_CB_CMD_0] = cmdpacket0(R300_RB3D_COLOROFFSET0, 1);
|
|
- r300->hw.cb.cmd[R300_CB_CMD_1] = cmdpacket0(R300_RB3D_COLORPITCH0, 1);
|
|
+ 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.cmd[R300_ZB_CMD_0] = cmdpacket0(R300_ZB_DEPTHOFFSET, 2);
|
|
+ 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);
|
|
+ ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
|
|
+ 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;
|
|
}
|
|
}
|
|
}
|
|
@@ -546,33 +732,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, mtu + 1, 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;
|
|
@@ -587,6 +774,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
|
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));
|
|
@@ -597,10 +785,19 @@ void r300InitCmdBuf(r300ContextPtr r300)
|
|
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;
|
|
- r300->cmdbuf.cmd_buf = (uint32_t *) CALLOC(size * 4);
|
|
- r300->cmdbuf.count_used = 0;
|
|
- r300->cmdbuf.count_reemit = 0;
|
|
}
|
|
|
|
/**
|
|
@@ -610,66 +807,13 @@ void r300DestroyCmdBuf(r300ContextPtr r300)
|
|
{
|
|
struct r300_state_atom *atom;
|
|
|
|
- FREE(r300->cmdbuf.cmd_buf);
|
|
-
|
|
+ radeon_cs_destroy(r300->cmdbuf.cs);
|
|
foreach(atom, &r300->hw.atomlist) {
|
|
FREE(atom->cmd);
|
|
}
|
|
-}
|
|
-
|
|
-void r300EmitBlit(r300ContextPtr rmesa,
|
|
- GLuint color_fmt,
|
|
- GLuint src_pitch,
|
|
- GLuint src_offset,
|
|
- GLuint dst_pitch,
|
|
- GLuint dst_offset,
|
|
- GLint srcx, GLint srcy,
|
|
- GLint dstx, GLint dsty, GLuint w, GLuint h)
|
|
-{
|
|
- drm_r300_cmd_header_t *cmd;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr,
|
|
- "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
|
|
- __FUNCTION__, src_pitch, src_offset, srcx, srcy,
|
|
- dst_pitch, dst_offset, dstx, dsty, w, h);
|
|
-
|
|
- assert((src_pitch & 63) == 0);
|
|
- assert((dst_pitch & 63) == 0);
|
|
- assert((src_offset & 1023) == 0);
|
|
- assert((dst_offset & 1023) == 0);
|
|
- assert(w < (1 << 16));
|
|
- assert(h < (1 << 16));
|
|
-
|
|
- cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 8, __FUNCTION__);
|
|
-
|
|
- cmd[0].header.cmd_type = R300_CMD_PACKET3;
|
|
- cmd[0].header.pad0 = R300_CMD_PACKET3_RAW;
|
|
- cmd[1].u = R300_CP_CMD_BITBLT_MULTI | (5 << 16);
|
|
- cmd[2].u = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
|
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
|
- RADEON_GMC_BRUSH_NONE |
|
|
- (color_fmt << 8) |
|
|
- RADEON_GMC_SRC_DATATYPE_COLOR |
|
|
- RADEON_ROP3_S |
|
|
- RADEON_DP_SRC_SOURCE_MEMORY |
|
|
- RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
|
|
-
|
|
- cmd[3].u = ((src_pitch / 64) << 22) | (src_offset >> 10);
|
|
- cmd[4].u = ((dst_pitch / 64) << 22) | (dst_offset >> 10);
|
|
- cmd[5].u = (srcx << 16) | srcy;
|
|
- cmd[6].u = (dstx << 16) | dsty; /* dst */
|
|
- cmd[7].u = (w << 16) | h;
|
|
-}
|
|
-
|
|
-void r300EmitWait(r300ContextPtr rmesa, GLuint flags)
|
|
-{
|
|
- drm_r300_cmd_header_t *cmd;
|
|
-
|
|
- assert(!(flags & ~(R300_WAIT_2D | R300_WAIT_3D)));
|
|
-
|
|
- cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
|
|
- cmd[0].u = 0;
|
|
- cmd[0].wait.cmd_type = R300_CMD_WAIT;
|
|
- cmd[0].wait.flags = flags;
|
|
+ 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);
|
|
+ }
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
|
|
index a8eaa58..bb7e0bf 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
|
|
@@ -37,6 +37,7 @@ 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 int r300FlushCmdBufLocked(r300ContextPtr r300, const char *caller);
|
|
extern int r300FlushCmdBuf(r300ContextPtr r300, const char *caller);
|
|
@@ -45,72 +46,92 @@ 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,
|
|
+ int dostate,
|
|
+ const char *file,
|
|
+ const char *function,
|
|
+ int line);
|
|
|
|
/**
|
|
- * 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
|
|
+ * Every function writing to the command buffer needs to declare this
|
|
+ * to get the necessary local variables.
|
|
*/
|
|
-static INLINE void r300EnsureCmdBufSpace(r300ContextPtr r300,
|
|
- int dwords, const char *caller)
|
|
-{
|
|
- assert(dwords < r300->cmdbuf.size);
|
|
+#define BATCH_LOCALS(r300) \
|
|
+ const r300ContextPtr b_l_r300 = r300
|
|
|
|
- if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size)
|
|
- r300FlushCmdBuf(r300, caller);
|
|
-}
|
|
+/**
|
|
+ * Prepare writing n dwords to the command buffer,
|
|
+ * including producing any necessary state emits on buffer wraparound.
|
|
+ */
|
|
+#define BEGIN_BATCH(n) r300BeginBatch(b_l_r300, n, 1, __FILE__, __FUNCTION__, __LINE__)
|
|
|
|
/**
|
|
- * Allocate the given number of dwords in the command buffer and return
|
|
- * a pointer to the allocated area.
|
|
- * When necessary, these functions cause a flush. r300AllocCmdBuf() also
|
|
- * causes state reemission after a flush. This is necessary to ensure
|
|
- * correct hardware state after an unlock.
|
|
+ * Same as BEGIN_BATCH, but do not cause automatic state emits.
|
|
*/
|
|
-static INLINE uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
|
|
- int dwords, const char *caller)
|
|
-{
|
|
- uint32_t *ptr;
|
|
-
|
|
- r300EnsureCmdBufSpace(r300, dwords, caller);
|
|
-
|
|
- ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
|
|
- r300->cmdbuf.count_used += dwords;
|
|
- return ptr;
|
|
-}
|
|
-
|
|
-static INLINE uint32_t *r300AllocCmdBuf(r300ContextPtr r300,
|
|
- int dwords, const char *caller)
|
|
-{
|
|
- uint32_t *ptr;
|
|
-
|
|
- r300EnsureCmdBufSpace(r300, dwords, caller);
|
|
-
|
|
- if (!r300->cmdbuf.count_used) {
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr,
|
|
- "Reemit state after flush (from %s)\n", caller);
|
|
- r300EmitState(r300);
|
|
- }
|
|
-
|
|
- ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
|
|
- r300->cmdbuf.count_used += dwords;
|
|
- return ptr;
|
|
-}
|
|
-
|
|
-extern void r300EmitBlit(r300ContextPtr rmesa,
|
|
- GLuint color_fmt,
|
|
- GLuint src_pitch,
|
|
- GLuint src_offset,
|
|
- GLuint dst_pitch,
|
|
- GLuint dst_offset,
|
|
- GLint srcx, GLint srcy,
|
|
- GLint dstx, GLint dsty, GLuint w, GLuint h);
|
|
-
|
|
-extern void r300EmitWait(r300ContextPtr rmesa, GLuint flags);
|
|
-extern void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start);
|
|
-extern void r300EmitVertexShader(r300ContextPtr rmesa);
|
|
-extern void r300EmitPixelShader(r300ContextPtr rmesa);
|
|
+#define BEGIN_BATCH_NO_AUTOSTATE(n) r300BeginBatch(b_l_r300, n, 0, __FILE__, __FUNCTION__, __LINE__)
|
|
+
|
|
+/**
|
|
+ * Write one dword to the command buffer.
|
|
+ */
|
|
+#define OUT_BATCH(data) \
|
|
+ do { \
|
|
+ radeon_cs_write_dword(b_l_r300->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 (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, \
|
|
+ rd, \
|
|
+ wd, \
|
|
+ flags);\
|
|
+ } 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_r300->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_r300->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)
|
|
+
|
|
+void emit_vpu(r300ContextPtr r300, struct r300_state_atom * atom);
|
|
+int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom);
|
|
+
|
|
+void emit_r500fp(r300ContextPtr r300, struct r300_state_atom * atom);
|
|
+int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom);
|
|
+int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom);
|
|
|
|
#endif /* __R300_CMDBUF_H__ */
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
|
|
index 3743627..5fce841 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_context.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_context.c
|
|
@@ -59,15 +59,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "radeon_span.h"
|
|
#include "r300_context.h"
|
|
#include "r300_cmdbuf.h"
|
|
+#include "r300_mipmap_tree.h"
|
|
#include "r300_state.h"
|
|
#include "r300_ioctl.h"
|
|
#include "r300_tex.h"
|
|
#include "r300_emit.h"
|
|
#include "r300_swtcl.h"
|
|
|
|
-#ifdef USER_BUFFERS
|
|
-#include "r300_mem.h"
|
|
-#endif
|
|
|
|
#include "vblank.h"
|
|
#include "utils.h"
|
|
@@ -178,6 +176,17 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {
|
|
0,
|
|
};
|
|
|
|
+static void r300RunPipeline(GLcontext * ctx)
|
|
+{
|
|
+ _mesa_lock_context_textures(ctx);
|
|
+
|
|
+ if (ctx->NewState)
|
|
+ _mesa_update_state_locked(ctx);
|
|
+
|
|
+ _tnl_run_pipeline(ctx);
|
|
+ _mesa_unlock_context_textures(ctx);
|
|
+}
|
|
+
|
|
/* Create the device specific rendering context.
|
|
*/
|
|
GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
@@ -189,7 +198,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
struct dd_function_table functions;
|
|
r300ContextPtr r300;
|
|
GLcontext *ctx;
|
|
- int tcl_mode, i;
|
|
+ int tcl_mode;
|
|
|
|
assert(glVisual);
|
|
assert(driContextPriv);
|
|
@@ -221,10 +230,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
r300InitTextureFuncs(&functions);
|
|
r300InitShaderFuncs(&functions);
|
|
|
|
-#ifdef USER_BUFFERS
|
|
- r300_mem_init(r300);
|
|
-#endif
|
|
-
|
|
if (!radeonInitContext(&r300->radeon, &functions,
|
|
glVisual, driContextPriv,
|
|
sharedContextPrivate)) {
|
|
@@ -233,33 +238,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
}
|
|
|
|
/* Init r300 context data */
|
|
- r300->dma.buf0_address =
|
|
- r300->radeon.radeonScreen->buffers->list[0].address;
|
|
-
|
|
- (void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
|
|
- make_empty_list(&r300->swapped);
|
|
-
|
|
- r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
|
|
- assert(r300->nr_heaps < RADEON_NR_TEX_HEAPS);
|
|
- for (i = 0; i < r300->nr_heaps; i++) {
|
|
- /* *INDENT-OFF* */
|
|
- r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
|
|
- screen->
|
|
- texSize[i], 12,
|
|
- RADEON_NR_TEX_REGIONS,
|
|
- (drmTextureRegionPtr)
|
|
- r300->radeon.sarea->
|
|
- tex_list[i],
|
|
- &r300->radeon.sarea->
|
|
- tex_age[i],
|
|
- &r300->swapped,
|
|
- sizeof
|
|
- (r300TexObj),
|
|
- (destroy_texture_object_t
|
|
- *)
|
|
- r300DestroyTexObj);
|
|
- /* *INDENT-ON* */
|
|
- }
|
|
r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
|
|
"texture_depth");
|
|
if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
|
|
@@ -298,13 +276,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
|
|
ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
|
|
|
|
-#ifdef USER_BUFFERS
|
|
/* Needs further modifications */
|
|
#if 0
|
|
ctx->Const.MaxArrayLockSize =
|
|
( /*512 */ RADEON_BUFFER_SIZE * 16 * 1024) / (4 * 4);
|
|
#endif
|
|
-#endif
|
|
|
|
/* Initialize the software rasterizer and helper modules.
|
|
*/
|
|
@@ -383,7 +359,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
|
|
r300InitSwtcl(ctx);
|
|
|
|
- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
|
|
+ TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline;
|
|
|
|
tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
|
|
if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
|
|
@@ -406,72 +382,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
|
|
return GL_TRUE;
|
|
}
|
|
|
|
-static void r300FreeGartAllocations(r300ContextPtr r300)
|
|
-{
|
|
- int i, ret, tries = 0, done_age, in_use = 0;
|
|
- drm_radeon_mem_free_t memfree;
|
|
-
|
|
- memfree.region = RADEON_MEM_REGION_GART;
|
|
-
|
|
-#ifdef USER_BUFFERS
|
|
- for (i = r300->rmm->u_last; i > 0; i--) {
|
|
- if (r300->rmm->u_list[i].ptr == NULL) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* check whether this buffer is still in use */
|
|
- if (r300->rmm->u_list[i].pending) {
|
|
- in_use++;
|
|
- }
|
|
- }
|
|
- /* Cannot flush/lock if no context exists. */
|
|
- if (in_use)
|
|
- r300FlushCmdBuf(r300, __FUNCTION__);
|
|
-
|
|
- done_age = radeonGetAge((radeonContextPtr) r300);
|
|
-
|
|
- for (i = r300->rmm->u_last; i > 0; i--) {
|
|
- if (r300->rmm->u_list[i].ptr == NULL) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- /* check whether this buffer is still in use */
|
|
- if (!r300->rmm->u_list[i].pending) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- assert(r300->rmm->u_list[i].h_pending == 0);
|
|
-
|
|
- tries = 0;
|
|
- while (r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
|
|
- usleep(10);
|
|
- done_age = radeonGetAge((radeonContextPtr) r300);
|
|
- }
|
|
- if (tries >= 1000) {
|
|
- WARN_ONCE("Failed to idle region!");
|
|
- }
|
|
-
|
|
- memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
|
|
- (char *)r300->radeon.radeonScreen->gartTextures.map;
|
|
-
|
|
- ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
|
|
- DRM_RADEON_FREE, &memfree,
|
|
- sizeof(memfree));
|
|
- if (ret) {
|
|
- fprintf(stderr, "Failed to free at %p\nret = %s\n",
|
|
- r300->rmm->u_list[i].ptr, strerror(-ret));
|
|
- } else {
|
|
- if (i == r300->rmm->u_last)
|
|
- r300->rmm->u_last--;
|
|
-
|
|
- r300->rmm->u_list[i].pending = 0;
|
|
- r300->rmm->u_list[i].ptr = NULL;
|
|
- }
|
|
- }
|
|
- r300->rmm->u_head = i;
|
|
-#endif /* USER_BUFFERS */
|
|
-}
|
|
-
|
|
/* Destroy the device specific context.
|
|
*/
|
|
void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
|
|
@@ -495,23 +405,12 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
|
|
assert(r300); /* should never be null */
|
|
|
|
if (r300) {
|
|
- GLboolean release_texture_heaps;
|
|
-
|
|
- release_texture_heaps =
|
|
- (r300->radeon.glCtx->Shared->RefCount == 1);
|
|
_swsetup_DestroyContext(r300->radeon.glCtx);
|
|
_tnl_DestroyContext(r300->radeon.glCtx);
|
|
_vbo_DestroyContext(r300->radeon.glCtx);
|
|
_swrast_DestroyContext(r300->radeon.glCtx);
|
|
|
|
- if (r300->dma.current.buf) {
|
|
- r300ReleaseDmaRegion(r300, &r300->dma.current,
|
|
- __FUNCTION__);
|
|
-#ifndef USER_BUFFERS
|
|
- r300FlushCmdBuf(r300, __FUNCTION__);
|
|
-#endif
|
|
- }
|
|
- r300FreeGartAllocations(r300);
|
|
+ r300FlushCmdBuf(r300, __FUNCTION__);
|
|
r300DestroyCmdBuf(r300);
|
|
|
|
if (radeon->state.scissor.pClipRects) {
|
|
@@ -519,28 +418,11 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
|
|
radeon->state.scissor.pClipRects = NULL;
|
|
}
|
|
|
|
- if (release_texture_heaps) {
|
|
- /* This share group is about to go away, free our private
|
|
- * texture object data.
|
|
- */
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < r300->nr_heaps; i++) {
|
|
- driDestroyTextureHeap(r300->texture_heaps[i]);
|
|
- r300->texture_heaps[i] = NULL;
|
|
- }
|
|
-
|
|
- assert(is_empty_list(&r300->swapped));
|
|
- }
|
|
-
|
|
radeonCleanupContext(&r300->radeon);
|
|
|
|
-#ifdef USER_BUFFERS
|
|
/* the memory manager might be accessed when Mesa frees the shared
|
|
* state, so don't destroy it earlier
|
|
*/
|
|
- r300_mem_destroy(r300);
|
|
-#endif
|
|
|
|
/* free the option cache */
|
|
driDestroyOptionCache(&r300->radeon.optionCache);
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
|
|
index c15e9fa..30229ed 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_context.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_context.h
|
|
@@ -42,13 +42,12 @@ 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_bo.h"
|
|
|
|
#include "main/macros.h"
|
|
#include "main/mtypes.h"
|
|
#include "main/colormac.h"
|
|
|
|
-#define USER_BUFFERS
|
|
-
|
|
struct r300_context;
|
|
typedef struct r300_context r300ContextRec;
|
|
typedef struct r300_context *r300ContextPtr;
|
|
@@ -122,68 +121,51 @@ static INLINE uint32_t r300PackFloat24(float f)
|
|
|
|
/************ DMA BUFFERS **************/
|
|
|
|
-/* Need refcounting on dma buffers:
|
|
- */
|
|
-struct r300_dma_buffer {
|
|
- int refcount; /**< the number of retained regions in buf */
|
|
- drmBufPtr buf;
|
|
- int id;
|
|
-};
|
|
-#undef GET_START
|
|
-#ifdef USER_BUFFERS
|
|
-#define GET_START(rvb) (r300GartOffsetFromVirtual(rmesa, (rvb)->address+(rvb)->start))
|
|
-#else
|
|
-#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
|
|
- (rvb)->address - rmesa->dma.buf0_address + \
|
|
- (rvb)->start)
|
|
-#endif
|
|
-/* A retained region, eg vertices for indexed vertices.
|
|
- */
|
|
-struct r300_dma_region {
|
|
- struct r300_dma_buffer *buf;
|
|
- char *address; /* == buf->address */
|
|
- int start, end, ptr; /* offsets from start of buf */
|
|
-
|
|
- int aos_offset; /* address in GART memory */
|
|
- int aos_stride; /* distance between elements, in dwords */
|
|
- int aos_size; /* number of components (1-4) */
|
|
-};
|
|
|
|
-struct r300_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 r300_dma_region current;
|
|
+/* Texture related */
|
|
+typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr;
|
|
+typedef struct _r300_texture_image r300_texture_image;
|
|
|
|
- void (*flush) (r300ContextPtr);
|
|
|
|
- char *buf0_address; /* start of buf[0], for index calcs */
|
|
+struct _r300_texture_image {
|
|
+ struct gl_texture_image base;
|
|
|
|
- /* Number of "in-flight" DMA buffers, i.e. the number of buffers
|
|
- * for which a DISCARD command is currently queued in the command buffer.
|
|
+ /**
|
|
+ * 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.
|
|
*/
|
|
- GLuint nr_released_bufs;
|
|
+ struct _r300_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 */
|
|
};
|
|
|
|
- /* Texture related */
|
|
+static INLINE r300_texture_image *get_r300_texture_image(struct gl_texture_image *image)
|
|
+{
|
|
+ return (r300_texture_image*)image;
|
|
+}
|
|
|
|
-typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr;
|
|
|
|
/* Texture object in locally shared texture space.
|
|
*/
|
|
struct r300_tex_obj {
|
|
- driTextureObject base;
|
|
+ struct gl_texture_object base;
|
|
+ struct _r300_mipmap_tree *mt;
|
|
|
|
- GLuint bufAddr; /* Offset to start of locally
|
|
- shared texture block */
|
|
-
|
|
- drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
|
|
- /* Six, for the cube faces */
|
|
+ /**
|
|
+ * This is true if we've verified that the mipmap tree above is complete
|
|
+ * and so on.
|
|
+ */
|
|
+ GLboolean validated;
|
|
|
|
GLboolean image_override; /* Image overridden by GLX_EXT_tfp */
|
|
+ GLuint override_offset;
|
|
|
|
- GLuint pitch; /* this isn't sent to hardware just used in calculations */
|
|
/* hardware register values */
|
|
/* Note that R200 has 8 registers per texture and R300 only 7 */
|
|
GLuint filter;
|
|
@@ -191,30 +173,17 @@ struct r300_tex_obj {
|
|
GLuint pitch_reg;
|
|
GLuint size; /* npot only */
|
|
GLuint format;
|
|
- GLuint offset; /* Image location in the card's address space.
|
|
- All cube faces follow. */
|
|
- GLuint unknown4;
|
|
- GLuint unknown5;
|
|
- /* end hardware registers */
|
|
-
|
|
- /* registers computed by r200 code - keep them here to
|
|
- compare against what is actually written.
|
|
-
|
|
- to be removed later.. */
|
|
GLuint pp_border_color;
|
|
- GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */
|
|
- GLuint format_x;
|
|
-
|
|
- GLboolean border_fallback;
|
|
+ /* end hardware registers */
|
|
|
|
GLuint tile_bits; /* hw texture tile bits used on this texture */
|
|
+ struct radeon_bo *bo;
|
|
};
|
|
|
|
-struct r300_texture_env_state {
|
|
- r300TexObjPtr texobj;
|
|
- GLenum format;
|
|
- GLenum envMode;
|
|
-};
|
|
+static INLINE r300TexObj* r300_tex_obj(struct gl_texture_object *texObj)
|
|
+{
|
|
+ return (r300TexObj*)texObj;
|
|
+}
|
|
|
|
/* The blit width for texture uploads
|
|
*/
|
|
@@ -222,7 +191,6 @@ struct r300_texture_env_state {
|
|
#define R300_MAX_TEXTURE_UNITS 8
|
|
|
|
struct r300_texture_state {
|
|
- struct r300_texture_env_state unit[R300_MAX_TEXTURE_UNITS];
|
|
int tc_count; /* number of incoming texture coordinates from VAP */
|
|
};
|
|
|
|
@@ -242,6 +210,7 @@ struct r300_state_atom {
|
|
GLboolean dirty;
|
|
|
|
int (*check) (r300ContextPtr, struct r300_state_atom * atom);
|
|
+ void (*emit) (r300ContextPtr, struct r300_state_atom * atom);
|
|
};
|
|
|
|
#define R300_VPT_CMD_0 0
|
|
@@ -549,6 +518,8 @@ struct r300_hw_state {
|
|
struct r300_state_atom border_color;
|
|
} tex;
|
|
struct r300_state_atom txe; /* tex enable (4104) */
|
|
+
|
|
+ r300TexObj *textures[R300_MAX_TEXTURE_UNITS];
|
|
};
|
|
|
|
/**
|
|
@@ -559,10 +530,10 @@ struct r300_hw_state {
|
|
* otherwise.
|
|
*/
|
|
struct r300_cmdbuf {
|
|
- int size; /* DWORDs allocated for buffer */
|
|
- uint32_t *cmd_buf;
|
|
- int count_used; /* DWORDs filled so far */
|
|
- int count_reemit; /* size of re-emission batch */
|
|
+ struct radeon_cs_manager *csm;
|
|
+ struct radeon_cs *cs;
|
|
+ int size; /** # of dwords total */
|
|
+ unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */
|
|
};
|
|
|
|
/**
|
|
@@ -811,18 +782,25 @@ struct r500_fragment_program {
|
|
#define REG_COLOR0 1
|
|
#define REG_TEX0 2
|
|
|
|
+struct r300_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 r300_state {
|
|
struct r300_depthbuffer_state depth;
|
|
struct r300_texture_state texture;
|
|
int sw_tcl_inputs[VERT_ATTRIB_MAX];
|
|
struct r300_vertex_shader_state vertex_shader;
|
|
- struct r300_dma_region aos[R300_MAX_AOS_ARRAYS];
|
|
+ struct r300_aos aos[R300_MAX_AOS_ARRAYS];
|
|
int aos_count;
|
|
|
|
- GLuint *Elts;
|
|
- struct r300_dma_region elt_dma;
|
|
+ struct radeon_bo *elt_dma_bo; /** Buffer object that contains element indices */
|
|
+ int elt_dma_offset; /** Offset into this buffer object, in bytes */
|
|
|
|
- struct r300_dma_region swtcl_dma;
|
|
DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for.
|
|
They are the same as tnl->render_inputs for fixed pipeline */
|
|
|
|
@@ -881,12 +859,8 @@ struct r300_swtcl_info {
|
|
*/
|
|
GLuint specoffset;
|
|
|
|
- /**
|
|
- * Should Mesa project vertex data or will the hardware do it?
|
|
- */
|
|
- GLboolean needproj;
|
|
-
|
|
- struct r300_dma_region indexed_verts;
|
|
+ struct radeon_bo *bo;
|
|
+ void (*flush) (r300ContextPtr);
|
|
};
|
|
|
|
|
|
@@ -904,26 +878,11 @@ struct r300_context {
|
|
|
|
/* Vertex buffers
|
|
*/
|
|
- struct r300_dma dma;
|
|
- GLboolean save_on_next_unlock;
|
|
GLuint NewGLState;
|
|
|
|
- /* Texture object bookkeeping
|
|
- */
|
|
- unsigned nr_heaps;
|
|
- driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS];
|
|
- driTextureObject swapped;
|
|
int texture_depth;
|
|
float initialMaxAnisotropy;
|
|
|
|
- /* Clientdata textures;
|
|
- */
|
|
- GLuint prefer_gart_client_texturing;
|
|
-
|
|
-#ifdef USER_BUFFERS
|
|
- struct r300_memory_manager *rmm;
|
|
-#endif
|
|
-
|
|
GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
|
|
GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
|
|
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
|
|
index 80bd338..a984f55 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_emit.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
|
|
@@ -51,9 +51,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_emit.h"
|
|
#include "r300_ioctl.h"
|
|
|
|
-#ifdef USER_BUFFERS
|
|
-#include "r300_mem.h"
|
|
-#endif
|
|
|
|
#if SWIZZLE_X != R300_INPUT_ROUTE_SELECT_X || \
|
|
SWIZZLE_Y != R300_INPUT_ROUTE_SELECT_Y || \
|
|
@@ -86,11 +83,9 @@ do { \
|
|
} while (0)
|
|
#endif
|
|
|
|
-static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
- GLvoid * data, int stride, int count)
|
|
+static void r300EmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
|
|
{
|
|
int i;
|
|
- int *out = (int *)(rvb->address + rvb->start);
|
|
|
|
if (RADEON_DEBUG & DEBUG_VERTS)
|
|
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
|
|
@@ -106,11 +101,9 @@ static void r300EmitVec4(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
}
|
|
}
|
|
|
|
-static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
- GLvoid * data, int stride, int count)
|
|
+static void r300EmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
|
|
{
|
|
int i;
|
|
- int *out = (int *)(rvb->address + rvb->start);
|
|
|
|
if (RADEON_DEBUG & DEBUG_VERTS)
|
|
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
|
|
@@ -127,18 +120,17 @@ static void r300EmitVec8(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
}
|
|
}
|
|
|
|
-static void r300EmitVec12(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
- GLvoid * data, int stride, int count)
|
|
+static void r300EmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
|
|
{
|
|
int i;
|
|
- int *out = (int *)(rvb->address + rvb->start);
|
|
|
|
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)
|
|
+ if (stride == 12) {
|
|
COPY_DWORDS(out, data, count * 3);
|
|
+ }
|
|
else
|
|
for (i = 0; i < count; i++) {
|
|
out[0] = *(int *)data;
|
|
@@ -149,11 +141,9 @@ static void r300EmitVec12(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
}
|
|
}
|
|
|
|
-static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
- GLvoid * data, int stride, int count)
|
|
+static void r300EmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
|
|
{
|
|
int i;
|
|
- int *out = (int *)(rvb->address + rvb->start);
|
|
|
|
if (RADEON_DEBUG & DEBUG_VERTS)
|
|
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
|
|
@@ -172,39 +162,40 @@ static void r300EmitVec16(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
}
|
|
}
|
|
|
|
-static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb,
|
|
+static void r300EmitVec(GLcontext * ctx, struct r300_aos *aos,
|
|
GLvoid * data, int size, int stride, int count)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
+ uint32_t *out;
|
|
+ uint32_t bo_size;
|
|
|
|
+ memset(aos, 0, sizeof(struct r300_aos));
|
|
if (stride == 0) {
|
|
- r300AllocDmaRegion(rmesa, rvb, size * 4, 4);
|
|
+ bo_size = size * 4;
|
|
count = 1;
|
|
- rvb->aos_offset = GET_START(rvb);
|
|
- rvb->aos_stride = 0;
|
|
+ aos->stride = 0;
|
|
} else {
|
|
- r300AllocDmaRegion(rmesa, rvb, size * count * 4, 4);
|
|
- rvb->aos_offset = GET_START(rvb);
|
|
- rvb->aos_stride = size;
|
|
+ bo_size = size * count * 4;
|
|
+ aos->stride = size;
|
|
}
|
|
-
|
|
+ aos->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
|
+ 0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0);
|
|
+ aos->offset = 0;
|
|
+ aos->components = size;
|
|
+ aos->count = count;
|
|
+
|
|
+ radeon_bo_map(aos->bo, 1);
|
|
+ out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
|
|
switch (size) {
|
|
- case 1:
|
|
- r300EmitVec4(ctx, rvb, data, stride, count);
|
|
- break;
|
|
- case 2:
|
|
- r300EmitVec8(ctx, rvb, data, stride, count);
|
|
- break;
|
|
- case 3:
|
|
- r300EmitVec12(ctx, rvb, data, stride, count);
|
|
- break;
|
|
- case 4:
|
|
- r300EmitVec16(ctx, rvb, data, stride, count);
|
|
- break;
|
|
+ case 1: r300EmitVec4(out, data, stride, count); break;
|
|
+ case 2: r300EmitVec8(out, data, stride, count); break;
|
|
+ case 3: r300EmitVec12(out, data, stride, count); break;
|
|
+ case 4: r300EmitVec16(out, data, stride, count); break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
+ radeon_bo_unmap(aos->bo);
|
|
}
|
|
|
|
#define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \
|
|
@@ -314,10 +305,6 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
|
|
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT |
|
|
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
|
|
|
|
-#if 0
|
|
- if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ;
|
|
-#endif
|
|
-
|
|
if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
|
|
ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
|
|
|
|
@@ -371,7 +358,6 @@ int r300EmitArrays(GLcontext * ctx)
|
|
|
|
assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS));
|
|
assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0);
|
|
- //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0));
|
|
|
|
if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) {
|
|
InputsRead |= 1 << VERT_ATTRIB_POS;
|
|
@@ -433,7 +419,7 @@ int r300EmitArrays(GLcontext * ctx)
|
|
}
|
|
|
|
for (i = 0; i < nr; i++) {
|
|
- int ci, fix, found = 0;
|
|
+ int ci;
|
|
|
|
swizzle[i][0] = SWIZZLE_ZERO;
|
|
swizzle[i][1] = SWIZZLE_ZERO;
|
|
@@ -443,52 +429,25 @@ int r300EmitArrays(GLcontext * ctx)
|
|
for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) {
|
|
swizzle[i][ci] = ci;
|
|
}
|
|
-
|
|
- if (r300IsGartMemory(rmesa, vb->AttribPtr[tab[i]]->data, 4)) {
|
|
- if (vb->AttribPtr[tab[i]]->stride % 4) {
|
|
- return R300_FALLBACK_TCL;
|
|
- }
|
|
- rmesa->state.aos[i].address = (void *)(vb->AttribPtr[tab[i]]->data);
|
|
- rmesa->state.aos[i].start = 0;
|
|
- rmesa->state.aos[i].aos_offset = r300GartOffsetFromVirtual(rmesa, vb->AttribPtr[tab[i]]->data);
|
|
- rmesa->state.aos[i].aos_stride = vb->AttribPtr[tab[i]]->stride / 4;
|
|
- rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size;
|
|
- } else {
|
|
- r300EmitVec(ctx, &rmesa->state.aos[i],
|
|
- vb->AttribPtr[tab[i]]->data,
|
|
- vb->AttribPtr[tab[i]]->size,
|
|
- vb->AttribPtr[tab[i]]->stride, count);
|
|
- }
|
|
-
|
|
- rmesa->state.aos[i].aos_size = vb->AttribPtr[tab[i]]->size;
|
|
-
|
|
- for (fix = 0; fix <= 4 - vb->AttribPtr[tab[i]]->size; fix++) {
|
|
- if ((rmesa->state.aos[i].aos_offset - _mesa_sizeof_type(GL_FLOAT) * fix) % 4) {
|
|
- continue;
|
|
- }
|
|
- found = 1;
|
|
- break;
|
|
- }
|
|
-
|
|
- if (found) {
|
|
- if (fix > 0) {
|
|
- WARN_ONCE("Feeling lucky?\n");
|
|
- }
|
|
- rmesa->state.aos[i].aos_offset -= _mesa_sizeof_type(GL_FLOAT) * fix;
|
|
- for (ci = 0; ci < vb->AttribPtr[tab[i]]->size; ci++) {
|
|
- swizzle[i][ci] += fix;
|
|
- }
|
|
- } else {
|
|
- WARN_ONCE
|
|
- ("Cannot handle offset %x with stride %d, comp %d\n",
|
|
- rmesa->state.aos[i].aos_offset,
|
|
- rmesa->state.aos[i].aos_stride,
|
|
- vb->AttribPtr[tab[i]]->size);
|
|
- return R300_FALLBACK_TCL;
|
|
- }
|
|
+ r300EmitVec(ctx, &rmesa->state.aos[i],
|
|
+ vb->AttribPtr[tab[i]]->data,
|
|
+ vb->AttribPtr[tab[i]]->size,
|
|
+ vb->AttribPtr[tab[i]]->stride, count);
|
|
}
|
|
|
|
/* Setup INPUT_ROUTE. */
|
|
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ 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],
|
|
@@ -497,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);
|
|
@@ -515,45 +475,33 @@ int r300EmitArrays(GLcontext * ctx)
|
|
return R300_FALLBACK_NONE;
|
|
}
|
|
|
|
-#ifdef USER_BUFFERS
|
|
-void r300UseArrays(GLcontext * ctx)
|
|
-{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- int i;
|
|
-
|
|
- if (rmesa->state.elt_dma.buf)
|
|
- r300_mem_use(rmesa, rmesa->state.elt_dma.buf->id);
|
|
-
|
|
- for (i = 0; i < rmesa->state.aos_count; i++) {
|
|
- if (rmesa->state.aos[i].buf)
|
|
- r300_mem_use(rmesa, rmesa->state.aos[i].buf->id);
|
|
- }
|
|
-}
|
|
-#endif
|
|
-
|
|
void r300ReleaseArrays(GLcontext * ctx)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
int i;
|
|
|
|
- r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__);
|
|
+ if (rmesa->state.elt_dma_bo) {
|
|
+ radeon_bo_unref(rmesa->state.elt_dma_bo);
|
|
+ rmesa->state.elt_dma_bo = 0;
|
|
+ }
|
|
for (i = 0; i < rmesa->state.aos_count; i++) {
|
|
- r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
|
|
+ if (rmesa->state.aos[i].bo) {
|
|
+ rmesa->state.aos[i].bo = radeon_bo_unref(rmesa->state.aos[i].bo);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
void r300EmitCacheFlush(r300ContextPtr rmesa)
|
|
{
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
-
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
-
|
|
- reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
|
|
- e32(R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
|
|
- R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
|
|
-
|
|
- reg_start(R300_ZB_ZCACHE_CTLSTAT, 0);
|
|
- e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
|
|
- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
|
|
+ BATCH_LOCALS(rmesa);
|
|
+
|
|
+ BEGIN_BATCH(4);
|
|
+ OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT,
|
|
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
|
|
+ R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
|
|
+ OUT_BATCH_REGVAL(R300_ZB_ZCACHE_CTLSTAT,
|
|
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
|
|
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
|
|
+ END_BATCH();
|
|
+ COMMIT_BATCH();
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
|
|
index 89d7383..db43cc3 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->kernel_mm) {
|
|
+ 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;
|
|
|
|
@@ -127,130 +138,100 @@ static INLINE uint32_t cmdpacify(void)
|
|
return cmd.u;
|
|
}
|
|
|
|
-/**
|
|
- * Prepare to write a register value to register at address reg.
|
|
- * If num_extra > 0 then the following extra values are written
|
|
- * to registers with address +4, +8 and so on..
|
|
- */
|
|
-#define reg_start(reg, num_extra) \
|
|
- do { \
|
|
- int _n; \
|
|
- _n=(num_extra); \
|
|
- cmd = (drm_radeon_cmd_header_t*) \
|
|
- r300AllocCmdBuf(rmesa, \
|
|
- (_n+2), \
|
|
- __FUNCTION__); \
|
|
- cmd_reserved=_n+2; \
|
|
- cmd_written=1; \
|
|
- cmd[0].i=cmdpacket0((reg), _n+1); \
|
|
- } while (0);
|
|
+
|
|
+/** Single register write to command buffer; requires 2 dwords. */
|
|
+#define OUT_BATCH_REGVAL(reg, val) \
|
|
+ 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(b_l_r300->radeon.radeonScreen, (reg), (count)));
|
|
+
|
|
+/** Write a 32 bit float to the ring; requires 1 dword. */
|
|
+#define OUT_BATCH_FLOAT32(f) \
|
|
+ OUT_BATCH(r300PackFloat32((f)));
|
|
|
|
/**
|
|
- * Emit GLuint freestyle
|
|
+ * Write the header of a packet3 to the command buffer.
|
|
+ * Outputs 2 dwords and expects (num_extra+1) additional dwords afterwards.
|
|
*/
|
|
-#define e32(dword) \
|
|
- do { \
|
|
- if(cmd_written<cmd_reserved) { \
|
|
- cmd[cmd_written].i=(dword); \
|
|
- cmd_written++; \
|
|
- } else { \
|
|
- fprintf(stderr, \
|
|
- "e32 but no previous packet " \
|
|
- "declaration.\n" \
|
|
- "Aborting! in %s::%s at line %d, " \
|
|
- "cmd_written=%d cmd_reserved=%d\n", \
|
|
- __FILE__, __FUNCTION__, __LINE__, \
|
|
- cmd_written, cmd_reserved); \
|
|
- _mesa_exit(-1); \
|
|
- } \
|
|
+#define OUT_BATCH_PACKET3(packet, num_extra) do {\
|
|
+ if (!b_l_r300->radeon.radeonScreen->kernel_mm) { \
|
|
+ OUT_BATCH(cmdpacket3(b_l_r300->radeon.radeonScreen,\
|
|
+ R300_CMD_PACKET3_RAW)); \
|
|
+ }\
|
|
+ OUT_BATCH(CP_PACKET3((packet), (num_extra))); \
|
|
} while(0)
|
|
|
|
-#define efloat(f) e32(r300PackFloat32(f))
|
|
-
|
|
-#define vsf_start_fragment(dest, length) \
|
|
- do { \
|
|
- int _n; \
|
|
- _n = (length); \
|
|
- cmd = (drm_radeon_cmd_header_t*) \
|
|
- r300AllocCmdBuf(rmesa, \
|
|
- (_n+1), \
|
|
- __FUNCTION__); \
|
|
- cmd_reserved = _n+2; \
|
|
- cmd_written =1; \
|
|
- cmd[0].i = cmdvpu((dest), _n/4); \
|
|
- } while (0);
|
|
-
|
|
-#define r500fp_start_fragment(dest, length) \
|
|
- do { \
|
|
- int _n; \
|
|
- _n = (length); \
|
|
- cmd = (drm_radeon_cmd_header_t*) \
|
|
- r300AllocCmdBuf(rmesa, \
|
|
- (_n+1), \
|
|
- __FUNCTION__); \
|
|
- cmd_reserved = _n+1; \
|
|
- cmd_written =1; \
|
|
- cmd[0].i = cmdr500fp((dest), _n/6, 0, 0); \
|
|
- } while (0);
|
|
-
|
|
-#define start_packet3(packet, count) \
|
|
- { \
|
|
- int _n; \
|
|
- GLuint _p; \
|
|
- _n = (count); \
|
|
- _p = (packet); \
|
|
- cmd = (drm_radeon_cmd_header_t*) \
|
|
- r300AllocCmdBuf(rmesa, \
|
|
- (_n+3), \
|
|
- __FUNCTION__); \
|
|
- cmd_reserved = _n+3; \
|
|
- cmd_written = 2; \
|
|
- if(_n > 0x3fff) { \
|
|
- fprintf(stderr,"Too big packet3 %08x: cannot " \
|
|
- "store %d dwords\n", \
|
|
- _p, _n); \
|
|
- _mesa_exit(-1); \
|
|
- } \
|
|
- cmd[0].i = cmdpacket3(R300_CMD_PACKET3_RAW); \
|
|
- cmd[1].i = _p | ((_n & 0x3fff)<<16); \
|
|
- }
|
|
-
|
|
/**
|
|
* Must be sent to switch to 2d commands
|
|
*/
|
|
void static INLINE end_3d(r300ContextPtr rmesa)
|
|
{
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
+ BATCH_LOCALS(rmesa);
|
|
|
|
- cmd =
|
|
- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
|
|
- cmd[0].header.cmd_type = R300_CMD_END3D;
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ BEGIN_BATCH(1);
|
|
+ OUT_BATCH(cmdpacify(rmesa->radeon.radeonScreen));
|
|
+ END_BATCH();
|
|
+ }
|
|
}
|
|
|
|
void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count)
|
|
{
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
+ BATCH_LOCALS(rmesa);
|
|
|
|
- cmd =
|
|
- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
|
|
- cmd[0].i = cmdcpdelay(count);
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ BEGIN_BATCH(1);
|
|
+ OUT_BATCH(cmdcpdelay(rmesa->radeon.radeonScreen, count));
|
|
+ END_BATCH();
|
|
+ }
|
|
}
|
|
|
|
void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags)
|
|
{
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
-
|
|
- cmd =
|
|
- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__);
|
|
- cmd[0].i = cmdwait(flags);
|
|
+ BATCH_LOCALS(rmesa);
|
|
+ uint32_t wait_until;
|
|
+
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ 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);
|
|
|
|
-#ifdef USER_BUFFERS
|
|
-void r300UseArrays(GLcontext * ctx);
|
|
-#endif
|
|
-
|
|
extern void r300ReleaseArrays(GLcontext * ctx);
|
|
extern int r300PrimitiveType(r300ContextPtr rmesa, int prim);
|
|
extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim);
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
|
|
index ee85e22..6d7b191 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
|
|
@@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "main/context.h"
|
|
#include "swrast/swrast.h"
|
|
|
|
+#include "radeon_buffer.h"
|
|
#include "r300_context.h"
|
|
#include "radeon_ioctl.h"
|
|
#include "r300_ioctl.h"
|
|
@@ -55,71 +56,83 @@ 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
|
|
|
|
-static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
|
+static void r300ClearBuffer(r300ContextPtr r300, int flags,
|
|
+ struct radeon_renderbuffer *rrb,
|
|
+ struct radeon_renderbuffer *rrbd)
|
|
{
|
|
+ BATCH_LOCALS(r300);
|
|
GLcontext *ctx = r300->radeon.glCtx;
|
|
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
|
- GLuint cboffset, cbpitch;
|
|
- drm_r300_cmd_header_t *cmd2;
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
+ GLuint cbpitch = 0;
|
|
r300ContextPtr rmesa = r300;
|
|
|
|
if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "%s: %s buffer (%i,%i %ix%i)\n",
|
|
- __FUNCTION__, buffer ? "back" : "front",
|
|
- dPriv->x, dPriv->y, dPriv->w, dPriv->h);
|
|
-
|
|
- if (buffer) {
|
|
- cboffset = r300->radeon.radeonScreen->backOffset;
|
|
- cbpitch = r300->radeon.radeonScreen->backPitch;
|
|
- } else {
|
|
- cboffset = r300->radeon.radeonScreen->frontOffset;
|
|
- cbpitch = r300->radeon.radeonScreen->frontPitch;
|
|
+ fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n",
|
|
+ __FUNCTION__, rrb, dPriv->x, dPriv->y,
|
|
+ dPriv->w, dPriv->h);
|
|
+
|
|
+ if (rrb) {
|
|
+ cbpitch = (rrb->pitch / rrb->cpp);
|
|
+ if (rrb->cpp == 4)
|
|
+ cbpitch |= R300_COLOR_FORMAT_ARGB8888;
|
|
+ else
|
|
+ cbpitch |= R300_COLOR_FORMAT_RGB565;
|
|
+
|
|
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
|
|
+ cbpitch |= R300_COLOR_TILE_ENABLE;
|
|
+ }
|
|
}
|
|
|
|
- cboffset += r300->radeon.radeonScreen->fbLocation;
|
|
-
|
|
+ /* TODO in bufmgr */
|
|
cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
|
|
end_3d(rmesa);
|
|
|
|
- R300_STATECHANGE(r300, cb);
|
|
- reg_start(R300_RB3D_COLOROFFSET0, 0);
|
|
- e32(cboffset);
|
|
-
|
|
- if (r300->radeon.radeonScreen->cpp == 4)
|
|
- cbpitch |= R300_COLOR_FORMAT_ARGB8888;
|
|
- else
|
|
- cbpitch |= R300_COLOR_FORMAT_RGB565;
|
|
-
|
|
- if (r300->radeon.sarea->tiling_enabled)
|
|
- cbpitch |= R300_COLOR_TILE_ENABLE;
|
|
-
|
|
- reg_start(R300_RB3D_COLORPITCH0, 0);
|
|
- e32(cbpitch);
|
|
-
|
|
- R300_STATECHANGE(r300, cmk);
|
|
- reg_start(RB3D_COLOR_CHANNEL_MASK, 0);
|
|
-
|
|
if (flags & CLEARBUFFER_COLOR) {
|
|
- e32((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) |
|
|
- (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) |
|
|
- (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) |
|
|
- (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0));
|
|
+ assert(rrb != 0);
|
|
+ BEGIN_BATCH_NO_AUTOSTATE(4);
|
|
+ OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
|
|
+ OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch);
|
|
+ END_BATCH();
|
|
+ }
|
|
+#if 1
|
|
+ if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) {
|
|
+ assert(rrbd != 0);
|
|
+ cbpitch = (rrbd->pitch / rrbd->cpp);
|
|
+ if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
|
|
+ cbpitch |= R300_DEPTHMACROTILE_ENABLE;
|
|
+ }
|
|
+ if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
|
|
+ cbpitch |= R300_DEPTHMICROTILE_TILED;
|
|
+ }
|
|
+ BEGIN_BATCH_NO_AUTOSTATE(4);
|
|
+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
|
|
+ OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, cbpitch);
|
|
+ END_BATCH();
|
|
+ }
|
|
+#endif
|
|
+ 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) |
|
|
+ (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) |
|
|
+ (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) |
|
|
+ (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0));
|
|
} else {
|
|
- e32(0x0);
|
|
+ OUT_BATCH(0);
|
|
}
|
|
|
|
- R300_STATECHANGE(r300, zs);
|
|
- reg_start(R300_ZB_CNTL, 2);
|
|
|
|
{
|
|
uint32_t t1, t2;
|
|
@@ -146,37 +159,55 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
|
|
R300_S_FRONT_ZFAIL_OP_SHIFT);
|
|
}
|
|
|
|
- e32(t1);
|
|
- e32(t2);
|
|
- e32(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << R300_STENCILWRITEMASK_SHIFT) |
|
|
- (ctx->Stencil.Clear & R300_STENCILREF_MASK));
|
|
+ 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) |
|
|
+ (ctx->Stencil.Clear & R300_STENCILREF_MASK));
|
|
+ END_BATCH();
|
|
}
|
|
|
|
- cmd2 = (drm_r300_cmd_header_t *) r300AllocCmdBuf(r300, 9, __FUNCTION__);
|
|
- cmd2[0].packet3.cmd_type = R300_CMD_PACKET3;
|
|
- cmd2[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
|
|
- cmd2[1].u = r300PackFloat32(dPriv->w / 2.0);
|
|
- cmd2[2].u = r300PackFloat32(dPriv->h / 2.0);
|
|
- cmd2[3].u = r300PackFloat32(ctx->Depth.Clear);
|
|
- cmd2[4].u = r300PackFloat32(1.0);
|
|
- cmd2[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
|
|
- cmd2[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
|
|
- cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
|
|
- cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ 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);
|
|
+
|
|
+ R300_STATECHANGE(r300, cb);
|
|
+ R300_STATECHANGE(r300, cmk);
|
|
+ R300_STATECHANGE(r300, zs);
|
|
}
|
|
|
|
static void r300EmitClearState(GLcontext * ctx)
|
|
{
|
|
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
|
- r300ContextPtr rmesa = r300;
|
|
+ BATCH_LOCALS(r300);
|
|
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
|
int i;
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
int has_tcl = 1;
|
|
int is_r500 = 0;
|
|
GLuint vap_cntl;
|
|
@@ -184,35 +215,37 @@ static void r300EmitClearState(GLcontext * ctx)
|
|
if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
|
|
has_tcl = 0;
|
|
|
|
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
|
|
- is_r500 = 1;
|
|
-
|
|
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
|
|
+ is_r500 = 1;
|
|
|
|
- /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and
|
|
- * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are
|
|
- * quite complex; see the functions in r300_emit.c.
|
|
+ /* State atom dirty tracking is a little subtle here.
|
|
+ *
|
|
+ * On the one hand, we need to make sure base state is emitted
|
|
+ * here if we start with an empty batch buffer, otherwise clear
|
|
+ * works incorrectly with multiple processes. Therefore, the first
|
|
+ * BEGIN_BATCH cannot be a BEGIN_BATCH_NO_AUTOSTATE.
|
|
*
|
|
- * I believe it would be a good idea to extend the functions in
|
|
- * r300_emit.c so that they can be used to setup the default values for
|
|
- * these registers, as well as the actual values used for rendering.
|
|
+ * On the other hand, implicit state emission clears the state atom
|
|
+ * dirty bits, so we have to call R300_STATECHANGE later than the
|
|
+ * first BEGIN_BATCH.
|
|
+ *
|
|
+ * The final trickiness is that, because we change state, we need
|
|
+ * to ensure that any stored swtcl primitives are flushed properly
|
|
+ * before we start changing state. See the R300_NEWPRIM in r300Clear
|
|
+ * for this.
|
|
*/
|
|
- R300_STATECHANGE(r300, vir[0]);
|
|
- reg_start(R300_VAP_PROG_STREAM_CNTL_0, 0);
|
|
+ BEGIN_BATCH(31);
|
|
+ OUT_BATCH_REGSEQ(R300_VAP_PROG_STREAM_CNTL_0, 1);
|
|
if (!has_tcl)
|
|
- e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
|
|
+ OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
|
|
((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)));
|
|
else
|
|
- e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
|
|
+ OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
|
|
((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)));
|
|
|
|
- /* disable fog */
|
|
- R300_STATECHANGE(r300, fogs);
|
|
- reg_start(R300_FG_FOG_BLEND, 0);
|
|
- e32(0x0);
|
|
-
|
|
- R300_STATECHANGE(r300, vir[1]);
|
|
- reg_start(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0);
|
|
- e32(((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
|
|
+ OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
|
|
+ OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
|
|
+ ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
|
|
(R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
|
|
(R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) |
|
|
(R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) |
|
|
@@ -226,238 +259,276 @@ static void r300EmitClearState(GLcontext * ctx)
|
|
<< R300_SWIZZLE1_SHIFT)));
|
|
|
|
/* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */
|
|
- R300_STATECHANGE(r300, vic);
|
|
- reg_start(R300_VAP_VTX_STATE_CNTL, 1);
|
|
- e32((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT));
|
|
- e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
|
|
+ OUT_BATCH_REGSEQ(R300_VAP_VTX_STATE_CNTL, 2);
|
|
+ OUT_BATCH((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT));
|
|
+ OUT_BATCH(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
|
|
|
|
- R300_STATECHANGE(r300, vte);
|
|
/* comes from fglrx startup of clear */
|
|
- reg_start(R300_SE_VTE_CNTL, 1);
|
|
- e32(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
|
|
- R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
|
|
- R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
|
|
- R300_VPORT_Z_OFFSET_ENA);
|
|
- e32(0x8);
|
|
+ OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
|
|
+ OUT_BATCH(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
|
|
+ R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
|
|
+ R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
|
|
+ R300_VPORT_Z_OFFSET_ENA);
|
|
+ OUT_BATCH(0x8);
|
|
|
|
- reg_start(R300_VAP_PSC_SGN_NORM_CNTL, 0);
|
|
- e32(0xaaaaaaaa);
|
|
+ OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
|
|
|
|
- R300_STATECHANGE(r300, vof);
|
|
- reg_start(R300_VAP_OUTPUT_VTX_FMT_0, 1);
|
|
- e32(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
|
|
- R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT);
|
|
- e32(0x0); /* no textures */
|
|
+ OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
|
|
+ OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
|
|
+ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT);
|
|
+ OUT_BATCH(0); /* no textures */
|
|
|
|
- R300_STATECHANGE(r300, txe);
|
|
- reg_start(R300_TX_ENABLE, 0);
|
|
- e32(0x0);
|
|
+ OUT_BATCH_REGVAL(R300_TX_ENABLE, 0);
|
|
|
|
- R300_STATECHANGE(r300, vpt);
|
|
- reg_start(R300_SE_VPORT_XSCALE, 5);
|
|
- efloat(1.0);
|
|
- efloat(dPriv->x);
|
|
- efloat(1.0);
|
|
- efloat(dPriv->y);
|
|
- efloat(1.0);
|
|
- efloat(0.0);
|
|
+ OUT_BATCH_REGSEQ(R300_SE_VPORT_XSCALE, 6);
|
|
+ OUT_BATCH_FLOAT32(1.0);
|
|
+ OUT_BATCH_FLOAT32(dPriv->x);
|
|
+ OUT_BATCH_FLOAT32(1.0);
|
|
+ OUT_BATCH_FLOAT32(dPriv->y);
|
|
+ OUT_BATCH_FLOAT32(1.0);
|
|
+ OUT_BATCH_FLOAT32(0.0);
|
|
|
|
- R300_STATECHANGE(r300, at);
|
|
- reg_start(R300_FG_ALPHA_FUNC, 0);
|
|
- e32(0x0);
|
|
+ OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
|
|
|
|
+ OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(0x0);
|
|
+ END_BATCH();
|
|
+
|
|
+ R300_STATECHANGE(r300, vir[0]);
|
|
+ R300_STATECHANGE(r300, fogs);
|
|
+ R300_STATECHANGE(r300, vir[1]);
|
|
+ R300_STATECHANGE(r300, vic);
|
|
+ R300_STATECHANGE(r300, vte);
|
|
+ R300_STATECHANGE(r300, vof);
|
|
+ R300_STATECHANGE(r300, txe);
|
|
+ R300_STATECHANGE(r300, vpt);
|
|
+ R300_STATECHANGE(r300, at);
|
|
R300_STATECHANGE(r300, bld);
|
|
- reg_start(R300_RB3D_CBLEND, 1);
|
|
- e32(0x0);
|
|
- e32(0x0);
|
|
+ R300_STATECHANGE(r300, ps);
|
|
|
|
if (has_tcl) {
|
|
- R300_STATECHANGE(r300, vap_clip_cntl);
|
|
- reg_start(R300_VAP_CLIP_CNTL, 0);
|
|
- e32(R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE);
|
|
+ R300_STATECHANGE(r300, vap_clip_cntl);
|
|
+
|
|
+ BEGIN_BATCH_NO_AUTOSTATE(2);
|
|
+ OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE);
|
|
+ END_BATCH();
|
|
}
|
|
|
|
- R300_STATECHANGE(r300, ps);
|
|
- reg_start(R300_GA_POINT_SIZE, 0);
|
|
- e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
|
|
- ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
|
|
+ BEGIN_BATCH_NO_AUTOSTATE(2);
|
|
+ OUT_BATCH_REGVAL(R300_GA_POINT_SIZE,
|
|
+ ((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
|
|
+ ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
|
|
+ END_BATCH();
|
|
|
|
if (!is_r500) {
|
|
R300_STATECHANGE(r300, ri);
|
|
- reg_start(R300_RS_IP_0, 7);
|
|
- for (i = 0; i < 8; ++i) {
|
|
- e32(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3));
|
|
- }
|
|
-
|
|
R300_STATECHANGE(r300, rc);
|
|
- /* The second constant is needed to get glxgears display anything .. */
|
|
- reg_start(R300_RS_COUNT, 1);
|
|
- e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
|
|
- e32(0x0);
|
|
-
|
|
R300_STATECHANGE(r300, rr);
|
|
- reg_start(R300_RS_INST_0, 0);
|
|
- e32(R300_RS_INST_COL_CN_WRITE);
|
|
+
|
|
+ BEGIN_BATCH(14);
|
|
+ OUT_BATCH_REGSEQ(R300_RS_IP_0, 8);
|
|
+ for (i = 0; i < 8; ++i)
|
|
+ OUT_BATCH(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3));
|
|
+
|
|
+ OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
|
|
+ OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
|
|
+ OUT_BATCH(0x0);
|
|
+
|
|
+ OUT_BATCH_REGVAL(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE);
|
|
+ END_BATCH();
|
|
} else {
|
|
R300_STATECHANGE(r300, ri);
|
|
- reg_start(R500_RS_IP_0, 7);
|
|
+ R300_STATECHANGE(r300, rc);
|
|
+ R300_STATECHANGE(r300, rr);
|
|
+
|
|
+ BEGIN_BATCH(14);
|
|
+ OUT_BATCH_REGSEQ(R500_RS_IP_0, 8);
|
|
for (i = 0; i < 8; ++i) {
|
|
- e32((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
|
|
- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
|
|
- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
|
|
- (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
|
|
+ OUT_BATCH((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
|
|
+ (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
|
|
+ (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
|
|
+ (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
|
|
}
|
|
|
|
- R300_STATECHANGE(r300, rc);
|
|
- /* The second constant is needed to get glxgears display anything .. */
|
|
- reg_start(R300_RS_COUNT, 1);
|
|
- e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
|
|
- e32(0x0);
|
|
-
|
|
- R300_STATECHANGE(r300, rr);
|
|
- reg_start(R500_RS_INST_0, 0);
|
|
- e32(R500_RS_INST_COL_CN_WRITE);
|
|
+ OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
|
|
+ OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
|
|
+ OUT_BATCH(0x0);
|
|
|
|
+ OUT_BATCH_REGVAL(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE);
|
|
+ END_BATCH();
|
|
}
|
|
|
|
if (!is_r500) {
|
|
R300_STATECHANGE(r300, fp);
|
|
- reg_start(R300_US_CONFIG, 2);
|
|
- e32(0x0);
|
|
- e32(0x0);
|
|
- e32(0x0);
|
|
- reg_start(R300_US_CODE_ADDR_0, 3);
|
|
- e32(0x0);
|
|
- e32(0x0);
|
|
- e32(0x0);
|
|
- e32(R300_RGBA_OUT);
|
|
-
|
|
R300_STATECHANGE(r300, fpi[0]);
|
|
R300_STATECHANGE(r300, fpi[1]);
|
|
R300_STATECHANGE(r300, fpi[2]);
|
|
R300_STATECHANGE(r300, fpi[3]);
|
|
|
|
- reg_start(R300_US_ALU_RGB_INST_0, 0);
|
|
- e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
|
|
-
|
|
- reg_start(R300_US_ALU_RGB_ADDR_0, 0);
|
|
- e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
|
|
-
|
|
- reg_start(R300_US_ALU_ALPHA_INST_0, 0);
|
|
- e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
|
|
-
|
|
- reg_start(R300_US_ALU_ALPHA_ADDR_0, 0);
|
|
- e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
|
|
+ BEGIN_BATCH(17);
|
|
+ OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH(R300_RGBA_OUT);
|
|
+
|
|
+ OUT_BATCH_REGVAL(R300_US_ALU_RGB_INST_0,
|
|
+ FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
|
|
+ OUT_BATCH_REGVAL(R300_US_ALU_RGB_ADDR_0,
|
|
+ FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
|
|
+ OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_INST_0,
|
|
+ FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
|
|
+ OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_ADDR_0,
|
|
+ FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
|
|
+ END_BATCH();
|
|
} else {
|
|
- R300_STATECHANGE(r300, fp);
|
|
- reg_start(R500_US_CONFIG, 1);
|
|
- e32(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
|
|
- e32(0x0);
|
|
- reg_start(R500_US_CODE_ADDR, 2);
|
|
- e32(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1));
|
|
- e32(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1));
|
|
- e32(R500_US_CODE_OFFSET_ADDR(0));
|
|
+ struct r300_state_atom r500fp;
|
|
+ uint32_t _cmd[10];
|
|
|
|
+ R300_STATECHANGE(r300, fp);
|
|
R300_STATECHANGE(r300, r500fp);
|
|
- r500fp_start_fragment(0, 6);
|
|
-
|
|
- e32(R500_INST_TYPE_OUT |
|
|
- R500_INST_TEX_SEM_WAIT |
|
|
- R500_INST_LAST |
|
|
- R500_INST_RGB_OMASK_R |
|
|
- R500_INST_RGB_OMASK_G |
|
|
- R500_INST_RGB_OMASK_B |
|
|
- R500_INST_ALPHA_OMASK |
|
|
- R500_INST_RGB_CLAMP |
|
|
- R500_INST_ALPHA_CLAMP);
|
|
-
|
|
- e32(R500_RGB_ADDR0(0) |
|
|
- R500_RGB_ADDR1(0) |
|
|
- R500_RGB_ADDR1_CONST |
|
|
- R500_RGB_ADDR2(0) |
|
|
- R500_RGB_ADDR2_CONST);
|
|
-
|
|
- e32(R500_ALPHA_ADDR0(0) |
|
|
- R500_ALPHA_ADDR1(0) |
|
|
- R500_ALPHA_ADDR1_CONST |
|
|
- R500_ALPHA_ADDR2(0) |
|
|
- R500_ALPHA_ADDR2_CONST);
|
|
-
|
|
- e32(R500_ALU_RGB_SEL_A_SRC0 |
|
|
- R500_ALU_RGB_R_SWIZ_A_R |
|
|
- R500_ALU_RGB_G_SWIZ_A_G |
|
|
- R500_ALU_RGB_B_SWIZ_A_B |
|
|
- R500_ALU_RGB_SEL_B_SRC0 |
|
|
- R500_ALU_RGB_R_SWIZ_B_R |
|
|
- R500_ALU_RGB_B_SWIZ_B_G |
|
|
- R500_ALU_RGB_G_SWIZ_B_B);
|
|
-
|
|
- e32(R500_ALPHA_OP_CMP |
|
|
- R500_ALPHA_SWIZ_A_A |
|
|
- R500_ALPHA_SWIZ_B_A);
|
|
-
|
|
- e32(R500_ALU_RGBA_OP_CMP |
|
|
- R500_ALU_RGBA_R_SWIZ_0 |
|
|
- R500_ALU_RGBA_G_SWIZ_0 |
|
|
- R500_ALU_RGBA_B_SWIZ_0 |
|
|
- R500_ALU_RGBA_A_SWIZ_0);
|
|
+
|
|
+ BEGIN_BATCH(14);
|
|
+ OUT_BATCH_REGSEQ(R500_US_CONFIG, 2);
|
|
+ OUT_BATCH(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
|
|
+ OUT_BATCH(0x0);
|
|
+ OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
|
|
+ OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1));
|
|
+ OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1));
|
|
+ OUT_BATCH(R500_US_CODE_OFFSET_ADDR(0));
|
|
+ END_BATCH();
|
|
+
|
|
+ r500fp.check = check_r500fp;
|
|
+ r500fp.cmd = _cmd;
|
|
+ r500fp.cmd[0] = cmdr500fp(r300->radeon.radeonScreen, 0, 1, 0, 0);
|
|
+ r500fp.cmd[1] = R500_INST_TYPE_OUT |
|
|
+ R500_INST_TEX_SEM_WAIT |
|
|
+ R500_INST_LAST |
|
|
+ R500_INST_RGB_OMASK_R |
|
|
+ R500_INST_RGB_OMASK_G |
|
|
+ R500_INST_RGB_OMASK_B |
|
|
+ R500_INST_ALPHA_OMASK |
|
|
+ R500_INST_RGB_CLAMP |
|
|
+ R500_INST_ALPHA_CLAMP;
|
|
+ r500fp.cmd[2] = R500_RGB_ADDR0(0) |
|
|
+ R500_RGB_ADDR1(0) |
|
|
+ R500_RGB_ADDR1_CONST |
|
|
+ R500_RGB_ADDR2(0) |
|
|
+ R500_RGB_ADDR2_CONST;
|
|
+ r500fp.cmd[3] = R500_ALPHA_ADDR0(0) |
|
|
+ R500_ALPHA_ADDR1(0) |
|
|
+ R500_ALPHA_ADDR1_CONST |
|
|
+ R500_ALPHA_ADDR2(0) |
|
|
+ R500_ALPHA_ADDR2_CONST;
|
|
+ r500fp.cmd[4] = R500_ALU_RGB_SEL_A_SRC0 |
|
|
+ R500_ALU_RGB_R_SWIZ_A_R |
|
|
+ R500_ALU_RGB_G_SWIZ_A_G |
|
|
+ R500_ALU_RGB_B_SWIZ_A_B |
|
|
+ R500_ALU_RGB_SEL_B_SRC0 |
|
|
+ R500_ALU_RGB_R_SWIZ_B_R |
|
|
+ R500_ALU_RGB_B_SWIZ_B_G |
|
|
+ R500_ALU_RGB_G_SWIZ_B_B;
|
|
+ r500fp.cmd[5] = R500_ALPHA_OP_CMP |
|
|
+ R500_ALPHA_SWIZ_A_A |
|
|
+ R500_ALPHA_SWIZ_B_A;
|
|
+ r500fp.cmd[6] = R500_ALU_RGBA_OP_CMP |
|
|
+ R500_ALU_RGBA_R_SWIZ_0 |
|
|
+ R500_ALU_RGBA_G_SWIZ_0 |
|
|
+ R500_ALU_RGBA_B_SWIZ_0 |
|
|
+ R500_ALU_RGBA_A_SWIZ_0;
|
|
+
|
|
+ r500fp.cmd[7] = 0;
|
|
+ emit_r500fp(r300, &r500fp);
|
|
}
|
|
|
|
- reg_start(R300_VAP_PVS_STATE_FLUSH_REG, 0);
|
|
- e32(0x00000000);
|
|
+ BEGIN_BATCH(2);
|
|
+ OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
|
|
+ END_BATCH();
|
|
+
|
|
if (has_tcl) {
|
|
- vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
|
|
+ vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
|
|
(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
|
|
(12 << R300_VF_MAX_VTX_NUM_SHIFT));
|
|
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
|
|
- vap_cntl |= R500_TCL_STATE_OPTIMIZATION;
|
|
- } else
|
|
- vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
|
|
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
|
|
+ vap_cntl |= R500_TCL_STATE_OPTIMIZATION;
|
|
+ } else {
|
|
+ vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
|
|
(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
|
|
(5 << R300_VF_MAX_VTX_NUM_SHIFT));
|
|
+ }
|
|
|
|
if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515)
|
|
- vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+ vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
|
|
else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) ||
|
|
(r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) ||
|
|
(r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))
|
|
- vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+ vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
|
|
else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) ||
|
|
(r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420))
|
|
- vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+ vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
|
|
else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||
|
|
(r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580))
|
|
- vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+ vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
|
|
else
|
|
- vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+ vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
|
|
+
|
|
+ R300_STATECHANGE(r300, vap_cntl);
|
|
|
|
- R300_STATECHANGE(rmesa, vap_cntl);
|
|
- reg_start(R300_VAP_CNTL, 0);
|
|
- e32(vap_cntl);
|
|
+ BEGIN_BATCH(2);
|
|
+ OUT_BATCH_REGVAL(R300_VAP_CNTL, vap_cntl);
|
|
+ END_BATCH();
|
|
|
|
if (has_tcl) {
|
|
+ struct r300_state_atom vpu;
|
|
+ uint32_t _cmd[10];
|
|
R300_STATECHANGE(r300, pvs);
|
|
- reg_start(R300_VAP_PVS_CODE_CNTL_0, 2);
|
|
-
|
|
- e32((0 << R300_PVS_FIRST_INST_SHIFT) |
|
|
- (0 << R300_PVS_XYZW_VALID_INST_SHIFT) |
|
|
- (1 << R300_PVS_LAST_INST_SHIFT));
|
|
- e32((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
|
|
- (0 << R300_PVS_MAX_CONST_ADDR_SHIFT));
|
|
- e32(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
|
|
-
|
|
R300_STATECHANGE(r300, vpi);
|
|
- vsf_start_fragment(0x0, 8);
|
|
|
|
- e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 0, 0xf, PVS_DST_REG_OUT));
|
|
- e32(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));
|
|
- e32(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));
|
|
- e32(0x0);
|
|
-
|
|
- e32(PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, PVS_DST_REG_OUT));
|
|
- e32(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));
|
|
- e32(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));
|
|
- e32(0x0);
|
|
+ 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) |
|
|
+ (1 << R300_PVS_LAST_INST_SHIFT));
|
|
+ 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);
|
|
+ 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);
|
|
}
|
|
}
|
|
|
|
@@ -468,9 +539,11 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
|
|
{
|
|
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
|
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
|
|
+ GLframebuffer *fb = dPriv->driverPrivate;
|
|
+ struct radeon_renderbuffer *rrb;
|
|
+ struct radeon_renderbuffer *rrbd;
|
|
int flags = 0;
|
|
int bits = 0;
|
|
- int swapped;
|
|
|
|
if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
fprintf(stderr, "r300Clear\n");
|
|
@@ -482,6 +555,12 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
|
|
return;
|
|
}
|
|
|
|
+ /* Flush swtcl vertices if necessary, because we will change hardware
|
|
+ * state during clear. See also the state-related comment in
|
|
+ * r300EmitClearState.
|
|
+ */
|
|
+ R300_NEWPRIM(r300);
|
|
+
|
|
if (mask & BUFFER_BIT_FRONT_LEFT) {
|
|
flags |= BUFFER_BIT_FRONT_LEFT;
|
|
mask &= ~BUFFER_BIT_FRONT_LEFT;
|
|
@@ -509,26 +588,28 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
|
|
_swrast_Clear(ctx, mask);
|
|
}
|
|
|
|
- swapped = r300->radeon.sarea->pfCurrentPage == 1;
|
|
-
|
|
/* Make sure it fits there. */
|
|
r300EnsureCmdBufSpace(r300, 421 * 3, __FUNCTION__);
|
|
if (flags || bits)
|
|
r300EmitClearState(ctx);
|
|
+ rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
|
|
|
|
if (flags & BUFFER_BIT_FRONT_LEFT) {
|
|
- r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped);
|
|
+ rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
|
+ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
|
|
bits = 0;
|
|
}
|
|
|
|
if (flags & BUFFER_BIT_BACK_LEFT) {
|
|
- r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, swapped ^ 1);
|
|
+ rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
|
|
+ r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
|
|
bits = 0;
|
|
}
|
|
|
|
if (bits)
|
|
- r300ClearBuffer(r300, bits, 0);
|
|
+ r300ClearBuffer(r300, bits, NULL, rrbd);
|
|
|
|
+ COMMIT_BATCH();
|
|
}
|
|
|
|
void r300Flush(GLcontext * ctx)
|
|
@@ -538,302 +619,13 @@ void r300Flush(GLcontext * ctx)
|
|
if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
|
|
- if (rmesa->dma.flush)
|
|
- rmesa->dma.flush( rmesa );
|
|
-
|
|
- if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit)
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
-}
|
|
-
|
|
-#ifdef USER_BUFFERS
|
|
-#include "r300_mem.h"
|
|
-
|
|
-void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
|
|
-{
|
|
- struct r300_dma_buffer *dmabuf;
|
|
- size = MAX2(size, RADEON_BUFFER_SIZE * 16);
|
|
-
|
|
- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
|
- fprintf(stderr, "%s\n", __FUNCTION__);
|
|
-
|
|
- if (rmesa->dma.flush) {
|
|
- rmesa->dma.flush(rmesa);
|
|
- }
|
|
-
|
|
- if (rmesa->dma.current.buf) {
|
|
-#ifdef USER_BUFFERS
|
|
- r300_mem_use(rmesa, rmesa->dma.current.buf->id);
|
|
-#endif
|
|
- r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
|
|
- }
|
|
- if (rmesa->dma.nr_released_bufs > 4)
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
-
|
|
- dmabuf = CALLOC_STRUCT(r300_dma_buffer);
|
|
- dmabuf->buf = (void *)1; /* hack */
|
|
- dmabuf->refcount = 1;
|
|
-
|
|
- dmabuf->id = r300_mem_alloc(rmesa, 4, size);
|
|
- if (dmabuf->id == 0) {
|
|
- LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
|
|
-
|
|
- r300FlushCmdBufLocked(rmesa, __FUNCTION__);
|
|
- radeonWaitForIdleLocked(&rmesa->radeon);
|
|
-
|
|
- dmabuf->id = r300_mem_alloc(rmesa, 4, size);
|
|
-
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
-
|
|
- if (dmabuf->id == 0) {
|
|
- fprintf(stderr,
|
|
- "Error: Could not get dma buffer... exiting\n");
|
|
- _mesa_exit(-1);
|
|
- }
|
|
- }
|
|
-
|
|
- rmesa->dma.current.buf = dmabuf;
|
|
- rmesa->dma.current.address = r300_mem_ptr(rmesa, dmabuf->id);
|
|
- rmesa->dma.current.end = size;
|
|
- rmesa->dma.current.start = 0;
|
|
- rmesa->dma.current.ptr = 0;
|
|
-}
|
|
-
|
|
-void r300ReleaseDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region, const char *caller)
|
|
-{
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
|
|
-
|
|
- if (!region->buf)
|
|
- return;
|
|
-
|
|
- if (rmesa->dma.flush)
|
|
- rmesa->dma.flush(rmesa);
|
|
-
|
|
- if (--region->buf->refcount == 0) {
|
|
- r300_mem_free(rmesa, region->buf->id);
|
|
- FREE(region->buf);
|
|
- rmesa->dma.nr_released_bufs++;
|
|
- }
|
|
-
|
|
- region->buf = 0;
|
|
- region->start = 0;
|
|
-}
|
|
-
|
|
-/* 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 r300AllocDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region,
|
|
- int bytes, int alignment)
|
|
-{
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
|
|
-
|
|
- if (rmesa->dma.flush)
|
|
- rmesa->dma.flush(rmesa);
|
|
-
|
|
- if (region->buf)
|
|
- r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
|
|
-
|
|
- alignment--;
|
|
- rmesa->dma.current.start = rmesa->dma.current.ptr =
|
|
- (rmesa->dma.current.ptr + alignment) & ~alignment;
|
|
-
|
|
- if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
|
|
- r300RefillCurrentDmaRegion(rmesa, (bytes + 0x7) & ~0x7);
|
|
-
|
|
- region->start = rmesa->dma.current.start;
|
|
- region->ptr = rmesa->dma.current.start;
|
|
- region->end = rmesa->dma.current.start + bytes;
|
|
- region->address = rmesa->dma.current.address;
|
|
- region->buf = rmesa->dma.current.buf;
|
|
- region->buf->refcount++;
|
|
-
|
|
- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
|
|
- rmesa->dma.current.start =
|
|
- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
|
|
-
|
|
- assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
|
|
-}
|
|
-
|
|
-#else
|
|
-static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
|
|
-{
|
|
- struct r300_dma_buffer *dmabuf;
|
|
- int fd = rmesa->radeon.dri.fd;
|
|
- int index = 0;
|
|
- int size = 0;
|
|
- drmDMAReq dma;
|
|
- int ret;
|
|
-
|
|
- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
|
- fprintf(stderr, "%s\n", __FUNCTION__);
|
|
-
|
|
- if (rmesa->dma.flush) {
|
|
- rmesa->dma.flush(rmesa);
|
|
- }
|
|
+ if (rmesa->swtcl.flush) {
|
|
+ rmesa->swtcl.flush(rmesa);
|
|
+ }
|
|
|
|
- if (rmesa->dma.current.buf)
|
|
- r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
|
|
-
|
|
- if (rmesa->dma.nr_released_bufs > 4)
|
|
+ if (rmesa->cmdbuf.cs->cdw) {
|
|
r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
-
|
|
- dma.context = rmesa->radeon.dri.hwContext;
|
|
- dma.send_count = 0;
|
|
- dma.send_list = NULL;
|
|
- dma.send_sizes = NULL;
|
|
- dma.flags = 0;
|
|
- dma.request_count = 1;
|
|
- dma.request_size = RADEON_BUFFER_SIZE;
|
|
- dma.request_list = &index;
|
|
- dma.request_sizes = &size;
|
|
- dma.granted_count = 0;
|
|
-
|
|
- LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */
|
|
-
|
|
- ret = drmDMA(fd, &dma);
|
|
-
|
|
- if (ret != 0) {
|
|
- /* Try to release some buffers and wait until we can't get any more */
|
|
- if (rmesa->dma.nr_released_bufs) {
|
|
- r300FlushCmdBufLocked(rmesa, __FUNCTION__);
|
|
- }
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_DMA)
|
|
- fprintf(stderr, "Waiting for buffers\n");
|
|
-
|
|
- radeonWaitForIdleLocked(&rmesa->radeon);
|
|
- ret = drmDMA(fd, &dma);
|
|
-
|
|
- if (ret != 0) {
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
- fprintf(stderr,
|
|
- "Error: Could not get dma buffer... exiting\n");
|
|
- _mesa_exit(-1);
|
|
- }
|
|
- }
|
|
-
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_DMA)
|
|
- fprintf(stderr, "Allocated buffer %d\n", index);
|
|
-
|
|
- dmabuf = CALLOC_STRUCT(r300_dma_buffer);
|
|
- dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
|
|
- dmabuf->refcount = 1;
|
|
-
|
|
- rmesa->dma.current.buf = dmabuf;
|
|
- rmesa->dma.current.address = dmabuf->buf->address;
|
|
- rmesa->dma.current.end = dmabuf->buf->total;
|
|
- rmesa->dma.current.start = 0;
|
|
- rmesa->dma.current.ptr = 0;
|
|
-}
|
|
-
|
|
-void r300ReleaseDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region, const char *caller)
|
|
-{
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
|
|
-
|
|
- if (!region->buf)
|
|
- return;
|
|
-
|
|
- if (rmesa->dma.flush)
|
|
- rmesa->dma.flush(rmesa);
|
|
-
|
|
- if (--region->buf->refcount == 0) {
|
|
- drm_radeon_cmd_header_t *cmd;
|
|
-
|
|
- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
|
- fprintf(stderr, "%s -- DISCARD BUF %d\n",
|
|
- __FUNCTION__, region->buf->buf->idx);
|
|
- cmd =
|
|
- (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
|
|
- sizeof
|
|
- (*cmd) / 4,
|
|
- __FUNCTION__);
|
|
- cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
|
|
- cmd->dma.buf_idx = region->buf->buf->idx;
|
|
-
|
|
- FREE(region->buf);
|
|
- rmesa->dma.nr_released_bufs++;
|
|
}
|
|
-
|
|
- region->buf = 0;
|
|
- region->start = 0;
|
|
-}
|
|
-
|
|
-/* 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 r300AllocDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region,
|
|
- int bytes, int alignment)
|
|
-{
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
|
|
-
|
|
- if (rmesa->dma.flush)
|
|
- rmesa->dma.flush(rmesa);
|
|
-
|
|
- if (region->buf)
|
|
- r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
|
|
-
|
|
- alignment--;
|
|
- rmesa->dma.current.start = rmesa->dma.current.ptr =
|
|
- (rmesa->dma.current.ptr + alignment) & ~alignment;
|
|
-
|
|
- if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
|
|
- r300RefillCurrentDmaRegion(rmesa);
|
|
-
|
|
- region->start = rmesa->dma.current.start;
|
|
- region->ptr = rmesa->dma.current.start;
|
|
- region->end = rmesa->dma.current.start + bytes;
|
|
- region->address = rmesa->dma.current.address;
|
|
- region->buf = rmesa->dma.current.buf;
|
|
- region->buf->refcount++;
|
|
-
|
|
- rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
|
|
- rmesa->dma.current.start =
|
|
- rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
|
|
-
|
|
- assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
|
|
-}
|
|
-
|
|
-#endif
|
|
-
|
|
-GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
|
|
- GLint size)
|
|
-{
|
|
- int offset =
|
|
- (char *)pointer -
|
|
- (char *)rmesa->radeon.radeonScreen->gartTextures.map;
|
|
- int valid = (size >= 0 && offset >= 0
|
|
- && offset + size <
|
|
- rmesa->radeon.radeonScreen->gartTextures.size);
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
|
|
- valid);
|
|
-
|
|
- return valid;
|
|
-}
|
|
-
|
|
-GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
|
|
-{
|
|
- int offset =
|
|
- (char *)pointer -
|
|
- (char *)rmesa->radeon.radeonScreen->gartTextures.map;
|
|
-
|
|
- //fprintf(stderr, "offset=%08x\n", offset);
|
|
-
|
|
- if (offset < 0
|
|
- || offset > rmesa->radeon.radeonScreen->gartTextures.size)
|
|
- return ~0;
|
|
- else
|
|
- return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
|
|
}
|
|
|
|
void r300InitIoctlFuncs(struct dd_function_table *functions)
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h
|
|
index e1143fb..5f00264 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_ioctl.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.h
|
|
@@ -39,20 +39,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_context.h"
|
|
#include "radeon_drm.h"
|
|
|
|
-extern GLboolean r300IsGartMemory(r300ContextPtr rmesa,
|
|
- const GLvoid * pointer, GLint size);
|
|
-
|
|
-extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa,
|
|
- const GLvoid * pointer);
|
|
-
|
|
extern void r300Flush(GLcontext * ctx);
|
|
|
|
-extern void r300ReleaseDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region,
|
|
- const char *caller);
|
|
extern void r300AllocDmaRegion(r300ContextPtr rmesa,
|
|
- struct r300_dma_region *region, int bytes,
|
|
- int alignment);
|
|
+ struct radeon_bo **pbo, int *poffset,
|
|
+ int bytes, int alignment);
|
|
|
|
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
|
|
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_mem.c b/src/mesa/drivers/dri/r300/r300_mem.c
|
|
deleted file mode 100644
|
|
index f8f9d4f..0000000
|
|
--- a/src/mesa/drivers/dri/r300/r300_mem.c
|
|
+++ /dev/null
|
|
@@ -1,385 +0,0 @@
|
|
-/*
|
|
- * Copyright (C) 2005 Aapo Tahkola.
|
|
- *
|
|
- * 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.
|
|
- *
|
|
- */
|
|
-
|
|
-/**
|
|
- * \file
|
|
- *
|
|
- * \author Aapo Tahkola <aet@rasterburn.org>
|
|
- */
|
|
-
|
|
-#include <unistd.h>
|
|
-
|
|
-#include "r300_context.h"
|
|
-#include "r300_cmdbuf.h"
|
|
-#include "r300_ioctl.h"
|
|
-#include "r300_mem.h"
|
|
-#include "radeon_ioctl.h"
|
|
-
|
|
-#ifdef USER_BUFFERS
|
|
-
|
|
-static void resize_u_list(r300ContextPtr rmesa)
|
|
-{
|
|
- void *temp;
|
|
- int nsize;
|
|
-
|
|
- temp = rmesa->rmm->u_list;
|
|
- nsize = rmesa->rmm->u_size * 2;
|
|
-
|
|
- rmesa->rmm->u_list = _mesa_malloc(nsize * sizeof(*rmesa->rmm->u_list));
|
|
- _mesa_memset(rmesa->rmm->u_list, 0,
|
|
- nsize * sizeof(*rmesa->rmm->u_list));
|
|
-
|
|
- if (temp) {
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
-
|
|
- _mesa_memcpy(rmesa->rmm->u_list, temp,
|
|
- rmesa->rmm->u_size * sizeof(*rmesa->rmm->u_list));
|
|
- _mesa_free(temp);
|
|
- }
|
|
-
|
|
- rmesa->rmm->u_size = nsize;
|
|
-}
|
|
-
|
|
-void r300_mem_init(r300ContextPtr rmesa)
|
|
-{
|
|
- rmesa->rmm = malloc(sizeof(struct r300_memory_manager));
|
|
- memset(rmesa->rmm, 0, sizeof(struct r300_memory_manager));
|
|
-
|
|
- rmesa->rmm->u_size = 128;
|
|
- resize_u_list(rmesa);
|
|
-}
|
|
-
|
|
-void r300_mem_destroy(r300ContextPtr rmesa)
|
|
-{
|
|
- _mesa_free(rmesa->rmm->u_list);
|
|
- rmesa->rmm->u_list = NULL;
|
|
-
|
|
- _mesa_free(rmesa->rmm);
|
|
- rmesa->rmm = NULL;
|
|
-}
|
|
-
|
|
-void *r300_mem_ptr(r300ContextPtr rmesa, int id)
|
|
-{
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
- return rmesa->rmm->u_list[id].ptr;
|
|
-}
|
|
-
|
|
-int r300_mem_find(r300ContextPtr rmesa, void *ptr)
|
|
-{
|
|
- int i;
|
|
-
|
|
- for (i = 1; i < rmesa->rmm->u_size + 1; i++)
|
|
- if (rmesa->rmm->u_list[i].ptr &&
|
|
- ptr >= rmesa->rmm->u_list[i].ptr &&
|
|
- ptr <
|
|
- rmesa->rmm->u_list[i].ptr + rmesa->rmm->u_list[i].size)
|
|
- break;
|
|
-
|
|
- if (i < rmesa->rmm->u_size + 1)
|
|
- return i;
|
|
-
|
|
- fprintf(stderr, "%p failed\n", ptr);
|
|
- return 0;
|
|
-}
|
|
-
|
|
-//#define MM_DEBUG
|
|
-int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size)
|
|
-{
|
|
- drm_radeon_mem_alloc_t alloc;
|
|
- int offset = 0, ret;
|
|
- int i, free = -1;
|
|
- int done_age;
|
|
- drm_radeon_mem_free_t memfree;
|
|
- int tries = 0;
|
|
- static int bytes_wasted = 0, allocated = 0;
|
|
-
|
|
- if (size < 4096)
|
|
- bytes_wasted += 4096 - size;
|
|
-
|
|
- allocated += size;
|
|
-
|
|
-#if 0
|
|
- static int t = 0;
|
|
- if (t != time(NULL)) {
|
|
- t = time(NULL);
|
|
- fprintf(stderr, "slots used %d, wasted %d kb, allocated %d\n",
|
|
- rmesa->rmm->u_last, bytes_wasted / 1024,
|
|
- allocated / 1024);
|
|
- }
|
|
-#endif
|
|
-
|
|
- memfree.region = RADEON_MEM_REGION_GART;
|
|
-
|
|
- again:
|
|
-
|
|
- done_age = radeonGetAge((radeonContextPtr) rmesa);
|
|
-
|
|
- if (rmesa->rmm->u_last + 1 >= rmesa->rmm->u_size)
|
|
- resize_u_list(rmesa);
|
|
-
|
|
- for (i = rmesa->rmm->u_last + 1; i > 0; i--) {
|
|
- if (rmesa->rmm->u_list[i].ptr == NULL) {
|
|
- free = i;
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (rmesa->rmm->u_list[i].h_pending == 0 &&
|
|
- rmesa->rmm->u_list[i].pending
|
|
- && rmesa->rmm->u_list[i].age <= done_age) {
|
|
- memfree.region_offset =
|
|
- (char *)rmesa->rmm->u_list[i].ptr -
|
|
- (char *)rmesa->radeon.radeonScreen->gartTextures.
|
|
- map;
|
|
-
|
|
- ret =
|
|
- drmCommandWrite(rmesa->radeon.radeonScreen->
|
|
- driScreen->fd, DRM_RADEON_FREE,
|
|
- &memfree, sizeof(memfree));
|
|
-
|
|
- if (ret) {
|
|
- fprintf(stderr, "Failed to free at %p\n",
|
|
- rmesa->rmm->u_list[i].ptr);
|
|
- fprintf(stderr, "ret = %s\n", strerror(-ret));
|
|
- exit(1);
|
|
- } else {
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "really freed %d at age %x\n",
|
|
- i,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
- if (i == rmesa->rmm->u_last)
|
|
- rmesa->rmm->u_last--;
|
|
-
|
|
- if (rmesa->rmm->u_list[i].size < 4096)
|
|
- bytes_wasted -=
|
|
- 4096 - rmesa->rmm->u_list[i].size;
|
|
-
|
|
- allocated -= rmesa->rmm->u_list[i].size;
|
|
- rmesa->rmm->u_list[i].pending = 0;
|
|
- rmesa->rmm->u_list[i].ptr = NULL;
|
|
- free = i;
|
|
- }
|
|
- }
|
|
- }
|
|
- rmesa->rmm->u_head = i;
|
|
-
|
|
- if (free == -1) {
|
|
- WARN_ONCE("Ran out of slots!\n");
|
|
- //usleep(100);
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
- tries++;
|
|
- if (tries > 100) {
|
|
- WARN_ONCE("Ran out of slots!\n");
|
|
- exit(1);
|
|
- }
|
|
- goto again;
|
|
- }
|
|
-
|
|
- alloc.region = RADEON_MEM_REGION_GART;
|
|
- alloc.alignment = alignment;
|
|
- alloc.size = size;
|
|
- alloc.region_offset = &offset;
|
|
-
|
|
- ret =
|
|
- drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc,
|
|
- sizeof(alloc));
|
|
- if (ret) {
|
|
-#if 0
|
|
- WARN_ONCE("Ran out of mem!\n");
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
- //usleep(100);
|
|
- tries2++;
|
|
- tries = 0;
|
|
- if (tries2 > 100) {
|
|
- WARN_ONCE("Ran out of GART memory!\n");
|
|
- exit(1);
|
|
- }
|
|
- goto again;
|
|
-#else
|
|
- WARN_ONCE
|
|
- ("Ran out of GART memory (for %d)!\nPlease consider adjusting GARTSize option.\n",
|
|
- size);
|
|
- return 0;
|
|
-#endif
|
|
- }
|
|
-
|
|
- i = free;
|
|
-
|
|
- if (i > rmesa->rmm->u_last)
|
|
- rmesa->rmm->u_last = i;
|
|
-
|
|
- rmesa->rmm->u_list[i].ptr =
|
|
- ((GLubyte *) rmesa->radeon.radeonScreen->gartTextures.map) + offset;
|
|
- rmesa->rmm->u_list[i].size = size;
|
|
- rmesa->rmm->u_list[i].age = 0;
|
|
- //fprintf(stderr, "alloc %p at id %d\n", rmesa->rmm->u_list[i].ptr, i);
|
|
-
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "allocated %d at age %x\n", i,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
-
|
|
- return i;
|
|
-}
|
|
-
|
|
-void r300_mem_use(r300ContextPtr rmesa, int id)
|
|
-{
|
|
- uint64_t ull;
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
- drm_r300_cmd_header_t *cmd;
|
|
-
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
-
|
|
- if (id == 0)
|
|
- return;
|
|
-
|
|
- cmd =
|
|
- (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa,
|
|
- 2 + sizeof(ull) / 4,
|
|
- __FUNCTION__);
|
|
- cmd[0].scratch.cmd_type = R300_CMD_SCRATCH;
|
|
- cmd[0].scratch.reg = R300_MEM_SCRATCH;
|
|
- cmd[0].scratch.n_bufs = 1;
|
|
- cmd[0].scratch.flags = 0;
|
|
- cmd++;
|
|
-
|
|
- ull = (uint64_t) (intptr_t) & rmesa->rmm->u_list[id].age;
|
|
- _mesa_memcpy(cmd, &ull, sizeof(ull));
|
|
- cmd += sizeof(ull) / 4;
|
|
-
|
|
- cmd[0].u = /*id */ 0;
|
|
-
|
|
- LOCK_HARDWARE(&rmesa->radeon); /* Protect from DRM. */
|
|
- rmesa->rmm->u_list[id].h_pending++;
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
-}
|
|
-
|
|
-unsigned long r300_mem_offset(r300ContextPtr rmesa, int id)
|
|
-{
|
|
- unsigned long offset;
|
|
-
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
-
|
|
- offset = (char *)rmesa->rmm->u_list[id].ptr -
|
|
- (char *)rmesa->radeon.radeonScreen->gartTextures.map;
|
|
- offset += rmesa->radeon.radeonScreen->gart_texture_offset;
|
|
-
|
|
- return offset;
|
|
-}
|
|
-
|
|
-void *r300_mem_map(r300ContextPtr rmesa, int id, int access)
|
|
-{
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
- void *ptr;
|
|
- int tries = 0;
|
|
-
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
-
|
|
- if (access == R300_MEM_R) {
|
|
-
|
|
- if (rmesa->rmm->u_list[id].mapped == 1)
|
|
- WARN_ONCE("buffer %d already mapped\n", id);
|
|
-
|
|
- rmesa->rmm->u_list[id].mapped = 1;
|
|
- ptr = r300_mem_ptr(rmesa, id);
|
|
-
|
|
- return ptr;
|
|
- }
|
|
-
|
|
- if (rmesa->rmm->u_list[id].h_pending)
|
|
- r300FlushCmdBuf(rmesa, __FUNCTION__);
|
|
-
|
|
- if (rmesa->rmm->u_list[id].h_pending) {
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- while (rmesa->rmm->u_list[id].age >
|
|
- radeonGetAge((radeonContextPtr) rmesa) && tries++ < 1000)
|
|
- usleep(10);
|
|
-
|
|
- if (tries >= 1000) {
|
|
- fprintf(stderr, "Idling failed (%x vs %x)\n",
|
|
- rmesa->rmm->u_list[id].age,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- if (rmesa->rmm->u_list[id].mapped == 1)
|
|
- WARN_ONCE("buffer %d already mapped\n", id);
|
|
-
|
|
- rmesa->rmm->u_list[id].mapped = 1;
|
|
- ptr = r300_mem_ptr(rmesa, id);
|
|
-
|
|
- return ptr;
|
|
-}
|
|
-
|
|
-void r300_mem_unmap(r300ContextPtr rmesa, int id)
|
|
-{
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
-
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
-
|
|
- if (rmesa->rmm->u_list[id].mapped == 0)
|
|
- WARN_ONCE("buffer %d not mapped\n", id);
|
|
-
|
|
- rmesa->rmm->u_list[id].mapped = 0;
|
|
-}
|
|
-
|
|
-void r300_mem_free(r300ContextPtr rmesa, int id)
|
|
-{
|
|
-#ifdef MM_DEBUG
|
|
- fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id,
|
|
- radeonGetAge((radeonContextPtr) rmesa));
|
|
-#endif
|
|
-
|
|
- assert(id <= rmesa->rmm->u_last);
|
|
-
|
|
- if (id == 0)
|
|
- return;
|
|
-
|
|
- if (rmesa->rmm->u_list[id].ptr == NULL) {
|
|
- WARN_ONCE("Not allocated!\n");
|
|
- return;
|
|
- }
|
|
-
|
|
- if (rmesa->rmm->u_list[id].pending) {
|
|
- WARN_ONCE("%p already pended!\n", rmesa->rmm->u_list[id].ptr);
|
|
- return;
|
|
- }
|
|
-
|
|
- rmesa->rmm->u_list[id].pending = 1;
|
|
-}
|
|
-#endif
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_mem.h b/src/mesa/drivers/dri/r300/r300_mem.h
|
|
deleted file mode 100644
|
|
index 625a7f6..0000000
|
|
--- a/src/mesa/drivers/dri/r300/r300_mem.h
|
|
+++ /dev/null
|
|
@@ -1,37 +0,0 @@
|
|
-#ifndef __R300_MEM_H__
|
|
-#define __R300_MEM_H__
|
|
-
|
|
-//#define R300_MEM_PDL 0
|
|
-#define R300_MEM_UL 1
|
|
-
|
|
-#define R300_MEM_R 1
|
|
-#define R300_MEM_W 2
|
|
-#define R300_MEM_RW (R300_MEM_R | R300_MEM_W)
|
|
-
|
|
-#define R300_MEM_SCRATCH 2
|
|
-
|
|
-struct r300_memory_manager {
|
|
- struct {
|
|
- void *ptr;
|
|
- uint32_t size;
|
|
- uint32_t age;
|
|
- uint32_t h_pending;
|
|
- int pending;
|
|
- int mapped;
|
|
- } *u_list;
|
|
- int u_head, u_size, u_last;
|
|
-
|
|
-};
|
|
-
|
|
-extern void r300_mem_init(r300ContextPtr rmesa);
|
|
-extern void r300_mem_destroy(r300ContextPtr rmesa);
|
|
-extern void *r300_mem_ptr(r300ContextPtr rmesa, int id);
|
|
-extern int r300_mem_find(r300ContextPtr rmesa, void *ptr);
|
|
-extern int r300_mem_alloc(r300ContextPtr rmesa, int alignment, int size);
|
|
-extern void r300_mem_use(r300ContextPtr rmesa, int id);
|
|
-extern unsigned long r300_mem_offset(r300ContextPtr rmesa, int id);
|
|
-extern void *r300_mem_map(r300ContextPtr rmesa, int id, int access);
|
|
-extern void r300_mem_unmap(r300ContextPtr rmesa, int id);
|
|
-extern void r300_mem_free(r300ContextPtr rmesa, int id);
|
|
-
|
|
-#endif
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c
|
|
new file mode 100644
|
|
index 0000000..097f9cd
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c
|
|
@@ -0,0 +1,319 @@
|
|
+/*
|
|
+ * Copyright (C) 2008 Nicolai Haehnle.
|
|
+ *
|
|
+ * 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 "r300_mipmap_tree.h"
|
|
+
|
|
+#include <errno.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include "main/simple_list.h"
|
|
+#include "main/texcompress.h"
|
|
+#include "main/texformat.h"
|
|
+
|
|
+#include "radeon_buffer.h"
|
|
+
|
|
+static GLuint r300_compressed_texture_size(GLcontext *ctx,
|
|
+ GLsizei width, GLsizei height, GLsizei depth,
|
|
+ GLuint mesaFormat)
|
|
+{
|
|
+ GLuint size = _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat);
|
|
+
|
|
+ if (mesaFormat == MESA_FORMAT_RGB_DXT1 ||
|
|
+ mesaFormat == MESA_FORMAT_RGBA_DXT1) {
|
|
+ if (width + 3 < 8) /* width one block */
|
|
+ size = size * 4;
|
|
+ else if (width + 3 < 16)
|
|
+ size = size * 2;
|
|
+ } else {
|
|
+ /* DXT3/5, 16 bytes per block */
|
|
+ WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
|
|
+ if (width + 3 < 8)
|
|
+ size = size * 2;
|
|
+ }
|
|
+
|
|
+ return size;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Compute sizes and fill in offset and blit information for the given
|
|
+ * image (determined by \p face and \p level).
|
|
+ *
|
|
+ * \param curOffset points to the offset at which the image is to be stored
|
|
+ * and is updated by this function according to the size of the image.
|
|
+ */
|
|
+static void compute_tex_image_offset(r300_mipmap_tree *mt,
|
|
+ GLuint face, GLuint level, GLuint* curOffset)
|
|
+{
|
|
+ r300_mipmap_level *lvl = &mt->levels[level];
|
|
+
|
|
+ /* Find image size in bytes */
|
|
+ if (mt->compressed) {
|
|
+ /* TODO: Is this correct? Need test cases for compressed textures! */
|
|
+ GLuint align;
|
|
+
|
|
+ if (mt->target == GL_TEXTURE_RECTANGLE_NV)
|
|
+ align = 64 / mt->bpp;
|
|
+ else
|
|
+ align = 32 / mt->bpp;
|
|
+ lvl->rowstride = (lvl->width + align - 1) & ~(align - 1);
|
|
+ lvl->size = r300_compressed_texture_size(mt->r300->radeon.glCtx,
|
|
+ lvl->width, lvl->height, lvl->depth, mt->compressed);
|
|
+ } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
|
|
+ lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
|
|
+ lvl->size = lvl->rowstride * lvl->height;
|
|
+ } else if (mt->tilebits & R300_TXO_MICRO_TILE) {
|
|
+ /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
|
+ * though the actual offset may be different (if texture is less than
|
|
+ * 32 bytes width) to the untiled case */
|
|
+ lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
|
|
+ lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
|
|
+ } else {
|
|
+ lvl->rowstride = (lvl->width * mt->bpp + 31) & ~31;
|
|
+ lvl->size = lvl->rowstride * lvl->height * lvl->depth;
|
|
+ }
|
|
+ assert(lvl->size > 0);
|
|
+
|
|
+ /* All images are aligned to a 32-byte offset */
|
|
+ *curOffset = (*curOffset + 0x1f) & ~0x1f;
|
|
+ lvl->faces[face].offset = *curOffset;
|
|
+ *curOffset += lvl->size;
|
|
+}
|
|
+
|
|
+static GLuint minify(GLuint size, GLuint levels)
|
|
+{
|
|
+ size = size >> levels;
|
|
+ if (size < 1)
|
|
+ size = 1;
|
|
+ return size;
|
|
+}
|
|
+
|
|
+static void calculate_miptree_layout(r300_mipmap_tree *mt)
|
|
+{
|
|
+ GLuint curOffset;
|
|
+ GLuint numLevels;
|
|
+ GLuint i;
|
|
+
|
|
+ numLevels = mt->lastLevel - mt->firstLevel + 1;
|
|
+ assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
|
|
+
|
|
+ curOffset = 0;
|
|
+ for(i = 0; i < numLevels; i++) {
|
|
+ GLuint face;
|
|
+
|
|
+ mt->levels[i].width = minify(mt->width0, i);
|
|
+ mt->levels[i].height = minify(mt->height0, i);
|
|
+ mt->levels[i].depth = minify(mt->depth0, i);
|
|
+
|
|
+ for(face = 0; face < mt->faces; face++)
|
|
+ compute_tex_image_offset(mt, face, i, &curOffset);
|
|
+ }
|
|
+
|
|
+ /* Note the required size in memory */
|
|
+ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Create a new mipmap tree, calculate its layout and allocate memory.
|
|
+ */
|
|
+r300_mipmap_tree* r300_miptree_create(r300ContextPtr rmesa, r300TexObj *t,
|
|
+ GLenum target, GLuint firstLevel, GLuint lastLevel,
|
|
+ GLuint width0, GLuint height0, GLuint depth0,
|
|
+ GLuint bpp, GLuint tilebits, GLuint compressed)
|
|
+{
|
|
+ r300_mipmap_tree *mt = CALLOC_STRUCT(_r300_mipmap_tree);
|
|
+
|
|
+ mt->r300 = rmesa;
|
|
+ mt->refcount = 1;
|
|
+ mt->t = t;
|
|
+ mt->target = target;
|
|
+ mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
|
+ mt->firstLevel = firstLevel;
|
|
+ mt->lastLevel = lastLevel;
|
|
+ mt->width0 = width0;
|
|
+ mt->height0 = height0;
|
|
+ mt->depth0 = depth0;
|
|
+ mt->bpp = bpp;
|
|
+ mt->tilebits = tilebits;
|
|
+ mt->compressed = compressed;
|
|
+
|
|
+ calculate_miptree_layout(mt);
|
|
+
|
|
+ mt->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
|
+ 0, mt->totalsize, 1024,
|
|
+ RADEON_GEM_DOMAIN_VRAM,
|
|
+ 0);
|
|
+
|
|
+ return mt;
|
|
+}
|
|
+
|
|
+void r300_miptree_reference(r300_mipmap_tree *mt)
|
|
+{
|
|
+ mt->refcount++;
|
|
+ assert(mt->refcount > 0);
|
|
+}
|
|
+
|
|
+void r300_miptree_unreference(r300_mipmap_tree *mt)
|
|
+{
|
|
+ if (!mt)
|
|
+ return;
|
|
+
|
|
+ assert(mt->refcount > 0);
|
|
+ mt->refcount--;
|
|
+ if (!mt->refcount) {
|
|
+ radeon_bo_unref(mt->bo);
|
|
+ free(mt);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static void calculate_first_last_level(struct gl_texture_object *tObj,
|
|
+ GLuint *pfirstLevel, GLuint *plastLevel)
|
|
+{
|
|
+ const struct gl_texture_image * const baseImage =
|
|
+ tObj->Image[0][tObj->BaseLevel];
|
|
+
|
|
+ /* These must be signed values. MinLod and MaxLod can be negative numbers,
|
|
+ * and having firstLevel and lastLevel as signed prevents the need for
|
|
+ * extra sign checks.
|
|
+ */
|
|
+ int firstLevel;
|
|
+ int lastLevel;
|
|
+
|
|
+ /* Yes, this looks overly complicated, but it's all needed.
|
|
+ */
|
|
+ switch (tObj->Target) {
|
|
+ case GL_TEXTURE_1D:
|
|
+ case GL_TEXTURE_2D:
|
|
+ case GL_TEXTURE_3D:
|
|
+ case GL_TEXTURE_CUBE_MAP:
|
|
+ if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
|
|
+ /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
|
|
+ */
|
|
+ firstLevel = lastLevel = tObj->BaseLevel;
|
|
+ } else {
|
|
+ firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
|
|
+ firstLevel = MAX2(firstLevel, tObj->BaseLevel);
|
|
+ firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
|
|
+ lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
|
|
+ lastLevel = MAX2(lastLevel, tObj->BaseLevel);
|
|
+ lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
|
|
+ lastLevel = MIN2(lastLevel, tObj->MaxLevel);
|
|
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
|
|
+ }
|
|
+ break;
|
|
+ case GL_TEXTURE_RECTANGLE_NV:
|
|
+ case GL_TEXTURE_4D_SGIS:
|
|
+ firstLevel = lastLevel = 0;
|
|
+ break;
|
|
+ default:
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* save these values */
|
|
+ *pfirstLevel = firstLevel;
|
|
+ *plastLevel = lastLevel;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Checks whether the given miptree can hold the given texture image at the
|
|
+ * given face and level.
|
|
+ */
|
|
+GLboolean r300_miptree_matches_image(r300_mipmap_tree *mt,
|
|
+ struct gl_texture_image *texImage, GLuint face, GLuint level)
|
|
+{
|
|
+ r300_mipmap_level *lvl;
|
|
+
|
|
+ if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
|
|
+ return GL_FALSE;
|
|
+
|
|
+ if (texImage->TexFormat->TexelBytes != mt->bpp)
|
|
+ return GL_FALSE;
|
|
+
|
|
+ lvl = &mt->levels[level - mt->firstLevel];
|
|
+ if (lvl->width != texImage->Width ||
|
|
+ lvl->height != texImage->Height ||
|
|
+ lvl->depth != texImage->Depth)
|
|
+ return GL_FALSE;
|
|
+
|
|
+ return GL_TRUE;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Checks whether the given miptree has the right format to store the given texture object.
|
|
+ */
|
|
+GLboolean r300_miptree_matches_texture(r300_mipmap_tree *mt, struct gl_texture_object *texObj)
|
|
+{
|
|
+ struct gl_texture_image *firstImage;
|
|
+ GLuint compressed;
|
|
+ GLuint numfaces = 1;
|
|
+ GLuint firstLevel, lastLevel;
|
|
+
|
|
+ calculate_first_last_level(texObj, &firstLevel, &lastLevel);
|
|
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP)
|
|
+ numfaces = 6;
|
|
+
|
|
+ firstImage = texObj->Image[0][firstLevel];
|
|
+ compressed = firstImage->IsCompressed ? firstImage->TexFormat->MesaFormat : 0;
|
|
+
|
|
+ return (mt->firstLevel == firstLevel &&
|
|
+ mt->lastLevel == lastLevel &&
|
|
+ mt->width0 == firstImage->Width &&
|
|
+ mt->height0 == firstImage->Height &&
|
|
+ mt->depth0 == firstImage->Depth &&
|
|
+ mt->bpp == firstImage->TexFormat->TexelBytes &&
|
|
+ mt->compressed == compressed);
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * Try to allocate a mipmap tree for the given texture that will fit the
|
|
+ * given image in the given position.
|
|
+ */
|
|
+void r300_try_alloc_miptree(r300ContextPtr rmesa, r300TexObj *t,
|
|
+ struct gl_texture_image *texImage, GLuint face, GLuint level)
|
|
+{
|
|
+ GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0;
|
|
+ GLuint numfaces = 1;
|
|
+ GLuint firstLevel, lastLevel;
|
|
+
|
|
+ assert(!t->mt);
|
|
+
|
|
+ calculate_first_last_level(&t->base, &firstLevel, &lastLevel);
|
|
+ if (t->base.Target == GL_TEXTURE_CUBE_MAP)
|
|
+ numfaces = 6;
|
|
+
|
|
+ if (level != firstLevel || face >= numfaces)
|
|
+ return;
|
|
+
|
|
+ t->mt = r300_miptree_create(rmesa, t, t->base.Target,
|
|
+ firstLevel, lastLevel,
|
|
+ texImage->Width, texImage->Height, texImage->Depth,
|
|
+ texImage->TexFormat->TexelBytes, t->tile_bits, compressed);
|
|
+}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.h b/src/mesa/drivers/dri/r300/r300_mipmap_tree.h
|
|
new file mode 100644
|
|
index 0000000..aeb52dc
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/r300/r300_mipmap_tree.h
|
|
@@ -0,0 +1,97 @@
|
|
+/*
|
|
+ * Copyright (C) 2008 Nicolai Haehnle.
|
|
+ *
|
|
+ * 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.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __R300_MIPMAP_TREE_H_
|
|
+#define __R300_MIPMAP_TREE_H_
|
|
+
|
|
+#include "r300_context.h"
|
|
+
|
|
+typedef struct _r300_mipmap_tree r300_mipmap_tree;
|
|
+typedef struct _r300_mipmap_level r300_mipmap_level;
|
|
+typedef struct _r300_mipmap_image r300_mipmap_image;
|
|
+
|
|
+struct _r300_mipmap_image {
|
|
+ GLuint offset; /** Offset of this image from the start of mipmap tree buffer, in bytes */
|
|
+};
|
|
+
|
|
+struct _r300_mipmap_level {
|
|
+ GLuint width;
|
|
+ GLuint height;
|
|
+ GLuint depth;
|
|
+ GLuint size; /** Size of each image, in bytes */
|
|
+ GLuint rowstride; /** in bytes */
|
|
+ r300_mipmap_image faces[6];
|
|
+};
|
|
+
|
|
+
|
|
+/**
|
|
+ * A mipmap tree contains texture images in the layout that the hardware
|
|
+ * expects.
|
|
+ *
|
|
+ * The meta-data of mipmap trees is immutable, i.e. you cannot change the
|
|
+ * layout on-the-fly; however, the texture contents (i.e. texels) can be
|
|
+ * changed.
|
|
+ */
|
|
+struct _r300_mipmap_tree {
|
|
+ r300ContextPtr r300;
|
|
+ r300TexObj *t;
|
|
+ struct radeon_bo *bo;
|
|
+ GLuint refcount;
|
|
+
|
|
+ GLuint totalsize; /** total size of the miptree, in bytes */
|
|
+
|
|
+ GLenum target; /** GL_TEXTURE_xxx */
|
|
+ GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */
|
|
+ GLuint firstLevel; /** First mip level stored in this mipmap tree */
|
|
+ GLuint lastLevel; /** Last mip level stored in this mipmap tree */
|
|
+
|
|
+ GLuint width0; /** Width of firstLevel image */
|
|
+ GLuint height0; /** Height of firstLevel image */
|
|
+ GLuint depth0; /** Depth of firstLevel image */
|
|
+
|
|
+ GLuint bpp; /** Bytes per texel */
|
|
+ GLuint tilebits; /** R300_TXO_xxx_TILE */
|
|
+ GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */
|
|
+
|
|
+ r300_mipmap_level levels[RADEON_MAX_TEXTURE_LEVELS];
|
|
+};
|
|
+
|
|
+r300_mipmap_tree* r300_miptree_create(r300ContextPtr rmesa, r300TexObj *t,
|
|
+ GLenum target, GLuint firstLevel, GLuint lastLevel,
|
|
+ GLuint width0, GLuint height0, GLuint depth0,
|
|
+ GLuint bpp, GLuint tilebits, GLuint compressed);
|
|
+void r300_miptree_reference(r300_mipmap_tree *mt);
|
|
+void r300_miptree_unreference(r300_mipmap_tree *mt);
|
|
+
|
|
+GLboolean r300_miptree_matches_image(r300_mipmap_tree *mt,
|
|
+ struct gl_texture_image *texImage, GLuint face, GLuint level);
|
|
+GLboolean r300_miptree_matches_texture(r300_mipmap_tree *mt, struct gl_texture_object *texObj);
|
|
+void r300_try_alloc_miptree(r300ContextPtr rmesa, r300TexObj *t,
|
|
+ struct gl_texture_image *texImage, GLuint face, GLuint level);
|
|
+
|
|
+
|
|
+#endif /* __R300_MIPMAP_TREE_H_ */
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
|
|
index 778db96..8b3fe43 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_reg.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
|
|
@@ -1525,6 +1525,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
# define R500_SEL_FILTER4_TC3 (3 << 18)
|
|
|
|
#define R300_TX_OFFSET_0 0x4540
|
|
+#define R300_TX_OFFSET_1 0x4544
|
|
+#define R300_TX_OFFSET_2 0x4548
|
|
+#define R300_TX_OFFSET_3 0x454C
|
|
+#define R300_TX_OFFSET_4 0x4550
|
|
+#define R300_TX_OFFSET_5 0x4554
|
|
+#define R300_TX_OFFSET_6 0x4558
|
|
+#define R300_TX_OFFSET_7 0x455C
|
|
/* BEGIN: Guess from R200 */
|
|
# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
|
|
# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
|
|
index 292f87a..ccc00b3 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_render.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_render.c
|
|
@@ -175,89 +175,163 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
|
|
static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct r300_dma_region *rvb = &rmesa->state.elt_dma;
|
|
void *out;
|
|
|
|
- if (r300IsGartMemory(rmesa, elts, n_elts * 4)) {
|
|
- rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
|
|
- rvb->start = ((char *)elts) - rvb->address;
|
|
- rvb->aos_offset =
|
|
- rmesa->radeon.radeonScreen->gart_texture_offset +
|
|
- rvb->start;
|
|
- return;
|
|
- } else if (r300IsGartMemory(rmesa, elts, 1)) {
|
|
- WARN_ONCE("Pointer not within GART memory!\n");
|
|
- _mesa_exit(-1);
|
|
- }
|
|
-
|
|
- r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4);
|
|
- rvb->aos_offset = GET_START(rvb);
|
|
-
|
|
- out = rvb->address + rvb->start;
|
|
+ rmesa->state.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
|
+ 0, n_elts * 4, 4,
|
|
+ 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;
|
|
memcpy(out, elts, n_elts * 4);
|
|
+ radeon_bo_unmap(rmesa->state.elt_dma_bo);
|
|
}
|
|
|
|
-static void r300FireEB(r300ContextPtr rmesa, unsigned long addr,
|
|
- int vertex_count, int type)
|
|
+static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type)
|
|
{
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
-
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0);
|
|
- e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
|
|
-
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2);
|
|
- e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
|
|
- e32(addr);
|
|
- e32(vertex_count);
|
|
+ BATCH_LOCALS(rmesa);
|
|
+
|
|
+ if (vertex_count > 0) {
|
|
+ BEGIN_BATCH(8);
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0);
|
|
+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
|
|
+ ((vertex_count + 0) << 16) |
|
|
+ type |
|
|
+ R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
|
|
+
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
|
|
+ OUT_BATCH(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
|
|
+ OUT_BATCH_RELOC(rmesa->state.elt_dma_offset,
|
|
+ rmesa->state.elt_dma_bo,
|
|
+ rmesa->state.elt_dma_offset,
|
|
+ RADEON_GEM_DOMAIN_GTT, 0, 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,
|
|
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
|
|
+ }
|
|
+ END_BATCH();
|
|
+ }
|
|
}
|
|
|
|
static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
|
|
{
|
|
+ BATCH_LOCALS(rmesa);
|
|
+ uint32_t voffset;
|
|
int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
|
|
int i;
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
|
|
if (RADEON_DEBUG & DEBUG_VERTS)
|
|
fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
|
|
offset);
|
|
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1), sz - 1);
|
|
- e32(nr);
|
|
+ BEGIN_BATCH(sz+2);
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1);
|
|
+ OUT_BATCH(nr);
|
|
|
|
+
|
|
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
|
|
for (i = 0; i + 1 < nr; i += 2) {
|
|
- e32((rmesa->state.aos[i].aos_size << 0) |
|
|
- (rmesa->state.aos[i].aos_stride << 8) |
|
|
- (rmesa->state.aos[i + 1].aos_size << 16) |
|
|
- (rmesa->state.aos[i + 1].aos_stride << 24));
|
|
+ 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_RELOC(voffset,
|
|
+ rmesa->state.aos[i].bo,
|
|
+ voffset,
|
|
+ RADEON_GEM_DOMAIN_GTT,
|
|
+ 0, 0);
|
|
+ voffset = rmesa->state.aos[i + 1].offset +
|
|
+ offset * 4 * rmesa->state.aos[i + 1].stride;
|
|
+ OUT_BATCH_RELOC(voffset,
|
|
+ rmesa->state.aos[i+1].bo,
|
|
+ voffset,
|
|
+ RADEON_GEM_DOMAIN_GTT,
|
|
+ 0, 0);
|
|
+ }
|
|
|
|
- e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride);
|
|
- e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride);
|
|
+ if (nr & 1) {
|
|
+ OUT_BATCH((rmesa->state.aos[nr - 1].components << 0) |
|
|
+ (rmesa->state.aos[nr - 1].stride << 8));
|
|
+ voffset = rmesa->state.aos[nr - 1].offset +
|
|
+ offset * 4 * rmesa->state.aos[nr - 1].stride;
|
|
+ OUT_BATCH_RELOC(voffset,
|
|
+ rmesa->state.aos[nr - 1].bo,
|
|
+ voffset,
|
|
+ RADEON_GEM_DOMAIN_GTT,
|
|
+ 0, 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) {
|
|
- e32((rmesa->state.aos[nr - 1].aos_size << 0) |
|
|
- (rmesa->state.aos[nr - 1].aos_stride << 8));
|
|
- e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride);
|
|
+ OUT_BATCH((rmesa->state.aos[nr - 1].components << 0) |
|
|
+ (rmesa->state.aos[nr - 1].stride << 8));
|
|
+ voffset = rmesa->state.aos[nr - 1].offset +
|
|
+ offset * 4 * rmesa->state.aos[nr - 1].stride;
|
|
+ OUT_BATCH(voffset);
|
|
+ }
|
|
+ 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,
|
|
+ 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,
|
|
+ rmesa->state.aos[i+1].bo,
|
|
+ RADEON_GEM_DOMAIN_GTT,
|
|
+ 0, 0);
|
|
+ }
|
|
+ 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,
|
|
+ rmesa->state.aos[nr-1].bo,
|
|
+ RADEON_GEM_DOMAIN_GTT,
|
|
+ 0, 0);
|
|
}
|
|
+ }
|
|
+ END_BATCH();
|
|
}
|
|
|
|
static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type)
|
|
{
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
+ BATCH_LOCALS(rmesa);
|
|
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
|
|
- e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
|
|
+ BEGIN_BATCH(3);
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
|
|
+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
|
|
+ END_BATCH();
|
|
}
|
|
|
|
static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
|
|
int start, int end, int prim)
|
|
{
|
|
+ BATCH_LOCALS(rmesa);
|
|
int type, num_verts;
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
struct vertex_buffer *vb = &tnl->vb;
|
|
@@ -268,6 +342,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
|
|
if (type < 0 || num_verts <= 0)
|
|
return;
|
|
|
|
+ /* Make space for at least 64 dwords.
|
|
+ * This is supposed to ensure that we can get all rendering
|
|
+ * commands into a single command buffer.
|
|
+ */
|
|
+ r300EnsureCmdBufSpace(rmesa, 64, __FUNCTION__);
|
|
+
|
|
if (vb->Elts) {
|
|
if (num_verts > 65535) {
|
|
/* not implemented yet */
|
|
@@ -287,11 +367,12 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
|
|
*/
|
|
r300EmitElts(ctx, vb->Elts, num_verts);
|
|
r300EmitAOS(rmesa, rmesa->state.aos_count, start);
|
|
- r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type);
|
|
+ r300FireEB(rmesa, num_verts, type);
|
|
} else {
|
|
r300EmitAOS(rmesa, rmesa->state.aos_count, start);
|
|
r300FireAOS(rmesa, num_verts, type);
|
|
}
|
|
+ COMMIT_BATCH();
|
|
}
|
|
|
|
static GLboolean r300RunRender(GLcontext * ctx,
|
|
@@ -302,7 +383,6 @@ static GLboolean r300RunRender(GLcontext * ctx,
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
struct vertex_buffer *vb = &tnl->vb;
|
|
|
|
-
|
|
if (RADEON_DEBUG & DEBUG_PRIMS)
|
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
|
|
@@ -324,10 +404,6 @@ static GLboolean r300RunRender(GLcontext * ctx,
|
|
|
|
r300EmitCacheFlush(rmesa);
|
|
|
|
-#ifdef USER_BUFFERS
|
|
- r300UseArrays(ctx);
|
|
-#endif
|
|
-
|
|
r300ReleaseArrays(ctx);
|
|
|
|
return GL_FALSE;
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
|
|
index 6a5c363..c79e69a 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_state.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_state.c
|
|
@@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
#include "radeon_ioctl.h"
|
|
#include "radeon_state.h"
|
|
+#include "radeon_buffer.h"
|
|
#include "r300_context.h"
|
|
#include "r300_ioctl.h"
|
|
#include "r300_state.h"
|
|
@@ -1100,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);
|
|
}
|
|
|
|
@@ -1144,55 +1154,25 @@ void r300UpdateViewportOffset(GLcontext * ctx)
|
|
void r300UpdateDrawBuffer(GLcontext * ctx)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- r300ContextPtr r300 = rmesa;
|
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
|
- driRenderbuffer *drb;
|
|
+ struct radeon_renderbuffer *rrb;
|
|
|
|
if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
|
|
/* draw to front */
|
|
- drb =
|
|
- (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].
|
|
- Renderbuffer;
|
|
+ rrb =
|
|
+ (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
|
} else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
|
|
/* draw to back */
|
|
- drb =
|
|
- (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].
|
|
- Renderbuffer;
|
|
+ rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
|
|
} else {
|
|
/* drawing to multiple buffers, or none */
|
|
return;
|
|
}
|
|
|
|
- assert(drb);
|
|
- assert(drb->flippedPitch);
|
|
+ assert(rrb);
|
|
+ assert(rrb->pitch);
|
|
|
|
R300_STATECHANGE(rmesa, cb);
|
|
-
|
|
- r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset +
|
|
- r300->radeon.radeonScreen->fbLocation;
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch; //r300->radeon.state.color.drawPitch;
|
|
-
|
|
- if (r300->radeon.radeonScreen->cpp == 4)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
|
|
- else
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
|
|
-
|
|
- if (r300->radeon.sarea->tiling_enabled)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
|
|
-#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
|
|
@@ -1412,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)
|
|
@@ -1497,14 +1478,9 @@ static void r300SetupTextures(GLcontext * ctx)
|
|
/* We cannot let disabled tmu offsets pass DRM */
|
|
for (i = 0; i < mtu; i++) {
|
|
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
|
-
|
|
-#if 0 /* Enables old behaviour */
|
|
- hw_tmu = i;
|
|
-#endif
|
|
tmu_mappings[i] = hw_tmu;
|
|
|
|
- t = r300->state.texture.unit[i].texobj;
|
|
- /* XXX questionable fix for bug 9170: */
|
|
+ t = r300_tex_obj(ctx->Texture.Unit[i]._Current);
|
|
if (!t)
|
|
continue;
|
|
|
|
@@ -1530,21 +1506,20 @@ static void r300SetupTextures(GLcontext * ctx)
|
|
*/
|
|
r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] =
|
|
t->filter_1 |
|
|
- translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.tObj->LodBias);
|
|
+ translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.LodBias);
|
|
r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] =
|
|
t->size;
|
|
r300->hw.tex.format.cmd[R300_TEX_VALUE_0 +
|
|
hw_tmu] = t->format;
|
|
r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] =
|
|
t->pitch_reg;
|
|
- r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 +
|
|
- hw_tmu] = t->offset;
|
|
+ r300->hw.textures[hw_tmu] = t;
|
|
|
|
- if (t->offset & R300_TXO_MACRO_TILE) {
|
|
+ if (t->tile_bits & R300_TXO_MACRO_TILE) {
|
|
WARN_ONCE("macro tiling enabled!\n");
|
|
}
|
|
|
|
- if (t->offset & R300_TXO_MICRO_TILE) {
|
|
+ if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
|
WARN_ONCE("micro tiling enabled!\n");
|
|
}
|
|
|
|
@@ -1561,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;
|
|
@@ -1587,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
|
|
@@ -1749,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)
|
|
@@ -1909,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)
|
|
@@ -2107,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;
|
|
@@ -2193,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))
|
|
@@ -2223,8 +2200,6 @@ static void r300ResetHwState(r300ContextPtr r300)
|
|
|
|
r300UpdateCulling(ctx);
|
|
|
|
- r300UpdateTextureState(ctx);
|
|
-
|
|
r300SetBlendState(ctx);
|
|
r300SetLogicOpState(ctx);
|
|
|
|
@@ -2371,20 +2346,6 @@ static void r300ResetHwState(r300ContextPtr r300)
|
|
|
|
r300BlendColor(ctx, ctx->Color.BlendColor);
|
|
|
|
- /* Again, r300ClearBuffer uses this */
|
|
- r300->hw.cb.cmd[R300_CB_OFFSET] =
|
|
- r300->radeon.state.color.drawOffset +
|
|
- r300->radeon.radeonScreen->fbLocation;
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
|
|
-
|
|
- if (r300->radeon.radeonScreen->cpp == 4)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
|
|
- else
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
|
|
-
|
|
- if (r300->radeon.sarea->tiling_enabled)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
|
|
-
|
|
r300->hw.rb3d_dither_ctl.cmd[1] = 0;
|
|
r300->hw.rb3d_dither_ctl.cmd[2] = 0;
|
|
r300->hw.rb3d_dither_ctl.cmd[3] = 0;
|
|
@@ -2400,12 +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;
|
|
|
|
- r300->hw.zb.cmd[R300_ZB_OFFSET] =
|
|
- r300->radeon.radeonScreen->depthOffset +
|
|
- r300->radeon.radeonScreen->fbLocation;
|
|
- r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
|
|
-
|
|
- 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;
|
|
|
|
@@ -2539,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;
|
|
@@ -2573,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]);
|
|
@@ -2675,7 +2632,7 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
|
|
GLcontext *ctx;
|
|
ctx = rmesa->radeon.glCtx;
|
|
|
|
- r300UpdateTextureState(ctx);
|
|
+ r300ValidateTextures(ctx);
|
|
r300SetEarlyZState(ctx);
|
|
|
|
GLuint fgdepthsrc = R300_FG_DEPTH_SRC_SCAN;
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h
|
|
index 0589ab7..4d0a25f 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_state.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_state.h
|
|
@@ -39,8 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
#define R300_NEWPRIM( rmesa ) \
|
|
do { \
|
|
- if ( rmesa->dma.flush ) \
|
|
- rmesa->dma.flush( rmesa ); \
|
|
} while (0)
|
|
|
|
#define R300_STATECHANGE(r300, atom) \
|
|
@@ -57,13 +55,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
TODO: This has not been implemented yet
|
|
*/
|
|
#define R300_FIREVERTICES( r300 ) \
|
|
-do { \
|
|
- \
|
|
- if ( (r300)->cmdbuf.count_used || (r300)->dma.flush ) { \
|
|
- r300Flush( (r300)->radeon.glCtx ); \
|
|
- } \
|
|
- \
|
|
-} while (0)
|
|
+ do { \
|
|
+ r300Flush( (r300)->radeon.glCtx ); \
|
|
+ } while (0)
|
|
|
|
// r300_state.c
|
|
extern int future_hw_tcl_on;
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
|
|
index b6e7ce1..fbfa8f4 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_swtcl.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
|
|
@@ -56,12 +56,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_state.h"
|
|
#include "r300_ioctl.h"
|
|
#include "r300_emit.h"
|
|
-#include "r300_mem.h"
|
|
|
|
static void flush_last_swtcl_prim( r300ContextPtr rmesa );
|
|
|
|
|
|
-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset);
|
|
+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset);
|
|
void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr);
|
|
#define EMIT_ATTR( ATTR, STYLE ) \
|
|
do { \
|
|
@@ -86,7 +85,6 @@ static void r300SetVertexFormat( GLcontext *ctx )
|
|
DECLARE_RENDERINPUTS(index_bitset);
|
|
GLuint InputsRead = 0, OutputsWritten = 0;
|
|
int vap_fmt_0 = 0;
|
|
- int vap_vte_cntl = 0;
|
|
int offset = 0;
|
|
int vte = 0;
|
|
GLint inputs[VERT_ATTRIB_MAX];
|
|
@@ -175,7 +173,7 @@ static void r300SetVertexFormat( GLcontext *ctx )
|
|
inputs[i] = -1;
|
|
}
|
|
}
|
|
-
|
|
+
|
|
/* Fixed, apply to vir0 only */
|
|
if (InputsRead & (1 << VERT_ATTRIB_POS))
|
|
inputs[VERT_ATTRIB_POS] = 0;
|
|
@@ -186,16 +184,16 @@ static void r300SetVertexFormat( GLcontext *ctx )
|
|
for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
|
|
if (InputsRead & (1 << i))
|
|
inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
|
|
-
|
|
+
|
|
for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
|
|
if (InputsRead & (1 << i)) {
|
|
tab[nr++] = i;
|
|
}
|
|
}
|
|
-
|
|
+
|
|
for (i = 0; i < nr; i++) {
|
|
int ci;
|
|
-
|
|
+
|
|
swizzle[i][0] = SWIZZLE_ZERO;
|
|
swizzle[i][1] = SWIZZLE_ZERO;
|
|
swizzle[i][2] = SWIZZLE_ZERO;
|
|
@@ -215,21 +213,21 @@ static void r300SetVertexFormat( 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);
|
|
-
|
|
+
|
|
R300_STATECHANGE(rmesa, vic);
|
|
rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
|
|
rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
|
|
-
|
|
+
|
|
R300_STATECHANGE(rmesa, vof);
|
|
rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
|
|
rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_fmt_1;
|
|
-
|
|
+
|
|
rmesa->swtcl.vertex_size =
|
|
_tnl_install_attrs( ctx,
|
|
- rmesa->swtcl.vertex_attrs,
|
|
+ rmesa->swtcl.vertex_attrs,
|
|
rmesa->swtcl.vertex_attr_count,
|
|
NULL, 0 );
|
|
-
|
|
+
|
|
rmesa->swtcl.vertex_size /= 4;
|
|
|
|
RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
|
|
@@ -247,37 +245,22 @@ static void flush_last_swtcl_prim( r300ContextPtr rmesa )
|
|
{
|
|
if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
-
|
|
- rmesa->dma.flush = NULL;
|
|
-
|
|
- if (rmesa->dma.current.buf) {
|
|
- struct r300_dma_region *current = &rmesa->dma.current;
|
|
- GLuint current_offset = GET_START(current);
|
|
-
|
|
- assert (current->start +
|
|
- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
|
|
- current->ptr);
|
|
-
|
|
- if (rmesa->dma.current.start != rmesa->dma.current.ptr) {
|
|
-
|
|
- r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__);
|
|
-
|
|
- r300EmitState(rmesa);
|
|
-
|
|
- r300EmitVertexAOS( rmesa,
|
|
- rmesa->swtcl.vertex_size,
|
|
- current_offset);
|
|
-
|
|
- r300EmitVbufPrim( rmesa,
|
|
- rmesa->swtcl.hw_primitive,
|
|
- rmesa->swtcl.numverts);
|
|
-
|
|
- r300EmitCacheFlush(rmesa);
|
|
- }
|
|
-
|
|
- rmesa->swtcl.numverts = 0;
|
|
- current->start = current->ptr;
|
|
- }
|
|
+ rmesa->swtcl.flush = NULL;
|
|
+ radeon_bo_unmap(rmesa->swtcl.bo);
|
|
+ r300EnsureCmdBufSpace(rmesa,
|
|
+ rmesa->hw.max_state_size + (12*sizeof(int)),
|
|
+ __FUNCTION__);
|
|
+ r300EmitState(rmesa);
|
|
+ r300EmitVertexAOS(rmesa,
|
|
+ rmesa->swtcl.vertex_size,
|
|
+ rmesa->swtcl.bo,
|
|
+ 0);
|
|
+ r300EmitVbufPrim(rmesa,
|
|
+ rmesa->swtcl.hw_primitive,
|
|
+ rmesa->swtcl.numverts);
|
|
+ r300EmitCacheFlush(rmesa);
|
|
+ COMMIT_BATCH();
|
|
+ rmesa->swtcl.numverts = 0;
|
|
}
|
|
|
|
/* Alloc space in the current dma region.
|
|
@@ -287,26 +270,14 @@ r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize )
|
|
{
|
|
GLuint bytes = vsize * nverts;
|
|
|
|
- if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
|
|
- r300RefillCurrentDmaRegion( rmesa, bytes);
|
|
-
|
|
- if (!rmesa->dma.flush) {
|
|
- rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
|
|
- rmesa->dma.flush = flush_last_swtcl_prim;
|
|
- }
|
|
-
|
|
- ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
|
|
- ASSERT( rmesa->dma.flush == flush_last_swtcl_prim );
|
|
- ASSERT( rmesa->dma.current.start +
|
|
- rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
|
|
- rmesa->dma.current.ptr );
|
|
-
|
|
- {
|
|
- GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr);
|
|
- rmesa->dma.current.ptr += bytes;
|
|
- rmesa->swtcl.numverts += nverts;
|
|
- return head;
|
|
- }
|
|
+ rmesa->swtcl.bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
|
+ 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;
|
|
+ rmesa->swtcl.flush = flush_last_swtcl_prim;
|
|
+ }
|
|
+ return rmesa->swtcl.bo->ptr;
|
|
}
|
|
|
|
static GLuint reduced_prim[] = {
|
|
@@ -352,7 +323,7 @@ static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx); \
|
|
const char *r300verts = (char *)rmesa->swtcl.verts;
|
|
#define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int)))
|
|
-#define VERTEX r300Vertex
|
|
+#define VERTEX r300Vertex
|
|
#define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
|
|
#define PRINT_VERTEX(x)
|
|
#undef TAG
|
|
@@ -572,18 +543,16 @@ static void r300RenderStart(GLcontext *ctx)
|
|
r300ContextPtr rmesa = R300_CONTEXT( ctx );
|
|
// fprintf(stderr, "%s\n", __FUNCTION__);
|
|
|
|
- r300ChooseRenderState(ctx);
|
|
+ r300ChooseRenderState(ctx);
|
|
r300SetVertexFormat(ctx);
|
|
|
|
r300UpdateShaders(rmesa);
|
|
r300UpdateShaderStates(rmesa);
|
|
|
|
r300EmitCacheFlush(rmesa);
|
|
-
|
|
- if (rmesa->dma.flush != 0 &&
|
|
- rmesa->dma.flush != flush_last_swtcl_prim)
|
|
- rmesa->dma.flush( rmesa );
|
|
-
|
|
+ if (rmesa->swtcl.flush != NULL) {
|
|
+ rmesa->swtcl.flush(rmesa);
|
|
+ }
|
|
}
|
|
|
|
static void r300RenderFinish(GLcontext *ctx)
|
|
@@ -593,7 +562,7 @@ static void r300RenderFinish(GLcontext *ctx)
|
|
static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
-
|
|
+
|
|
if (rmesa->swtcl.hw_primitive != hwprim) {
|
|
R300_NEWPRIM( rmesa );
|
|
rmesa->swtcl.hw_primitive = hwprim;
|
|
@@ -611,7 +580,7 @@ static void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
|
|
|
|
r300RasterPrimitive( ctx, reduced_prim[prim] );
|
|
// fprintf(stderr, "%s\n", __FUNCTION__);
|
|
-
|
|
+
|
|
}
|
|
|
|
static void r300ResetLineStipple(GLcontext *ctx)
|
|
@@ -625,12 +594,12 @@ void r300InitSwtcl(GLcontext *ctx)
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
static int firsttime = 1;
|
|
-
|
|
+
|
|
if (firsttime) {
|
|
init_rast_tab();
|
|
firsttime = 0;
|
|
}
|
|
-
|
|
+
|
|
tnl->Driver.Render.Start = r300RenderStart;
|
|
tnl->Driver.Render.Finish = r300RenderFinish;
|
|
tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
|
|
@@ -638,15 +607,15 @@ void r300InitSwtcl(GLcontext *ctx)
|
|
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
|
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
|
tnl->Driver.Render.Interp = _tnl_interp;
|
|
-
|
|
+
|
|
/* FIXME: what are these numbers? */
|
|
- _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
|
|
+ _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
|
|
48 * sizeof(GLfloat) );
|
|
-
|
|
+
|
|
rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
|
|
rmesa->swtcl.RenderIndex = ~0;
|
|
rmesa->swtcl.render_primitive = GL_TRIANGLES;
|
|
- rmesa->swtcl.hw_primitive = 0;
|
|
+ rmesa->swtcl.hw_primitive = 0;
|
|
|
|
_tnl_invalidate_vertex_state( ctx, ~0 );
|
|
_tnl_invalidate_vertices( ctx, ~0 );
|
|
@@ -655,9 +624,9 @@ void r300InitSwtcl(GLcontext *ctx)
|
|
_tnl_need_projected_coords( ctx, GL_FALSE );
|
|
r300ChooseRenderState(ctx);
|
|
|
|
- _mesa_validate_all_lighting_tables( ctx );
|
|
+ _mesa_validate_all_lighting_tables( ctx );
|
|
|
|
- tnl->Driver.NotifyMaterialChange =
|
|
+ tnl->Driver.NotifyMaterialChange =
|
|
_mesa_validate_all_lighting_tables;
|
|
}
|
|
|
|
@@ -665,33 +634,32 @@ void r300DestroySwtcl(GLcontext *ctx)
|
|
{
|
|
}
|
|
|
|
-void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset)
|
|
+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
|
|
{
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
+ BATCH_LOCALS(rmesa);
|
|
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
if (RADEON_DEBUG & DEBUG_VERTS)
|
|
- fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
|
|
- __FUNCTION__, vertex_size, offset);
|
|
-
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2), 2);
|
|
- e32(1);
|
|
- e32(vertex_size | (vertex_size << 8));
|
|
- e32(offset);
|
|
+ fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
|
|
+ __FUNCTION__, vertex_size, offset);
|
|
+
|
|
+ BEGIN_BATCH(5);
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2);
|
|
+ OUT_BATCH(1);
|
|
+ OUT_BATCH(vertex_size | (vertex_size << 8));
|
|
+ OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
|
|
+ END_BATCH();
|
|
}
|
|
|
|
void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
|
|
{
|
|
-
|
|
- int cmd_reserved = 0;
|
|
- int cmd_written = 0;
|
|
+ BATCH_LOCALS(rmesa);
|
|
int type, num_verts;
|
|
- drm_radeon_cmd_header_t *cmd = NULL;
|
|
|
|
type = r300PrimitiveType(rmesa, primitive);
|
|
num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
|
|
-
|
|
- start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
|
|
- e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
|
|
+
|
|
+ BEGIN_BATCH(3);
|
|
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
|
|
+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
|
|
+ END_BATCH();
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
|
|
index 8ab382c..9ceac70 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_tex.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
|
|
@@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "main/context.h"
|
|
#include "main/enums.h"
|
|
#include "main/image.h"
|
|
+#include "main/mipmap.h"
|
|
#include "main/simple_list.h"
|
|
#include "main/texformat.h"
|
|
#include "main/texstore.h"
|
|
@@ -49,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_context.h"
|
|
#include "r300_state.h"
|
|
#include "r300_ioctl.h"
|
|
+#include "r300_mipmap_tree.h"
|
|
#include "r300_tex.h"
|
|
|
|
#include "xmlpool.h"
|
|
@@ -79,7 +81,7 @@ static unsigned int translate_wrap_mode(GLenum wrapmode)
|
|
*/
|
|
static void r300UpdateTexWrap(r300TexObjPtr t)
|
|
{
|
|
- struct gl_texture_object *tObj = t->base.tObj;
|
|
+ struct gl_texture_object *tObj = &t->base;
|
|
|
|
t->filter &=
|
|
~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK);
|
|
@@ -119,6 +121,9 @@ static GLuint aniso_filter(GLfloat anisotropy)
|
|
*/
|
|
static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
|
|
{
|
|
+ /* Force revalidation to account for switches from/to mipmapping. */
|
|
+ t->validated = GL_FALSE;
|
|
+
|
|
t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK);
|
|
t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY;
|
|
|
|
@@ -176,39 +181,6 @@ static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
|
|
t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
|
|
}
|
|
|
|
-/**
|
|
- * Allocate space for and load the mesa images into the texture memory block.
|
|
- * This will happen before drawing with a new texture, or drawing with a
|
|
- * texture after it was swapped out or teximaged again.
|
|
- */
|
|
-
|
|
-static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
|
|
-{
|
|
- r300TexObjPtr t;
|
|
-
|
|
- t = CALLOC_STRUCT(r300_tex_obj);
|
|
- texObj->DriverData = t;
|
|
- if (t != NULL) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE) {
|
|
- fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
|
|
- (void *)texObj, (void *)t);
|
|
- }
|
|
-
|
|
- /* Initialize non-image-dependent parts of the state:
|
|
- */
|
|
- t->base.tObj = texObj;
|
|
- t->border_fallback = GL_FALSE;
|
|
-
|
|
- make_empty_list(&t->base);
|
|
-
|
|
- r300UpdateTexWrap(t);
|
|
- r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
|
|
- r300SetTexBorderColor(t, texObj->_BorderChan);
|
|
- }
|
|
-
|
|
- return t;
|
|
-}
|
|
-
|
|
/* try to find a format which will only need a memcopy */
|
|
static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
|
|
GLenum srcType)
|
|
@@ -434,277 +406,208 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
|
|
return NULL; /* never get here */
|
|
}
|
|
|
|
-static GLboolean
|
|
-r300ValidateClientStorage(GLcontext * ctx, GLenum target,
|
|
- GLint internalFormat,
|
|
- GLint srcWidth, GLint srcHeight,
|
|
- GLenum format, GLenum type, const void *pixels,
|
|
- const struct gl_pixelstore_attrib *packing,
|
|
- struct gl_texture_object *texObj,
|
|
- struct gl_texture_image *texImage)
|
|
+
|
|
+/**
|
|
+ * Allocate an empty texture image object.
|
|
+ */
|
|
+static struct gl_texture_image *r300NewTextureImage(GLcontext *ctx)
|
|
{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
+ return CALLOC(sizeof(r300_texture_image));
|
|
+}
|
|
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "intformat %s format %s type %s\n",
|
|
- _mesa_lookup_enum_by_nr(internalFormat),
|
|
- _mesa_lookup_enum_by_nr(format),
|
|
- _mesa_lookup_enum_by_nr(type));
|
|
+/**
|
|
+ * Free memory associated with this texture image.
|
|
+ */
|
|
+static void r300FreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
|
|
+{
|
|
+ r300_texture_image* image = get_r300_texture_image(timage);
|
|
|
|
- if (!ctx->Unpack.ClientStorage)
|
|
- return 0;
|
|
+ if (image->mt) {
|
|
+ r300_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 (ctx->_ImageTransferState ||
|
|
- texImage->IsCompressed || texObj->GenerateMipmap)
|
|
- return 0;
|
|
|
|
- /* This list is incomplete, may be different on ppc???
|
|
- */
|
|
- switch (internalFormat) {
|
|
- case GL_RGBA:
|
|
- if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
|
|
- texImage->TexFormat = _dri_texformat_argb8888;
|
|
- } else
|
|
- return 0;
|
|
- break;
|
|
+/* Set Data pointer and additional data for mapped texture image */
|
|
+static void teximage_set_map_data(r300_texture_image *image)
|
|
+{
|
|
+ r300_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;
|
|
+}
|
|
|
|
- case GL_RGB:
|
|
- if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
|
|
- texImage->TexFormat = _dri_texformat_rgb565;
|
|
- } else
|
|
- return 0;
|
|
- break;
|
|
|
|
- case GL_YCBCR_MESA:
|
|
- if (format == GL_YCBCR_MESA &&
|
|
- type == GL_UNSIGNED_SHORT_8_8_REV_APPLE) {
|
|
- texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
|
|
- } else if (format == GL_YCBCR_MESA &&
|
|
- (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
|
|
- type == GL_UNSIGNED_BYTE)) {
|
|
- texImage->TexFormat = &_mesa_texformat_ycbcr;
|
|
- } else
|
|
- return 0;
|
|
- break;
|
|
+/**
|
|
+ * Map a single texture image for glTexImage and friends.
|
|
+ */
|
|
+static void r300_teximage_map(r300_texture_image *image, GLboolean write_enable)
|
|
+{
|
|
+ if (image->mt) {
|
|
+ assert(!image->base.Data);
|
|
|
|
- default:
|
|
- return 0;
|
|
+ radeon_bo_map(image->mt->bo, write_enable);
|
|
+ teximage_set_map_data(image);
|
|
}
|
|
+}
|
|
|
|
- /* Could deal with these packing issues, but currently don't:
|
|
- */
|
|
- if (packing->SkipPixels ||
|
|
- packing->SkipRows || packing->SwapBytes || packing->LsbFirst) {
|
|
- return 0;
|
|
- }
|
|
|
|
- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
|
|
- format, type);
|
|
+static void r300_teximage_unmap(r300_texture_image *image)
|
|
+{
|
|
+ if (image->mt) {
|
|
+ assert(image->base.Data);
|
|
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: srcRowStride %d/%x\n",
|
|
- __FUNCTION__, srcRowStride, srcRowStride);
|
|
+ image->base.Data = 0;
|
|
+ radeon_bo_unmap(image->mt->bo);
|
|
+ }
|
|
+}
|
|
|
|
- /* Could check this later in upload, pitch restrictions could be
|
|
- * relaxed, but would need to store the image pitch somewhere,
|
|
- * as packing details might change before image is uploaded:
|
|
- */
|
|
- if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
|
|
- || (srcRowStride & 63))
|
|
- return 0;
|
|
+/**
|
|
+ * Map a validated texture for reading during software rendering.
|
|
+ */
|
|
+static void r300MapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
|
|
+{
|
|
+ r300TexObj* t = r300_tex_obj(texObj);
|
|
+ int face, level;
|
|
|
|
- /* Have validated that _mesa_transfer_teximage would be a straight
|
|
- * memcpy at this point. NOTE: future calls to TexSubImage will
|
|
- * overwrite the client data. This is explicitly mentioned in the
|
|
- * extension spec.
|
|
- */
|
|
- texImage->Data = (void *)pixels;
|
|
- texImage->IsClientData = GL_TRUE;
|
|
- texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
|
|
+ assert(texObj->_Complete);
|
|
+ assert(t->mt);
|
|
|
|
- return 1;
|
|
+ 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_r300_texture_image(texObj->Image[face][level]));
|
|
+ }
|
|
}
|
|
|
|
-static void r300TexImage1D(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)
|
|
+static void r300UnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
|
|
{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
+ r300TexObj* t = r300_tex_obj(texObj);
|
|
+ int face, level;
|
|
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
|
- return;
|
|
- }
|
|
- }
|
|
+ assert(texObj->_Complete);
|
|
+ assert(t->mt);
|
|
|
|
- /* Note, this will call ChooseTextureFormat */
|
|
- _mesa_store_teximage1d(ctx, target, level, internalFormat,
|
|
- width, border, format, type, pixels,
|
|
- &ctx->Unpack, texObj, texImage);
|
|
-
|
|
- t->dirty_images[0] |= (1 << level);
|
|
+ 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);
|
|
}
|
|
|
|
-static void r300TexSubImage1D(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)
|
|
+/**
|
|
+ * All glTexImage calls go through this function.
|
|
+ */
|
|
+static void r300_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)
|
|
{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
+ r300TexObj* t = r300_tex_obj(texObj);
|
|
+ r300_texture_image* image = get_r300_texture_image(texImage);
|
|
|
|
- assert(t); /* this _should_ be true */
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
|
|
- return;
|
|
- }
|
|
- }
|
|
+ R300_FIREVERTICES(rmesa);
|
|
|
|
- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
|
|
- format, type, pixels, packing, texObj,
|
|
- texImage);
|
|
+ t->validated = GL_FALSE;
|
|
|
|
- t->dirty_images[0] |= (1 << level);
|
|
-}
|
|
+ /* Choose and fill in the texture format for this image */
|
|
+ texImage->TexFormat = r300ChooseTextureFormat(ctx, internalFormat, format, type);
|
|
+ _mesa_set_fetch_functions(texImage, dims);
|
|
|
|
-static void r300TexImage2D(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)
|
|
-{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
- GLuint face;
|
|
-
|
|
- /* which cube face or ordinary 2D image */
|
|
- 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:
|
|
- face =
|
|
- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
- ASSERT(face < 6);
|
|
- break;
|
|
- default:
|
|
- face = 0;
|
|
+ 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;
|
|
}
|
|
|
|
- if (t != NULL) {
|
|
- driSwapOutTextureObject(t);
|
|
+ /* Allocate memory for image */
|
|
+ r300FreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
|
|
+
|
|
+ if (!t->mt)
|
|
+ r300_try_alloc_miptree(rmesa, t, texImage, face, level);
|
|
+ if (t->mt && r300_miptree_matches_image(t->mt, texImage, face, level)) {
|
|
+ image->mt = t->mt;
|
|
+ image->mtlevel = level - t->mt->firstLevel;
|
|
+ image->mtface = face;
|
|
+ r300_miptree_reference(t->mt);
|
|
} else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
|
- return;
|
|
+ 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);
|
|
}
|
|
|
|
- texImage->IsClientData = GL_FALSE;
|
|
-
|
|
- if (r300ValidateClientStorage(ctx, target,
|
|
- internalFormat,
|
|
- width, height,
|
|
- format, type, pixels,
|
|
- packing, texObj, texImage)) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using client storage\n",
|
|
- __FUNCTION__);
|
|
+ /* 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 {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using normal storage\n",
|
|
- __FUNCTION__);
|
|
-
|
|
- /* Normal path: copy (to cached memory) and eventually upload
|
|
- * via another copy to GART memory and then a blit... Could
|
|
- * eliminate one copy by going straight to (permanent) GART.
|
|
- *
|
|
- * Note, this will call r300ChooseTextureFormat.
|
|
- */
|
|
- _mesa_store_teximage2d(ctx, target, level, internalFormat,
|
|
- width, height, border, format, type,
|
|
- pixels, &ctx->Unpack, texObj, texImage);
|
|
-
|
|
- t->dirty_images[face] |= (1 << level);
|
|
+ pixels = _mesa_validate_pbo_teximage(
|
|
+ ctx, dims, width, height, depth,
|
|
+ format, type, pixels, packing, "glTexImage");
|
|
}
|
|
-}
|
|
|
|
-static void r300TexSubImage2D(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)
|
|
-{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
- GLuint face;
|
|
+ if (pixels) {
|
|
+ r300_teximage_map(image, GL_TRUE);
|
|
|
|
- /* which cube face or ordinary 2D image */
|
|
- 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:
|
|
- face =
|
|
- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
- ASSERT(face < 6);
|
|
- break;
|
|
- default:
|
|
- face = 0;
|
|
- }
|
|
-
|
|
- assert(t); /* this _should_ be true */
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
|
|
- return;
|
|
+ if (compressed) {
|
|
+ memcpy(texImage->Data, pixels, imageSize);
|
|
+ } else {
|
|
+ GLuint dstRowStride;
|
|
+ if (image->mt) {
|
|
+ r300_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");
|
|
}
|
|
+
|
|
+ r300_teximage_unmap(image);
|
|
}
|
|
|
|
- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
|
|
- height, format, type, pixels, packing, texObj,
|
|
- texImage);
|
|
+ _mesa_unmap_teximage_pbo(ctx, packing);
|
|
|
|
- t->dirty_images[face] |= (1 << level);
|
|
+ /* SGIS_generate_mipmap */
|
|
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
|
|
+ ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
|
|
+ }
|
|
}
|
|
|
|
-static void r300CompressedTexImage2D(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)
|
|
-{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
- GLuint face;
|
|
|
|
- /* which cube face or ordinary 2D image */
|
|
+static GLuint face_for_target(GLenum target)
|
|
+{
|
|
switch (target) {
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
@@ -712,103 +615,50 @@ static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
- face =
|
|
- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
- ASSERT(face < 6);
|
|
- break;
|
|
+ return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
default:
|
|
- face = 0;
|
|
- }
|
|
-
|
|
- if (t != NULL) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
|
|
- "glCompressedTexImage2D");
|
|
- return;
|
|
- }
|
|
+ return 0;
|
|
}
|
|
+}
|
|
|
|
- texImage->IsClientData = GL_FALSE;
|
|
|
|
- /* can't call this, different parameters. Would never evaluate to true anyway currently */
|
|
-#if 0
|
|
- if (r300ValidateClientStorage(ctx, target,
|
|
- internalFormat,
|
|
- width, height,
|
|
- format, type, pixels,
|
|
- packing, texObj, texImage)) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using client storage\n",
|
|
- __FUNCTION__);
|
|
- } else
|
|
-#endif
|
|
- {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using normal storage\n",
|
|
- __FUNCTION__);
|
|
-
|
|
- /* Normal path: copy (to cached memory) and eventually upload
|
|
- * via another copy to GART memory and then a blit... Could
|
|
- * eliminate one copy by going straight to (permanent) GART.
|
|
- *
|
|
- * Note, this will call r300ChooseTextureFormat.
|
|
- */
|
|
- _mesa_store_compressed_teximage2d(ctx, target, level,
|
|
- internalFormat, width, height,
|
|
- border, imageSize, data,
|
|
- texObj, texImage);
|
|
-
|
|
- t->dirty_images[face] |= (1 << level);
|
|
- }
|
|
+static void r300TexImage1D(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)
|
|
+{
|
|
+ r300_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
|
|
+ 0, format, type, pixels, packing, texObj, texImage, 0);
|
|
}
|
|
|
|
-static void r300CompressedTexSubImage2D(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)
|
|
+static void r300TexImage2D(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)
|
|
{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
- GLuint face;
|
|
+ GLuint face = face_for_target(target);
|
|
|
|
- /* which cube face or ordinary 2D image */
|
|
- 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:
|
|
- face =
|
|
- (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
- ASSERT(face < 6);
|
|
- break;
|
|
- default:
|
|
- face = 0;
|
|
- }
|
|
-
|
|
- assert(t); /* this _should_ be true */
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
|
|
- "glCompressedTexSubImage3D");
|
|
- return;
|
|
- }
|
|
- }
|
|
+ r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
|
|
+ 0, format, type, pixels, packing, texObj, texImage, 0);
|
|
+}
|
|
|
|
- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset,
|
|
- yoffset, width, height, format,
|
|
- imageSize, data, texObj, texImage);
|
|
+static void r300CompressedTexImage2D(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 = face_for_target(target);
|
|
|
|
- t->dirty_images[face] |= (1 << level);
|
|
+ r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
|
|
+ imageSize, 0, 0, data, 0, texObj, texImage, 1);
|
|
}
|
|
|
|
static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|
@@ -820,51 +670,100 @@ static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|
struct gl_texture_object *texObj,
|
|
struct gl_texture_image *texImage)
|
|
{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
+ r300_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
|
|
+ 0, format, type, pixels, packing, texObj, texImage, 0);
|
|
+}
|
|
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
|
|
- return;
|
|
+/**
|
|
+ * Update a subregion of the given texture image.
|
|
+ */
|
|
+static void r300_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)
|
|
+{
|
|
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
+ r300_texture_image* image = get_r300_texture_image(texImage);
|
|
+
|
|
+ R300_FIREVERTICES(rmesa);
|
|
+
|
|
+ pixels = _mesa_validate_pbo_teximage(ctx, dims,
|
|
+ width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
|
|
+
|
|
+ if (pixels) {
|
|
+ GLint dstRowStride;
|
|
+ r300_teximage_map(image, GL_TRUE);
|
|
+
|
|
+ if (image->mt) {
|
|
+ r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
|
|
+ dstRowStride = lvl->rowstride;
|
|
+ } else {
|
|
+ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
|
|
}
|
|
- }
|
|
|
|
- texImage->IsClientData = GL_FALSE;
|
|
+ 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");
|
|
|
|
-#if 0
|
|
- if (r300ValidateClientStorage(ctx, target,
|
|
- internalFormat,
|
|
- width, height,
|
|
- format, type, pixels,
|
|
- packing, texObj, texImage)) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using client storage\n",
|
|
- __FUNCTION__);
|
|
- } else
|
|
-#endif
|
|
- {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: Using normal storage\n",
|
|
- __FUNCTION__);
|
|
-
|
|
- /* Normal path: copy (to cached memory) and eventually upload
|
|
- * via another copy to GART memory and then a blit... Could
|
|
- * eliminate one copy by going straight to (permanent) GART.
|
|
- *
|
|
- * Note, this will call r300ChooseTextureFormat.
|
|
- */
|
|
- _mesa_store_teximage3d(ctx, target, level, internalFormat,
|
|
- width, height, depth, border,
|
|
- format, type, pixels,
|
|
- &ctx->Unpack, texObj, texImage);
|
|
+ r300_teximage_unmap(image);
|
|
+ }
|
|
|
|
- t->dirty_images[0] |= (1 << level);
|
|
+ _mesa_unmap_teximage_pbo(ctx, packing);
|
|
+
|
|
+ /* GL_SGIS_generate_mipmap */
|
|
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
|
|
+ ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
|
|
}
|
|
}
|
|
|
|
+static void r300TexSubImage1D(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)
|
|
+{
|
|
+ r300_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
|
|
+ format, type, pixels, packing, texObj, texImage, 0);
|
|
+}
|
|
+
|
|
+static void r300TexSubImage2D(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)
|
|
+{
|
|
+ r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
|
|
+ format, type, pixels, packing, texObj, texImage, 0);
|
|
+}
|
|
+
|
|
+static void r300CompressedTexSubImage2D(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)
|
|
+{
|
|
+ r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
|
|
+ format, 0, data, 0, texObj, texImage, 1);
|
|
+}
|
|
+
|
|
static void
|
|
r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|
GLint xoffset, GLint yoffset, GLint zoffset,
|
|
@@ -875,30 +774,29 @@ r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
|
|
struct gl_texture_object *texObj,
|
|
struct gl_texture_image *texImage)
|
|
{
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
-
|
|
-/* fprintf(stderr, "%s\n", __FUNCTION__); */
|
|
+ r300_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
|
|
+ format, type, pixels, packing, texObj, texImage, 0);
|
|
+}
|
|
|
|
- assert(t); /* this _should_ be true */
|
|
- if (t) {
|
|
- driSwapOutTextureObject(t);
|
|
- } else {
|
|
- t = (driTextureObject *) r300AllocTexObj(texObj);
|
|
- if (!t) {
|
|
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
|
|
- return;
|
|
- }
|
|
- texObj->DriverData = t;
|
|
- }
|
|
|
|
- _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
|
|
- width, height, depth,
|
|
- format, type, pixels, packing, texObj,
|
|
- texImage);
|
|
+/**
|
|
+ * 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 r300_generate_mipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
|
|
+{
|
|
+ GLuint face = face_for_target(target);
|
|
+ r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[face][texObj->BaseLevel]);
|
|
|
|
- t->dirty_images[0] |= (1 << level);
|
|
+ r300_teximage_map(baseimage, GL_FALSE);
|
|
+ _mesa_generate_mipmap(ctx, target, texObj);
|
|
+ r300_teximage_unmap(baseimage);
|
|
}
|
|
|
|
+
|
|
+
|
|
/**
|
|
* Changes variables and flags for a state update, which will happen at the
|
|
* next UpdateTextureState
|
|
@@ -908,7 +806,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
|
struct gl_texture_object *texObj,
|
|
GLenum pname, const GLfloat * params)
|
|
{
|
|
- r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;
|
|
+ r300TexObj* t = r300_tex_obj(texObj);
|
|
|
|
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
|
|
fprintf(stderr, "%s( %s )\n", __FUNCTION__,
|
|
@@ -941,7 +839,11 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
|
* we just have to rely on loading the right subset of mipmap levels
|
|
* to simulate a clamped LOD.
|
|
*/
|
|
- driSwapOutTextureObject((driTextureObject *) t);
|
|
+ if (t->mt) {
|
|
+ r300_miptree_unreference(t->mt);
|
|
+ t->mt = 0;
|
|
+ t->validated = GL_FALSE;
|
|
+ }
|
|
break;
|
|
|
|
case GL_DEPTH_TEXTURE_MODE:
|
|
@@ -964,27 +866,10 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
|
|
}
|
|
}
|
|
|
|
-static void r300BindTexture(GLcontext * ctx, GLenum target,
|
|
- struct gl_texture_object *texObj)
|
|
-{
|
|
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
|
|
- fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__,
|
|
- (void *)texObj, ctx->Texture.CurrentUnit);
|
|
- }
|
|
-
|
|
- if ((target == GL_TEXTURE_1D)
|
|
- || (target == GL_TEXTURE_2D)
|
|
- || (target == GL_TEXTURE_3D)
|
|
- || (target == GL_TEXTURE_CUBE_MAP)
|
|
- || (target == GL_TEXTURE_RECTANGLE_NV)) {
|
|
- assert(texObj->DriverData != NULL);
|
|
- }
|
|
-}
|
|
-
|
|
static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- driTextureObject *t = (driTextureObject *) texObj->DriverData;
|
|
+ r300TexObj* t = r300_tex_obj(texObj);
|
|
|
|
if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
|
|
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
|
|
@@ -992,14 +877,19 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|
_mesa_lookup_enum_by_nr(texObj->Target));
|
|
}
|
|
|
|
- if (t != NULL) {
|
|
- if (rmesa) {
|
|
- R300_FIREVERTICES(rmesa);
|
|
- }
|
|
+ if (rmesa) {
|
|
+ int i;
|
|
+ R300_FIREVERTICES(rmesa);
|
|
+
|
|
+ for(i = 0; i < R300_MAX_TEXTURE_UNITS; ++i)
|
|
+ if (rmesa->hw.textures[i] == t)
|
|
+ rmesa->hw.textures[i] = 0;
|
|
+ }
|
|
|
|
- driDestroyTextureObject(t);
|
|
+ if (t->mt) {
|
|
+ r300_miptree_unreference(t->mt);
|
|
+ t->mt = 0;
|
|
}
|
|
- /* Free mipmap images and the texture object itself */
|
|
_mesa_delete_texture_object(ctx, texObj);
|
|
}
|
|
|
|
@@ -1008,8 +898,6 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|
* Called via ctx->Driver.NewTextureObject.
|
|
* Note: this function will be called during context creation to
|
|
* allocate the default texture objects.
|
|
- * Note: we could use containment here to 'derive' the driver-specific
|
|
- * texture object from the core mesa gl_texture_object. Not done at this time.
|
|
* Fixup MaxAnisotropy according to user preference.
|
|
*/
|
|
static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
|
|
@@ -1017,14 +905,23 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
|
|
GLenum target)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_object *obj;
|
|
- obj = _mesa_new_texture_object(ctx, name, target);
|
|
- if (!obj)
|
|
- return NULL;
|
|
- obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
|
|
+ r300TexObj* t = CALLOC_STRUCT(r300_tex_obj);
|
|
|
|
- r300AllocTexObj(obj);
|
|
- return obj;
|
|
+
|
|
+ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
|
|
+ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
|
|
+ t, _mesa_lookup_enum_by_nr(target));
|
|
+ }
|
|
+
|
|
+ _mesa_initialize_texture_object(&t->base, name, target);
|
|
+ t->base.MaxAnisotropy = rmesa->initialMaxAnisotropy;
|
|
+
|
|
+ /* Initialize hardware state */
|
|
+ r300UpdateTexWrap(t);
|
|
+ r300SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
|
|
+ r300SetTexBorderColor(t, t->base._BorderChan);
|
|
+
|
|
+ return &t->base;
|
|
}
|
|
|
|
void r300InitTextureFuncs(struct dd_function_table *functions)
|
|
@@ -1032,6 +929,11 @@ void r300InitTextureFuncs(struct dd_function_table *functions)
|
|
/* Note: we only plug in the functions we implement in the driver
|
|
* since _mesa_init_driver_functions() was already called.
|
|
*/
|
|
+ functions->NewTextureImage = r300NewTextureImage;
|
|
+ functions->FreeTexImageData = r300FreeTexImageData;
|
|
+ functions->MapTexture = r300MapTexture;
|
|
+ functions->UnmapTexture = r300UnmapTexture;
|
|
+
|
|
functions->ChooseTextureFormat = r300ChooseTextureFormat;
|
|
functions->TexImage1D = r300TexImage1D;
|
|
functions->TexImage2D = r300TexImage2D;
|
|
@@ -1040,7 +942,6 @@ void r300InitTextureFuncs(struct dd_function_table *functions)
|
|
functions->TexSubImage2D = r300TexSubImage2D;
|
|
functions->TexSubImage3D = r300TexSubImage3D;
|
|
functions->NewTextureObject = r300NewTextureObject;
|
|
- functions->BindTexture = r300BindTexture;
|
|
functions->DeleteTexture = r300DeleteTexture;
|
|
functions->IsTextureResident = driIsTextureResident;
|
|
|
|
@@ -1049,5 +950,7 @@ void r300InitTextureFuncs(struct dd_function_table *functions)
|
|
functions->CompressedTexImage2D = r300CompressedTexImage2D;
|
|
functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
|
|
|
|
+ functions->GenerateMipmap = r300_generate_mipmap;
|
|
+
|
|
driInitTextureFormats();
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
|
|
index b86d45b..358b927 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_tex.h
|
|
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
|
|
@@ -41,12 +41,7 @@ extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
|
|
unsigned long long offset, GLint depth,
|
|
GLuint pitch);
|
|
|
|
-extern void r300UpdateTextureState(GLcontext * ctx);
|
|
-
|
|
-extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t,
|
|
- GLuint face);
|
|
-
|
|
-extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t);
|
|
+extern void r300ValidateTextures(GLcontext * ctx);
|
|
|
|
extern void r300InitTextureFuncs(struct dd_function_table *functions);
|
|
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c
|
|
index b03eefa..53eeca1 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_texmem.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_texmem.c
|
|
@@ -48,520 +48,11 @@ SOFTWARE.
|
|
#include "r300_context.h"
|
|
#include "r300_state.h"
|
|
#include "r300_cmdbuf.h"
|
|
+#include "r300_emit.h"
|
|
+#include "r300_mipmap_tree.h"
|
|
#include "radeon_ioctl.h"
|
|
#include "r300_tex.h"
|
|
#include "r300_ioctl.h"
|
|
#include <unistd.h> /* for usleep() */
|
|
|
|
-#ifdef USER_BUFFERS
|
|
-#include "r300_mem.h"
|
|
-#endif
|
|
|
|
-/**
|
|
- * Destroy any device-dependent state associated with the texture. This may
|
|
- * include NULLing out hardware state that points to the texture.
|
|
- */
|
|
-void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t)
|
|
-{
|
|
- int i;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE) {
|
|
- fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
|
|
- (void *)t, (void *)t->base.tObj);
|
|
- }
|
|
-
|
|
- for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) {
|
|
- if (rmesa->state.texture.unit[i].texobj == t) {
|
|
- rmesa->state.texture.unit[i].texobj = NULL;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/* ------------------------------------------------------------
|
|
- * Texture image conversions
|
|
- */
|
|
-
|
|
-static void r300UploadGARTClientSubImage(r300ContextPtr rmesa,
|
|
- r300TexObjPtr t,
|
|
- struct gl_texture_image *texImage,
|
|
- GLint hwlevel,
|
|
- GLint x, GLint y,
|
|
- GLint width, GLint height)
|
|
-{
|
|
- const struct gl_texture_format *texFormat = texImage->TexFormat;
|
|
- GLuint srcPitch, dstPitch;
|
|
- int blit_format;
|
|
- int srcOffset;
|
|
-
|
|
- /*
|
|
- * XXX it appears that we always upload the full image, not a subimage.
|
|
- * I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever
|
|
- * changed, the src pitch will have to change.
|
|
- */
|
|
- switch (texFormat->TexelBytes) {
|
|
- case 1:
|
|
- blit_format = R300_CP_COLOR_FORMAT_CI8;
|
|
- srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- break;
|
|
- case 2:
|
|
- blit_format = R300_CP_COLOR_FORMAT_RGB565;
|
|
- srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- break;
|
|
- case 4:
|
|
- blit_format = R300_CP_COLOR_FORMAT_ARGB8888;
|
|
- srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- break;
|
|
- case 8:
|
|
- case 16:
|
|
- blit_format = R300_CP_COLOR_FORMAT_CI8;
|
|
- srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
|
- break;
|
|
- default:
|
|
- return;
|
|
- }
|
|
-
|
|
- t->image[0][hwlevel].data = texImage->Data;
|
|
- srcOffset = r300GartOffsetFromVirtual(rmesa, texImage->Data);
|
|
-
|
|
- assert(srcOffset != ~0);
|
|
-
|
|
- /* Don't currently need to cope with small pitches?
|
|
- */
|
|
- width = texImage->Width;
|
|
- height = texImage->Height;
|
|
-
|
|
- if (texFormat->TexelBytes > 4) {
|
|
- width *= texFormat->TexelBytes;
|
|
- }
|
|
-
|
|
- r300EmitWait(rmesa, R300_WAIT_3D);
|
|
-
|
|
- r300EmitBlit(rmesa, blit_format,
|
|
- srcPitch,
|
|
- srcOffset,
|
|
- dstPitch,
|
|
- t->bufAddr,
|
|
- x,
|
|
- y,
|
|
- t->image[0][hwlevel].x + x,
|
|
- t->image[0][hwlevel].y + y, width, height);
|
|
-
|
|
- r300EmitWait(rmesa, R300_WAIT_2D);
|
|
-}
|
|
-
|
|
-static void r300UploadRectSubImage(r300ContextPtr rmesa,
|
|
- r300TexObjPtr t,
|
|
- struct gl_texture_image *texImage,
|
|
- GLint x, GLint y, GLint width, GLint height)
|
|
-{
|
|
- const struct gl_texture_format *texFormat = texImage->TexFormat;
|
|
- int blit_format, dstPitch, done;
|
|
-
|
|
- switch (texFormat->TexelBytes) {
|
|
- case 1:
|
|
- blit_format = R300_CP_COLOR_FORMAT_CI8;
|
|
- break;
|
|
- case 2:
|
|
- blit_format = R300_CP_COLOR_FORMAT_RGB565;
|
|
- break;
|
|
- case 4:
|
|
- blit_format = R300_CP_COLOR_FORMAT_ARGB8888;
|
|
- break;
|
|
- case 8:
|
|
- case 16:
|
|
- blit_format = R300_CP_COLOR_FORMAT_CI8;
|
|
- break;
|
|
- default:
|
|
- return;
|
|
- }
|
|
-
|
|
- t->image[0][0].data = texImage->Data;
|
|
-
|
|
- /* Currently don't need to cope with small pitches.
|
|
- */
|
|
- width = texImage->Width;
|
|
- height = texImage->Height;
|
|
- dstPitch = t->pitch;
|
|
-
|
|
- if (texFormat->TexelBytes > 4) {
|
|
- width *= texFormat->TexelBytes;
|
|
- }
|
|
-
|
|
- if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
|
|
- /* In this case, could also use GART texturing. This is
|
|
- * currently disabled, but has been tested & works.
|
|
- */
|
|
- t->offset = r300GartOffsetFromVirtual(rmesa, texImage->Data);
|
|
- t->pitch = texImage->RowStride * texFormat->TexelBytes - 32;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr,
|
|
- "Using GART texturing for rectangular client texture\n");
|
|
-
|
|
- /* Release FB memory allocated for this image:
|
|
- */
|
|
- /* FIXME This may not be correct as driSwapOutTextureObject sets
|
|
- * FIXME dirty_images. It may be fine, though.
|
|
- */
|
|
- if (t->base.memBlock) {
|
|
- driSwapOutTextureObject((driTextureObject *) t);
|
|
- }
|
|
- } else if (texImage->IsClientData) {
|
|
- /* Data already in GART memory, with usable pitch.
|
|
- */
|
|
- GLuint srcPitch;
|
|
- srcPitch = texImage->RowStride * texFormat->TexelBytes;
|
|
- r300EmitBlit(rmesa,
|
|
- blit_format,
|
|
- srcPitch,
|
|
- r300GartOffsetFromVirtual(rmesa, texImage->Data),
|
|
- dstPitch, t->bufAddr, 0, 0, 0, 0, width, height);
|
|
- } else {
|
|
- /* Data not in GART memory, or bad pitch.
|
|
- */
|
|
- for (done = 0; done < height;) {
|
|
- struct r300_dma_region region;
|
|
- int lines =
|
|
- MIN2(height - done, RADEON_BUFFER_SIZE / dstPitch);
|
|
- int src_pitch;
|
|
- char *tex;
|
|
-
|
|
- src_pitch = texImage->RowStride * texFormat->TexelBytes;
|
|
-
|
|
- tex = (char *)texImage->Data + done * src_pitch;
|
|
-
|
|
- memset(®ion, 0, sizeof(region));
|
|
- r300AllocDmaRegion(rmesa, ®ion, lines * dstPitch,
|
|
- 1024);
|
|
-
|
|
- /* Copy texdata to dma:
|
|
- */
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr,
|
|
- "%s: src_pitch %d dst_pitch %d\n",
|
|
- __FUNCTION__, src_pitch, dstPitch);
|
|
-
|
|
- if (src_pitch == dstPitch) {
|
|
- memcpy(region.address + region.start, tex,
|
|
- lines * src_pitch);
|
|
- } else {
|
|
- char *buf = region.address + region.start;
|
|
- int i;
|
|
- for (i = 0; i < lines; i++) {
|
|
- memcpy(buf, tex, src_pitch);
|
|
- buf += dstPitch;
|
|
- tex += src_pitch;
|
|
- }
|
|
- }
|
|
-
|
|
- r300EmitWait(rmesa, R300_WAIT_3D);
|
|
-
|
|
- /* Blit to framebuffer
|
|
- */
|
|
- r300EmitBlit(rmesa,
|
|
- blit_format,
|
|
- dstPitch, GET_START(®ion),
|
|
- dstPitch | (t->tile_bits >> 16),
|
|
- t->bufAddr, 0, 0, 0, done, width, lines);
|
|
-
|
|
- r300EmitWait(rmesa, R300_WAIT_2D);
|
|
-#ifdef USER_BUFFERS
|
|
- r300_mem_use(rmesa, region.buf->id);
|
|
-#endif
|
|
-
|
|
- r300ReleaseDmaRegion(rmesa, ®ion, __FUNCTION__);
|
|
- done += lines;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/**
|
|
- * Upload the texture image associated with texture \a t at the specified
|
|
- * level at the address relative to \a start.
|
|
- */
|
|
-static void r300UploadSubImage(r300ContextPtr rmesa, r300TexObjPtr t,
|
|
- GLint hwlevel,
|
|
- GLint x, GLint y, GLint width, GLint height,
|
|
- GLuint face)
|
|
-{
|
|
- struct gl_texture_image *texImage = NULL;
|
|
- GLuint offset;
|
|
- GLint imageWidth, imageHeight;
|
|
- GLint ret;
|
|
- drm_radeon_texture_t tex;
|
|
- drm_radeon_tex_image_t tmp;
|
|
- const int level = hwlevel + t->base.firstLevel;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE) {
|
|
- fprintf(stderr,
|
|
- "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
|
- __FUNCTION__, (void *)t, (void *)t->base.tObj, level,
|
|
- width, height, face);
|
|
- }
|
|
-
|
|
- ASSERT(face < 6);
|
|
-
|
|
- /* Ensure we have a valid texture to upload */
|
|
- if ((hwlevel < 0) || (hwlevel >= RADEON_MAX_TEXTURE_LEVELS)) {
|
|
- _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
|
|
- return;
|
|
- }
|
|
-
|
|
- texImage = t->base.tObj->Image[face][level];
|
|
-
|
|
- if (!texImage) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: texImage %d is NULL!\n",
|
|
- __FUNCTION__, level);
|
|
- return;
|
|
- }
|
|
- if (!texImage->Data) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: image data is NULL!\n",
|
|
- __FUNCTION__);
|
|
- return;
|
|
- }
|
|
-
|
|
- if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
|
- assert(level == 0);
|
|
- assert(hwlevel == 0);
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: image data is rectangular\n",
|
|
- __FUNCTION__);
|
|
- r300UploadRectSubImage(rmesa, t, texImage, x, y, width, height);
|
|
- return;
|
|
- } else if (texImage->IsClientData) {
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr,
|
|
- "%s: image data is in GART client storage\n",
|
|
- __FUNCTION__);
|
|
- r300UploadGARTClientSubImage(rmesa, t, texImage, hwlevel, x, y,
|
|
- width, height);
|
|
- return;
|
|
- } else if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "%s: image data is in normal memory\n",
|
|
- __FUNCTION__);
|
|
-
|
|
- imageWidth = texImage->Width;
|
|
- imageHeight = texImage->Height;
|
|
-
|
|
- offset = t->bufAddr;
|
|
-
|
|
- if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
|
|
- GLint imageX = 0;
|
|
- GLint imageY = 0;
|
|
- GLint blitX = t->image[face][hwlevel].x;
|
|
- GLint blitY = t->image[face][hwlevel].y;
|
|
- GLint blitWidth = t->image[face][hwlevel].width;
|
|
- GLint blitHeight = t->image[face][hwlevel].height;
|
|
- fprintf(stderr, " upload image: %d,%d at %d,%d\n",
|
|
- imageWidth, imageHeight, imageX, imageY);
|
|
- fprintf(stderr, " upload blit: %d,%d at %d,%d\n",
|
|
- blitWidth, blitHeight, blitX, blitY);
|
|
- fprintf(stderr, " blit ofs: 0x%07x level: %d/%d\n",
|
|
- (GLuint) offset, hwlevel, level);
|
|
- }
|
|
-
|
|
- t->image[face][hwlevel].data = texImage->Data;
|
|
-
|
|
- /* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
|
|
- * NOTE: we're always use a 1KB-wide blit and I8 texture format.
|
|
- * We used to use 1, 2 and 4-byte texels and used to use the texture
|
|
- * width to dictate the blit width - but that won't work for compressed
|
|
- * textures. (Brian)
|
|
- * NOTE: can't do that with texture tiling. (sroland)
|
|
- */
|
|
- tex.offset = offset;
|
|
- tex.image = &tmp;
|
|
- /* copy (x,y,width,height,data) */
|
|
- memcpy(&tmp, &t->image[face][hwlevel], sizeof(tmp));
|
|
-
|
|
- if (texImage->TexFormat->TexelBytes > 4) {
|
|
- const int log2TexelBytes =
|
|
- (3 + (texImage->TexFormat->TexelBytes >> 4));
|
|
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
|
- tex.pitch =
|
|
- MAX2((texImage->Width * texImage->TexFormat->TexelBytes) /
|
|
- 64, 1);
|
|
- tex.height = imageHeight;
|
|
- tex.width = imageWidth << log2TexelBytes;
|
|
- tex.offset += (tmp.x << log2TexelBytes) & ~1023;
|
|
- tmp.x = tmp.x % (1024 >> log2TexelBytes);
|
|
- tmp.width = tmp.width << log2TexelBytes;
|
|
- } else if (texImage->TexFormat->TexelBytes) {
|
|
- /* use multi-byte upload scheme */
|
|
- tex.height = imageHeight;
|
|
- tex.width = imageWidth;
|
|
- switch (texImage->TexFormat->TexelBytes) {
|
|
- case 1:
|
|
- tex.format = RADEON_TXFORMAT_I8;
|
|
- break;
|
|
- case 2:
|
|
- tex.format = RADEON_TXFORMAT_AI88;
|
|
- break;
|
|
- case 4:
|
|
- tex.format = RADEON_TXFORMAT_ARGB8888;
|
|
- break;
|
|
- }
|
|
- tex.pitch =
|
|
- MAX2((texImage->Width * texImage->TexFormat->TexelBytes) /
|
|
- 64, 1);
|
|
- tex.offset += tmp.x & ~1023;
|
|
- tmp.x = tmp.x % 1024;
|
|
-
|
|
- if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
|
- /* need something like "tiled coordinates" ? */
|
|
- tmp.y = tmp.x / (tex.pitch * 128) * 2;
|
|
- tmp.x =
|
|
- tmp.x % (tex.pitch * 128) / 2 /
|
|
- texImage->TexFormat->TexelBytes;
|
|
- tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
|
|
- } else {
|
|
- tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
|
|
- }
|
|
-#if 1
|
|
- if ((t->tile_bits & R300_TXO_MACRO_TILE) &&
|
|
- (texImage->Width * texImage->TexFormat->TexelBytes >= 256)
|
|
- && ((!(t->tile_bits & R300_TXO_MICRO_TILE)
|
|
- && (texImage->Height >= 8))
|
|
- || (texImage->Height >= 16))) {
|
|
- /* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
|
|
- OR if height is smaller than 8 automatically, but if micro tiling is active
|
|
- the limit is height 16 instead ? */
|
|
- tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
|
|
- }
|
|
-#endif
|
|
- } else {
|
|
- /* In case of for instance 8x8 texture (2x2 dxt blocks),
|
|
- padding after the first two blocks is needed (only
|
|
- with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
|
|
- /* set tex.height to 1/4 since 1 "macropixel" (dxt-block)
|
|
- has 4 real pixels. Needed so the kernel module reads
|
|
- the right amount of data. */
|
|
- tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */
|
|
- tex.pitch = (R300_BLIT_WIDTH_BYTES / 64);
|
|
- tex.height = (imageHeight + 3) / 4;
|
|
- tex.width = (imageWidth + 3) / 4;
|
|
- if ((t->format & R300_TX_FORMAT_DXT1) == R300_TX_FORMAT_DXT1) {
|
|
- tex.width *= 8;
|
|
- } else {
|
|
- tex.width *= 16;
|
|
- }
|
|
- }
|
|
-
|
|
- LOCK_HARDWARE(&rmesa->radeon);
|
|
- do {
|
|
- ret =
|
|
- drmCommandWriteRead(rmesa->radeon.dri.fd,
|
|
- DRM_RADEON_TEXTURE, &tex,
|
|
- sizeof(drm_radeon_texture_t));
|
|
- if (ret) {
|
|
- if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
- fprintf(stderr,
|
|
- "DRM_RADEON_TEXTURE: again!\n");
|
|
- usleep(1);
|
|
- }
|
|
- } while (ret == -EAGAIN);
|
|
-
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
-
|
|
- if (ret) {
|
|
- fprintf(stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret);
|
|
- fprintf(stderr, " offset=0x%08x\n", offset);
|
|
- fprintf(stderr, " image width=%d height=%d\n",
|
|
- imageWidth, imageHeight);
|
|
- fprintf(stderr, " blit width=%d height=%d data=%p\n",
|
|
- t->image[face][hwlevel].width,
|
|
- t->image[face][hwlevel].height,
|
|
- t->image[face][hwlevel].data);
|
|
- _mesa_exit(-1);
|
|
- }
|
|
-}
|
|
-
|
|
-/**
|
|
- * Upload the texture images associated with texture \a t. This might
|
|
- * require the allocation of texture memory.
|
|
- *
|
|
- * \param rmesa Context pointer
|
|
- * \param t Texture to be uploaded
|
|
- * \param face Cube map face to be uploaded. Zero for non-cube maps.
|
|
- */
|
|
-
|
|
-int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
|
|
-{
|
|
- const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
|
-
|
|
- if (t->image_override)
|
|
- return 0;
|
|
-
|
|
- if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) {
|
|
- fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
|
- (void *)rmesa->radeon.glCtx, (void *)t->base.tObj,
|
|
- t->base.totalSize, t->base.firstLevel,
|
|
- t->base.lastLevel);
|
|
- }
|
|
-
|
|
- if (t->base.totalSize == 0)
|
|
- return 0;
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_SYNC) {
|
|
- fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
|
|
- radeonFinish(rmesa->radeon.glCtx);
|
|
- }
|
|
-
|
|
- LOCK_HARDWARE(&rmesa->radeon);
|
|
-
|
|
- if (t->base.memBlock == NULL) {
|
|
- int heap;
|
|
-
|
|
- heap = driAllocateTexture(rmesa->texture_heaps, rmesa->nr_heaps,
|
|
- (driTextureObject *) t);
|
|
- if (heap == -1) {
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- /* Set the base offset of the texture image */
|
|
- t->bufAddr = rmesa->radeon.radeonScreen->texOffset[heap]
|
|
- + t->base.memBlock->ofs;
|
|
- t->offset = t->bufAddr;
|
|
-
|
|
- if (!(t->base.tObj->Image[0][0]->IsClientData)) {
|
|
- /* hope it's safe to add that here... */
|
|
- t->offset |= t->tile_bits;
|
|
- }
|
|
- }
|
|
-
|
|
- /* Let the world know we've used this memory recently.
|
|
- */
|
|
- driUpdateTextureLRU((driTextureObject *) t);
|
|
- UNLOCK_HARDWARE(&rmesa->radeon);
|
|
-
|
|
- /* Upload any images that are new */
|
|
- if (t->base.dirty_images[face]) {
|
|
- int i;
|
|
- for (i = 0; i < numLevels; i++) {
|
|
- if ((t->base.
|
|
- dirty_images[face] & (1 <<
|
|
- (i + t->base.firstLevel))) !=
|
|
- 0) {
|
|
- r300UploadSubImage(rmesa, t, i, 0, 0,
|
|
- t->image[face][i].width,
|
|
- t->image[face][i].height,
|
|
- face);
|
|
- }
|
|
- }
|
|
- t->base.dirty_images[face] = 0;
|
|
- }
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_SYNC) {
|
|
- fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
|
|
- radeonFinish(rmesa->radeon.glCtx);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
|
|
index e2329f0..4fea822 100644
|
|
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
|
|
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
|
|
@@ -48,8 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_state.h"
|
|
#include "r300_ioctl.h"
|
|
#include "radeon_ioctl.h"
|
|
+#include "r300_mipmap_tree.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 && \
|
|
@@ -148,8 +150,7 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
|
|
if (!tObj)
|
|
return;
|
|
|
|
- t = (r300TexObjPtr) tObj->DriverData;
|
|
-
|
|
+ t = r300_tex_obj(tObj);
|
|
|
|
switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
|
|
case MESA_FORMAT_Z16:
|
|
@@ -190,399 +191,228 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
|
|
|
|
|
|
/**
|
|
- * Compute sizes and fill in offset and blit information for the given
|
|
- * image (determined by \p face and \p level).
|
|
- *
|
|
- * \param curOffset points to the offset at which the image is to be stored
|
|
- * and is updated by this function according to the size of the image.
|
|
- */
|
|
-static void compute_tex_image_offset(
|
|
- struct gl_texture_object *tObj,
|
|
- GLuint face,
|
|
- GLint level,
|
|
- GLint* curOffset)
|
|
-{
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
- const struct gl_texture_image* texImage;
|
|
- GLuint blitWidth = R300_BLIT_WIDTH_BYTES;
|
|
- GLuint texelBytes;
|
|
- GLuint size;
|
|
-
|
|
- texImage = tObj->Image[0][level + t->base.firstLevel];
|
|
- if (!texImage)
|
|
- return;
|
|
-
|
|
- texelBytes = texImage->TexFormat->TexelBytes;
|
|
-
|
|
- /* find image size in bytes */
|
|
- if (texImage->IsCompressed) {
|
|
- if ((t->format & R300_TX_FORMAT_DXT1) ==
|
|
- R300_TX_FORMAT_DXT1) {
|
|
- // fprintf(stderr,"DXT 1 %d %08X\n", texImage->Width, t->format);
|
|
- if ((texImage->Width + 3) < 8) /* width one block */
|
|
- size = texImage->CompressedSize * 4;
|
|
- else if ((texImage->Width + 3) < 16)
|
|
- size = texImage->CompressedSize * 2;
|
|
- else
|
|
- size = texImage->CompressedSize;
|
|
- } else {
|
|
- /* DXT3/5, 16 bytes per block */
|
|
- WARN_ONCE
|
|
- ("DXT 3/5 suffers from multitexturing problems!\n");
|
|
- // fprintf(stderr,"DXT 3/5 %d\n", texImage->Width);
|
|
- if ((texImage->Width + 3) < 8)
|
|
- size = texImage->CompressedSize * 2;
|
|
- else
|
|
- size = texImage->CompressedSize;
|
|
- }
|
|
- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
|
- size =
|
|
- ((texImage->Width * texelBytes +
|
|
- 63) & ~63) * texImage->Height;
|
|
- blitWidth = 64 / texelBytes;
|
|
- } else if (t->tile_bits & R300_TXO_MICRO_TILE) {
|
|
- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
|
|
- though the actual offset may be different (if texture is less than
|
|
- 32 bytes width) to the untiled case */
|
|
- int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
|
|
- size =
|
|
- (w * ((texImage->Height + 1) / 2)) *
|
|
- texImage->Depth;
|
|
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
|
- } else {
|
|
- int w = (texImage->Width * texelBytes + 31) & ~31;
|
|
- size = w * texImage->Height * texImage->Depth;
|
|
- blitWidth = MAX2(texImage->Width, 64 / texelBytes);
|
|
- }
|
|
- assert(size > 0);
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr, "w=%d h=%d d=%d tb=%d intFormat=%d\n",
|
|
- texImage->Width, texImage->Height,
|
|
- texImage->Depth,
|
|
- texImage->TexFormat->TexelBytes,
|
|
- texImage->InternalFormat);
|
|
-
|
|
- /* All images are aligned to a 32-byte offset */
|
|
- *curOffset = (*curOffset + 0x1f) & ~0x1f;
|
|
-
|
|
- if (texelBytes) {
|
|
- /* fix x and y coords up later together with offset */
|
|
- t->image[face][level].x = *curOffset;
|
|
- t->image[face][level].y = 0;
|
|
- t->image[face][level].width =
|
|
- MIN2(size / texelBytes, blitWidth);
|
|
- t->image[face][level].height =
|
|
- (size / texelBytes) / t->image[face][level].width;
|
|
- } else {
|
|
- t->image[face][level].x = *curOffset % R300_BLIT_WIDTH_BYTES;
|
|
- t->image[face][level].y = *curOffset / R300_BLIT_WIDTH_BYTES;
|
|
- t->image[face][level].width =
|
|
- MIN2(size, R300_BLIT_WIDTH_BYTES);
|
|
- t->image[face][level].height = size / t->image[face][level].width;
|
|
- }
|
|
-
|
|
- if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
- fprintf(stderr,
|
|
- "level %d, face %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
|
|
- level, face, texImage->Width, texImage->Height,
|
|
- t->image[face][level].x, t->image[face][level].y,
|
|
- t->image[face][level].width, t->image[face][level].height,
|
|
- size, *curOffset);
|
|
-
|
|
- *curOffset += size;
|
|
-}
|
|
-
|
|
-
|
|
-
|
|
-/**
|
|
- * This function computes the number of bytes of storage needed for
|
|
- * the given texture object (all mipmap levels, all cube faces).
|
|
- * The \c image[face][level].x/y/width/height parameters for upload/blitting
|
|
- * are computed here. \c filter, \c format, etc. will be set here
|
|
- * too.
|
|
+ * Compute the cached hardware register values for the given texture object.
|
|
*
|
|
* \param rmesa Context pointer
|
|
- * \param tObj GL texture object whose images are to be posted to
|
|
- * hardware state.
|
|
+ * \param t the r300 texture object
|
|
*/
|
|
-static void r300SetTexImages(r300ContextPtr rmesa,
|
|
- struct gl_texture_object *tObj)
|
|
+static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t)
|
|
{
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
- const struct gl_texture_image *baseImage =
|
|
- tObj->Image[0][tObj->BaseLevel];
|
|
- GLint curOffset;
|
|
- GLint i, texelBytes;
|
|
- GLint numLevels;
|
|
- GLint log2Width, log2Height, log2Depth;
|
|
-
|
|
- /* Set the hardware texture format
|
|
- */
|
|
+ const struct gl_texture_image *firstImage =
|
|
+ t->base.Image[0][t->mt->firstLevel];
|
|
+
|
|
if (!t->image_override
|
|
- && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
|
|
- if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
|
|
- r300SetDepthTexMode(tObj);
|
|
+ && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
|
|
+ if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
|
|
+ r300SetDepthTexMode(&t->base);
|
|
} else {
|
|
- t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
|
|
+ t->format = tx_table[firstImage->TexFormat->MesaFormat].format;
|
|
}
|
|
|
|
- t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
|
|
+ t->filter |= tx_table[firstImage->TexFormat->MesaFormat].filter;
|
|
} else if (!t->image_override) {
|
|
_mesa_problem(NULL, "unexpected texture format in %s",
|
|
__FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
- texelBytes = baseImage->TexFormat->TexelBytes;
|
|
-
|
|
- /* Compute which mipmap levels we really want to send to the hardware.
|
|
- */
|
|
- driCalculateTextureFirstLastLevel((driTextureObject *) t);
|
|
- log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
|
|
- log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
|
|
- log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
|
|
-
|
|
- numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
|
-
|
|
- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
|
|
-
|
|
- /* Calculate mipmap offsets and dimensions for blitting (uploading)
|
|
- * The idea is that we lay out the mipmap levels within a block of
|
|
- * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
|
|
- */
|
|
t->tile_bits = 0;
|
|
|
|
- /* figure out if this texture is suitable for tiling. */
|
|
-#if 0 /* Disabled for now */
|
|
- if (texelBytes) {
|
|
- if ((tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
|
|
- /* texrect might be able to use micro tiling too in theory? */
|
|
- (baseImage->Height > 1)) {
|
|
-
|
|
- /* allow 32 (bytes) x 1 mip (which will use two times the space
|
|
- the non-tiled version would use) max if base texture is large enough */
|
|
- if ((numLevels == 1) ||
|
|
- (((baseImage->Width * texelBytes /
|
|
- baseImage->Height) <= 32)
|
|
- && (baseImage->Width * texelBytes > 64))
|
|
- ||
|
|
- ((baseImage->Width * texelBytes /
|
|
- baseImage->Height) <= 16)) {
|
|
- t->tile_bits |= R300_TXO_MICRO_TILE;
|
|
- }
|
|
- }
|
|
-
|
|
- if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
|
|
- /* we can set macro tiling even for small textures, they will be untiled anyway */
|
|
- t->tile_bits |= R300_TXO_MACRO_TILE;
|
|
- }
|
|
- }
|
|
-#endif
|
|
-
|
|
- curOffset = 0;
|
|
-
|
|
- if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
|
- ASSERT(log2Width == log2Height);
|
|
+ if (t->base.Target == GL_TEXTURE_CUBE_MAP)
|
|
t->format |= R300_TX_FORMAT_CUBIC_MAP;
|
|
+ if (t->base.Target == GL_TEXTURE_3D)
|
|
+ t->format |= R300_TX_FORMAT_3D;
|
|
|
|
- for(i = 0; i < numLevels; i++) {
|
|
- GLuint face;
|
|
- for(face = 0; face < 6; face++)
|
|
- compute_tex_image_offset(tObj, face, i, &curOffset);
|
|
- }
|
|
- } else {
|
|
- if (tObj->Target == GL_TEXTURE_3D)
|
|
- t->format |= R300_TX_FORMAT_3D;
|
|
+ t->size = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
|
|
+ | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
|
|
+ | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT);
|
|
|
|
- for (i = 0; i < numLevels; i++)
|
|
- compute_tex_image_offset(tObj, 0, i, &curOffset);
|
|
- }
|
|
-
|
|
- /* Align the total size of texture memory block.
|
|
- */
|
|
- t->base.totalSize =
|
|
- (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
|
|
-
|
|
- t->size =
|
|
- (((tObj->Image[0][t->base.firstLevel]->Width -
|
|
- 1) << R300_TX_WIDTHMASK_SHIFT)
|
|
- | ((tObj->Image[0][t->base.firstLevel]->Height - 1) <<
|
|
- R300_TX_HEIGHTMASK_SHIFT)
|
|
- | ((tObj->Image[0][t->base.firstLevel]->DepthLog2) <<
|
|
- R300_TX_DEPTHMASK_SHIFT))
|
|
- | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT);
|
|
-
|
|
- t->pitch = 0;
|
|
-
|
|
- /* Only need to round to nearest 32 for textures, but the blitter
|
|
- * requires 64-byte aligned pitches, and we may/may not need the
|
|
- * blitter. NPOT only!
|
|
- */
|
|
- if (baseImage->IsCompressed) {
|
|
- t->pitch |=
|
|
- (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
|
|
- } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
|
- unsigned int align = (64 / texelBytes) - 1;
|
|
- t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width *
|
|
- texelBytes) + 63) & ~(63);
|
|
+ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
|
|
+ unsigned int align = (64 / t->mt->bpp) - 1;
|
|
t->size |= R300_TX_SIZE_TXPITCH_EN;
|
|
if (!t->image_override)
|
|
- t->pitch_reg =
|
|
- (((tObj->Image[0][t->base.firstLevel]->Width) +
|
|
- align) & ~align) - 1;
|
|
- } else {
|
|
- t->pitch |=
|
|
- ((tObj->Image[0][t->base.firstLevel]->Width *
|
|
- texelBytes) + 63) & ~(63);
|
|
+ t->pitch_reg = ((firstImage->Width + align) & ~align) - 1;
|
|
}
|
|
|
|
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
|
|
- if (tObj->Image[0][t->base.firstLevel]->Width > 2048)
|
|
+ if (firstImage->Width > 2048)
|
|
t->pitch_reg |= R500_TXWIDTH_BIT11;
|
|
- if (tObj->Image[0][t->base.firstLevel]->Height > 2048)
|
|
+ if (firstImage->Height > 2048)
|
|
t->pitch_reg |= R500_TXHEIGHT_BIT11;
|
|
}
|
|
}
|
|
|
|
-/* ================================================================
|
|
- * Texture unit state management
|
|
- */
|
|
|
|
-static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit)
|
|
+static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
|
|
+ GLuint numrows, GLuint rowsize)
|
|
{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
- struct gl_texture_object *tObj = texUnit->_Current;
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
-
|
|
- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
|
|
-
|
|
- if (t->base.dirty_images[0]) {
|
|
- R300_FIREVERTICES(rmesa);
|
|
+ assert(rowsize <= dststride);
|
|
+ assert(rowsize <= srcstride);
|
|
|
|
- r300SetTexImages(rmesa, tObj);
|
|
- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
|
|
- if (!t->base.memBlock && !t->image_override)
|
|
- return GL_FALSE;
|
|
+ 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;
|
|
+ }
|
|
}
|
|
-
|
|
- return GL_TRUE;
|
|
}
|
|
|
|
-static GLboolean r300EnableTexture3D(GLcontext * ctx, int unit)
|
|
+
|
|
+/**
|
|
+ * Ensure that the given image is stored in the given miptree from now on.
|
|
+ */
|
|
+static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *image, int face, int level)
|
|
{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
- struct gl_texture_object *tObj = texUnit->_Current;
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
+ r300_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
|
|
+ unsigned char *dest;
|
|
|
|
- ASSERT(tObj->Target == GL_TEXTURE_3D);
|
|
+ assert(image->mt != mt);
|
|
+ assert(dstlvl->width == image->base.Width);
|
|
+ assert(dstlvl->height == image->base.Height);
|
|
+ assert(dstlvl->depth == image->base.Depth);
|
|
|
|
- /* r300 does not support mipmaps for 3D textures. */
|
|
- if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
|
|
- return GL_FALSE;
|
|
- }
|
|
+ radeon_bo_map(mt->bo, GL_TRUE);
|
|
+ dest = mt->bo->ptr + dstlvl->faces[face].offset;
|
|
|
|
- if (t->base.dirty_images[0]) {
|
|
- R300_FIREVERTICES(rmesa);
|
|
- r300SetTexImages(rmesa, tObj);
|
|
- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
|
|
- if (!t->base.memBlock)
|
|
- return GL_FALSE;
|
|
- }
|
|
+ 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.
|
|
+ */
|
|
+ r300_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
|
|
|
|
- return GL_TRUE;
|
|
-}
|
|
+ assert(srclvl->size == dstlvl->size);
|
|
+ assert(srclvl->rowstride == dstlvl->rowstride);
|
|
|
|
-static GLboolean r300EnableTextureCube(GLcontext * ctx, int unit)
|
|
-{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
- struct gl_texture_object *tObj = texUnit->_Current;
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
- GLuint face;
|
|
-
|
|
- ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
|
|
-
|
|
- if (t->base.dirty_images[0] || t->base.dirty_images[1] ||
|
|
- t->base.dirty_images[2] || t->base.dirty_images[3] ||
|
|
- t->base.dirty_images[4] || t->base.dirty_images[5]) {
|
|
- /* flush */
|
|
- R300_FIREVERTICES(rmesa);
|
|
- /* layout memory space, once for all faces */
|
|
- r300SetTexImages(rmesa, tObj);
|
|
- }
|
|
+ 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);
|
|
|
|
- /* upload (per face) */
|
|
- for (face = 0; face < 6; face++) {
|
|
- if (t->base.dirty_images[face]) {
|
|
- r300UploadTexImages(rmesa,
|
|
- (r300TexObjPtr) tObj->DriverData,
|
|
- face);
|
|
- }
|
|
- }
|
|
+ r300_miptree_unreference(image->mt);
|
|
+ } else {
|
|
+ uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
|
|
|
|
- if (!t->base.memBlock) {
|
|
- /* texmem alloc failed, use s/w fallback */
|
|
- return GL_FALSE;
|
|
+ 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;
|
|
}
|
|
|
|
- return GL_TRUE;
|
|
+ radeon_bo_unmap(mt->bo);
|
|
+
|
|
+ image->mt = mt;
|
|
+ image->mtface = face;
|
|
+ image->mtlevel = level;
|
|
+ r300_miptree_reference(image->mt);
|
|
}
|
|
|
|
-static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit)
|
|
+
|
|
+/**
|
|
+ * Ensure the given texture is ready for rendering.
|
|
+ *
|
|
+ * Mostly this means populating the texture object's mipmap tree.
|
|
+ */
|
|
+static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
|
|
{
|
|
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
- struct gl_texture_object *tObj = texUnit->_Current;
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
+ r300TexObj *t = r300_tex_obj(texObj);
|
|
+ r300_texture_image *baseimage = get_r300_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);
|
|
|
|
- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
|
|
+ if (baseimage->base.Border > 0)
|
|
+ return GL_FALSE;
|
|
|
|
- if (t->base.dirty_images[0]) {
|
|
- R300_FIREVERTICES(rmesa);
|
|
+ /* 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 &&
|
|
+ r300_miptree_matches_texture(baseimage->mt, &t->base)) {
|
|
+ r300_miptree_unreference(t->mt);
|
|
+ t->mt = baseimage->mt;
|
|
+ r300_miptree_reference(t->mt);
|
|
+ } else if (t->mt && !r300_miptree_matches_texture(t->mt, &t->base)) {
|
|
+ r300_miptree_unreference(t->mt);
|
|
+ t->mt = 0;
|
|
+ }
|
|
|
|
- r300SetTexImages(rmesa, tObj);
|
|
- r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0);
|
|
- if (!t->base.memBlock && !t->image_override &&
|
|
- !rmesa->prefer_gart_client_texturing)
|
|
+ if (!t->mt) {
|
|
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
+ fprintf(stderr, " Allocate new miptree\n");
|
|
+ r300_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) {
|
|
+ r300_texture_image *image = get_r300_texture_image(texObj->Image[face][level]);
|
|
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
|
|
+ fprintf(stderr, " face %i, level %i... ", face, level);
|
|
+ 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);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Configure the hardware registers (more precisely, the cached version
|
|
+ * of the hardware registers). */
|
|
+ setup_hardware_state(rmesa, t);
|
|
+
|
|
+ t->validated = GL_TRUE;
|
|
return GL_TRUE;
|
|
}
|
|
|
|
-static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
|
|
+
|
|
+/**
|
|
+ * Ensure all enabled and complete textures are uploaded.
|
|
+ */
|
|
+void r300ValidateTextures(GLcontext * ctx)
|
|
{
|
|
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
- struct gl_texture_object *tObj = texUnit->_Current;
|
|
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
|
|
+ int i;
|
|
|
|
- /* Fallback if there's a texture border */
|
|
- if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
|
|
- return GL_FALSE;
|
|
+ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
|
|
+ if (!ctx->Texture.Unit[i]._ReallyEnabled)
|
|
+ continue;
|
|
|
|
- /* Update state if this is a different texture object to last
|
|
- * time.
|
|
- */
|
|
- if (rmesa->state.texture.unit[unit].texobj != t) {
|
|
- if (rmesa->state.texture.unit[unit].texobj != NULL) {
|
|
- /* The old texture is no longer bound to this texture unit.
|
|
- * Mark it as such.
|
|
- */
|
|
-
|
|
- rmesa->state.texture.unit[unit].texobj->base.bound &=
|
|
- ~(1 << unit);
|
|
+ if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
|
|
+ _mesa_warning(ctx,
|
|
+ "failed to validate texture for unit %d.\n",
|
|
+ i);
|
|
}
|
|
-
|
|
- rmesa->state.texture.unit[unit].texobj = t;
|
|
- t->base.bound |= (1 << unit);
|
|
- driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */
|
|
}
|
|
-
|
|
- return !t->border_fallback;
|
|
}
|
|
|
|
void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
|
|
@@ -591,20 +421,18 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
|
|
r300ContextPtr rmesa = pDRICtx->driverPrivate;
|
|
struct gl_texture_object *tObj =
|
|
_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
|
|
- r300TexObjPtr t;
|
|
+ r300TexObjPtr t = r300_tex_obj(tObj);
|
|
uint32_t pitch_val;
|
|
|
|
if (!tObj)
|
|
return;
|
|
|
|
- t = (r300TexObjPtr) tObj->DriverData;
|
|
-
|
|
t->image_override = GL_TRUE;
|
|
|
|
if (!offset)
|
|
return;
|
|
-
|
|
- t->offset = offset;
|
|
+ t->bo = NULL;
|
|
+ t->override_offset = offset;
|
|
t->pitch_reg &= (1 << 13) -1;
|
|
pitch_val = pitch;
|
|
|
|
@@ -631,38 +459,96 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
|
|
t->pitch_reg |= pitch_val;
|
|
}
|
|
|
|
-static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
|
|
+void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
|
|
{
|
|
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
|
-
|
|
- if (texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT)) {
|
|
- return (r300EnableTextureRect(ctx, unit) &&
|
|
- r300UpdateTexture(ctx, unit));
|
|
- } else if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
|
|
- return (r300EnableTexture2D(ctx, unit) &&
|
|
- r300UpdateTexture(ctx, unit));
|
|
- } else if (texUnit->_ReallyEnabled & (TEXTURE_3D_BIT)) {
|
|
- return (r300EnableTexture3D(ctx, unit) &&
|
|
- r300UpdateTexture(ctx, unit));
|
|
- } else if (texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT)) {
|
|
- return (r300EnableTextureCube(ctx, unit) &&
|
|
- r300UpdateTexture(ctx, unit));
|
|
- } else if (texUnit->_ReallyEnabled) {
|
|
- return GL_FALSE;
|
|
- } else {
|
|
- return GL_TRUE;
|
|
- }
|
|
-}
|
|
-
|
|
-void r300UpdateTextureState(GLcontext * ctx)
|
|
-{
|
|
- int i;
|
|
+ struct gl_texture_unit *texUnit;
|
|
+ struct gl_texture_object *texObj;
|
|
+ struct gl_texture_image *texImage;
|
|
+ struct radeon_renderbuffer *rb;
|
|
+ r300_texture_image *rImage;
|
|
+ radeonContextPtr radeon;
|
|
+ r300ContextPtr rmesa;
|
|
+ GLframebuffer *fb;
|
|
+ r300TexObjPtr t;
|
|
+ uint32_t pitch_val;
|
|
|
|
- for (i = 0; i < 8; i++) {
|
|
- if (!r300UpdateTextureUnit(ctx, i)) {
|
|
- _mesa_warning(ctx,
|
|
- "failed to update texture state for unit %d.\n",
|
|
- i);
|
|
- }
|
|
+ target = GL_TEXTURE_RECTANGLE_ARB;
|
|
+ radeon = pDRICtx->driverPrivate;
|
|
+ rmesa = pDRICtx->driverPrivate;
|
|
+ fb = dPriv->driverPrivate;
|
|
+ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
|
|
+ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
|
|
+ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
|
|
+ rImage = get_r300_texture_image(texImage);
|
|
+ t = r300_tex_obj(texObj);
|
|
+ if (t == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ radeon_update_renderbuffers(pDRICtx, dPriv);
|
|
+ /* back & depth buffer are useless free them right away */
|
|
+ rb = (void*)fb->Attachment[BUFFER_DEPTH].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_FRONT_LEFT].Renderbuffer;
|
|
+ if (rb->bo == NULL) {
|
|
+ /* Failed to BO for the buffer */
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ _mesa_lock_texture(radeon->glCtx, texObj);
|
|
+ if (t->bo) {
|
|
+ t->bo = NULL;
|
|
+ }
|
|
+ if (t->mt) {
|
|
+ t->mt = NULL;
|
|
+ }
|
|
+ if (rImage->mt) {
|
|
+ r300_miptree_unreference(rImage->mt);
|
|
+ rImage->mt = NULL;
|
|
+ }
|
|
+ _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
|
|
+ rb->width, rb->height, rb->cpp, 0, rb->cpp);
|
|
+ texImage->TexFormat = &_mesa_texformat_rgba8888_rev;
|
|
+ rImage->bo = rb->bo;
|
|
+
|
|
+ t->bo = rb->bo;
|
|
+ t->tile_bits = 0;
|
|
+ t->image_override = GL_TRUE;
|
|
+ t->override_offset = 0;
|
|
+ t->pitch_reg &= (1 << 13) -1;
|
|
+ pitch_val = rb->pitch;
|
|
+ switch (rb->cpp) {
|
|
+ case 4:
|
|
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
|
|
+ t->filter |= tx_table[2].filter;
|
|
+ pitch_val /= 4;
|
|
+ break;
|
|
+ case 3:
|
|
+ default:
|
|
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
|
|
+ t->filter |= tx_table[4].filter;
|
|
+ pitch_val /= 4;
|
|
+ break;
|
|
+ case 2:
|
|
+ t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
|
|
+ t->filter |= tx_table[5].filter;
|
|
+ pitch_val /= 2;
|
|
+ break;
|
|
}
|
|
+ pitch_val--;
|
|
+ t->size = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
|
|
+ ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
|
|
+ t->size |= R300_TX_SIZE_TXPITCH_EN;
|
|
+ t->pitch_reg |= pitch_val;
|
|
+ t->validated = GL_TRUE;
|
|
+ _mesa_unlock_texture(radeon->glCtx, texObj);
|
|
+ return;
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
|
|
index 5267fe9..2bb679b 100644
|
|
--- a/src/mesa/drivers/dri/r300/radeon_context.c
|
|
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
|
|
@@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "drivers/common/driverfuncs.h"
|
|
#include "swrast/swrast.h"
|
|
|
|
+#include "radeon_buffer.h"
|
|
#include "radeon_screen.h"
|
|
#include "radeon_ioctl.h"
|
|
#include "radeon_macros.h"
|
|
@@ -57,6 +58,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "utils.h"
|
|
#include "vblank.h"
|
|
#include "xmlpool.h" /* for symbolic values of enum-type options */
|
|
+#include "drirenderbuffer.h"
|
|
|
|
#define DRIVER_DATE "20060815"
|
|
|
|
@@ -189,6 +191,43 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
|
|
*/
|
|
void radeonCleanupContext(radeonContextPtr radeon)
|
|
{
|
|
+ FILE *track;
|
|
+ struct radeon_renderbuffer *rb;
|
|
+ GLframebuffer *fb;
|
|
+
|
|
+ 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.
|
|
*
|
|
@@ -202,6 +241,11 @@ void radeonCleanupContext(radeonContextPtr radeon)
|
|
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);
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -218,7 +262,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 {
|
|
@@ -258,6 +302,232 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
|
|
}
|
|
}
|
|
|
|
+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;
|
|
+ }
|
|
+}
|
|
+
|
|
+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;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+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;
|
|
+ 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'.
|
|
*/
|
|
@@ -265,51 +535,71 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
|
|
__DRIdrawablePrivate * driDrawPriv,
|
|
__DRIdrawablePrivate * driReadPriv)
|
|
{
|
|
- if (driContextPriv) {
|
|
- radeonContextPtr radeon =
|
|
- (radeonContextPtr) driContextPriv->driverPrivate;
|
|
+ radeonContextPtr radeon;
|
|
+ GLframebuffer *dfb, *rfb;
|
|
|
|
+ if (!driContextPriv) {
|
|
if (RADEON_DEBUG & DEBUG_DRI)
|
|
- fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
|
|
- radeon->glCtx);
|
|
-
|
|
- if (radeon->dri.drawable != driDrawPriv) {
|
|
- if (driDrawPriv->swap_interval == (unsigned)-1) {
|
|
- driDrawPriv->vblFlags =
|
|
- (radeon->radeonScreen->irq != 0)
|
|
- ? driGetDefaultVBlankFlags(&radeon->
|
|
- optionCache)
|
|
- : VBLANK_FLAG_NO_IRQ;
|
|
+ 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_buffer =
|
|
+ (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer;
|
|
+ }
|
|
|
|
- driDrawableInitVBlank(driDrawPriv);
|
|
- }
|
|
- }
|
|
|
|
- radeon->dri.readable = driReadPriv;
|
|
+ if (RADEON_DEBUG & DEBUG_DRI)
|
|
+ fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx);
|
|
|
|
- if (radeon->dri.drawable != driDrawPriv ||
|
|
- radeon->lastStamp != driDrawPriv->lastStamp) {
|
|
- radeon->dri.drawable = driDrawPriv;
|
|
+ driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
|
|
+ if (driReadPriv != driDrawPriv)
|
|
+ driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
|
|
+
|
|
+ if (!driContextPriv->driScreenPriv->dri2.enabled) {
|
|
+ radeon_make_renderbuffer_current(radeon, dfb);
|
|
+ }
|
|
+
|
|
+ _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;
|
|
|
|
- radeonSetCliprects(radeon);
|
|
- r300UpdateViewportOffset(radeon->glCtx);
|
|
+ driDrawableInitVBlank(driDrawPriv);
|
|
}
|
|
+ }
|
|
|
|
- _mesa_make_current(radeon->glCtx,
|
|
- (GLframebuffer *) driDrawPriv->
|
|
- driverPrivate,
|
|
- (GLframebuffer *) driReadPriv->
|
|
- driverPrivate);
|
|
+ radeon->dri.readable = driReadPriv;
|
|
|
|
- _mesa_update_state(radeon->glCtx);
|
|
+ if (radeon->dri.drawable != driDrawPriv ||
|
|
+ radeon->lastStamp != driDrawPriv->lastStamp) {
|
|
+ radeon->dri.drawable = driDrawPriv;
|
|
|
|
- radeonUpdatePageFlipping(radeon);
|
|
- } else {
|
|
- if (RADEON_DEBUG & DEBUG_DRI)
|
|
- fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
|
|
- _mesa_make_current(0, 0, 0);
|
|
+ radeonSetCliprects(radeon);
|
|
+ r300UpdateViewportOffset(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/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
|
|
index 47cbc22..d5bbf29 100644
|
|
--- a/src/mesa/drivers/dri/r300/radeon_context.h
|
|
+++ b/src/mesa/drivers/dri/r300/radeon_context.h
|
|
@@ -132,12 +132,13 @@ struct radeon_scissor_state {
|
|
|
|
struct radeon_colorbuffer_state {
|
|
GLuint clear;
|
|
- GLint drawOffset, drawPitch;
|
|
+ struct radeon_renderbuffer *rrb;
|
|
};
|
|
|
|
struct radeon_state {
|
|
struct radeon_colorbuffer_state color;
|
|
struct radeon_scissor_state scissor;
|
|
+ struct radeon_renderbuffer *depth_buffer;
|
|
};
|
|
|
|
/**
|
|
@@ -202,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_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c
|
|
index 36502eb..c8d6bf9 100644
|
|
--- a/src/mesa/drivers/dri/r300/radeon_ioctl.c
|
|
+++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c
|
|
@@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "swrast/swrast.h"
|
|
#include "r300_context.h"
|
|
#include "radeon_ioctl.h"
|
|
+#include "radeon_buffer.h"
|
|
#include "r300_ioctl.h"
|
|
#include "r300_state.h"
|
|
#include "radeon_reg.h"
|
|
@@ -171,7 +172,7 @@ void radeonCopyBuffer(__DRIdrawablePrivate * dPriv,
|
|
assert(dPriv->driContextPriv->driverPrivate);
|
|
|
|
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
|
-
|
|
+
|
|
if (RADEON_DEBUG & DEBUG_IOCTL) {
|
|
fprintf(stderr, "\n%s( %p )\n\n", __FUNCTION__,
|
|
(void *)radeon->glCtx);
|
|
@@ -261,6 +262,8 @@ void radeonPageFlip(__DRIdrawablePrivate * dPriv)
|
|
GLint ret;
|
|
GLboolean missed_target;
|
|
__DRIscreenPrivate *psp = dPriv->driScreenPriv;
|
|
+ GLframebuffer *fb = dPriv->driverPrivate;
|
|
+ struct radeon_renderbuffer *rrb;
|
|
|
|
assert(dPriv);
|
|
assert(dPriv->driContextPriv);
|
|
@@ -268,6 +271,8 @@ void radeonPageFlip(__DRIdrawablePrivate * dPriv)
|
|
|
|
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
|
|
|
|
+ rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
|
+
|
|
if (RADEON_DEBUG & DEBUG_IOCTL) {
|
|
fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
|
|
radeon->sarea->pfCurrentPage);
|
|
@@ -315,32 +320,10 @@ void radeonPageFlip(__DRIdrawablePrivate * dPriv)
|
|
radeon->swap_count++;
|
|
(void)(*psp->systemTime->getUST) (&radeon->swap_ust);
|
|
|
|
- driFlipRenderbuffers(radeon->glCtx->WinSysDrawBuffer,
|
|
+ driFlipRenderbuffers(radeon->glCtx->WinSysDrawBuffer,
|
|
radeon->sarea->pfCurrentPage);
|
|
|
|
- if (radeon->sarea->pfCurrentPage == 1) {
|
|
- radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
|
|
- radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
|
|
- } else {
|
|
- radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
|
|
- radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
|
|
- }
|
|
-
|
|
- if (IS_R300_CLASS(radeon->radeonScreen)) {
|
|
- r300ContextPtr r300 = (r300ContextPtr)radeon;
|
|
- R300_STATECHANGE(r300, cb);
|
|
- r300->hw.cb.cmd[R300_CB_OFFSET] = r300->radeon.state.color.drawOffset +
|
|
- r300->radeon.radeonScreen->fbLocation;
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
|
|
-
|
|
- if (r300->radeon.radeonScreen->cpp == 4)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
|
|
- else
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
|
|
-
|
|
- if (r300->radeon.sarea->tiling_enabled)
|
|
- r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
|
|
- }
|
|
+ radeon->state.color.rrb = rrb;
|
|
}
|
|
|
|
void radeonWaitForIdleLocked(radeonContextPtr radeon)
|
|
@@ -391,6 +374,7 @@ void radeonFinish(GLcontext * ctx)
|
|
radeonEmitIrqLocked(radeon);
|
|
UNLOCK_HARDWARE(radeon);
|
|
radeonWaitIrq(radeon);
|
|
- } else
|
|
+ } else {
|
|
radeonWaitForIdle(radeon);
|
|
+ }
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c
|
|
index 4f47afd..a1b2163 100644
|
|
--- a/src/mesa/drivers/dri/r300/radeon_lock.c
|
|
+++ b/src/mesa/drivers/dri/r300/radeon_lock.c
|
|
@@ -59,11 +59,11 @@ int prevLockLine = 0;
|
|
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) {
|
|
- driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
|
|
- rmesa->sarea->pfCurrentPage);
|
|
r300UpdateDrawBuffer(rmesa->glCtx);
|
|
}
|
|
|
|
@@ -72,16 +72,12 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa)
|
|
BUFFER_BACK_LEFT) : 1;
|
|
use_back ^= (rmesa->sarea->pfCurrentPage == 1);
|
|
|
|
- if (use_back) {
|
|
- rmesa->state.color.drawOffset =
|
|
- rmesa->radeonScreen->backOffset;
|
|
- rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
|
|
- } else {
|
|
- rmesa->state.color.drawOffset =
|
|
- rmesa->radeonScreen->frontOffset;
|
|
- rmesa->state.color.drawPitch =
|
|
- rmesa->radeonScreen->frontPitch;
|
|
- }
|
|
+ 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_buffer = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
|
|
}
|
|
|
|
/* Update the hardware state. This is called if another context has
|
|
@@ -98,7 +94,6 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
|
|
__DRIdrawablePrivate *const readable = rmesa->dri.readable;
|
|
__DRIscreenPrivate *sPriv = rmesa->dri.screen;
|
|
drm_radeon_sarea_t *sarea = rmesa->sarea;
|
|
- r300ContextPtr r300 = (r300ContextPtr) rmesa;
|
|
|
|
assert(drawable != NULL);
|
|
|
|
@@ -125,12 +120,9 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
|
|
}
|
|
|
|
if (sarea->ctx_owner != rmesa->dri.hwContext) {
|
|
- int i;
|
|
-
|
|
sarea->ctx_owner = rmesa->dri.hwContext;
|
|
- for (i = 0; i < r300->nr_heaps; i++) {
|
|
- DRI_AGE_TEXTURES(r300->texture_heaps[i]);
|
|
- }
|
|
+ if (!rmesa->radeonScreen->kernel_mm)
|
|
+ radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom);
|
|
}
|
|
|
|
rmesa->lost_context = GL_TRUE;
|
|
diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h
|
|
index a344837..eaef49c 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 16f9fb9..30dde80 100644
|
|
--- a/src/mesa/drivers/dri/r300/radeon_span.c
|
|
+++ b/src/mesa/drivers/dri/r300/radeon_span.c
|
|
@@ -48,7 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#include "r300_ioctl.h"
|
|
#include "radeon_span.h"
|
|
|
|
-#include "drirenderbuffer.h"
|
|
+#include "radeon_buffer.h"
|
|
|
|
#define DBG 0
|
|
|
|
@@ -58,21 +58,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
* information.
|
|
*/
|
|
#define LOCAL_VARS \
|
|
- driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
|
- const __DRIdrawablePrivate *dPriv = drb->dPriv; \
|
|
+ struct radeon_renderbuffer *rrb = (void *) rb; \
|
|
+ const __DRIdrawablePrivate *dPriv = rrb->dPriv; \
|
|
const GLuint bottom = dPriv->h - 1; \
|
|
- GLubyte *buf = (GLubyte *) drb->flippedData \
|
|
- + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \
|
|
- GLuint p; \
|
|
- (void) p;
|
|
+ GLuint p; \
|
|
+ (void)p;
|
|
|
|
#define LOCAL_DEPTH_VARS \
|
|
- driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
|
- const __DRIdrawablePrivate *dPriv = drb->dPriv; \
|
|
+ struct radeon_renderbuffer *rrb = (void *) rb; \
|
|
+ const __DRIdrawablePrivate *dPriv = rrb->dPriv; \
|
|
const GLuint bottom = dPriv->h - 1; \
|
|
GLuint xo = dPriv->x; \
|
|
- GLuint yo = dPriv->y; \
|
|
- GLubyte *buf = (GLubyte *) drb->Base.Data;
|
|
+ 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) * drb->flippedPitch + (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) * drb->flippedPitch + (X)) * 4)
|
|
+#define GET_PTR(X,Y) radeon_ptr32(rrb, (X), (Y))
|
|
#include "spantmp2.h"
|
|
|
|
/* ================================================================
|
|
@@ -120,65 +244,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
* too...
|
|
*/
|
|
|
|
-static GLuint radeon_mba_z32(const driRenderbuffer * drb, GLint x, GLint y)
|
|
-{
|
|
- GLuint pitch = drb->pitch;
|
|
- if (drb->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 driRenderbuffer * drb, GLint x, GLint y)
|
|
-{
|
|
- GLuint pitch = drb->pitch;
|
|
- if (drb->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( drb, _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( drb, _x + xo, _y + yo ));
|
|
+ d = *(GLushort *)radeon_ptr(rrb, _x + xo, _y + yo)
|
|
|
|
#define TAG(x) radeon##x##_z16
|
|
#include "depthtmp.h"
|
|
@@ -193,35 +267,36 @@ radeon_mba_z16(const driRenderbuffer * drb, GLint x, GLint y)
|
|
#ifdef COMPILE_R300
|
|
#define WRITE_DEPTH( _x, _y, d ) \
|
|
do { \
|
|
- GLuint offset = radeon_mba_z32( drb, _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( drb, _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( drb, _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( drb, _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"
|
|
|
|
@@ -234,35 +309,35 @@ do { \
|
|
#ifdef COMPILE_R300
|
|
#define WRITE_STENCIL( _x, _y, d ) \
|
|
do { \
|
|
- GLuint offset = radeon_mba_z32( drb, _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( drb, _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( drb, _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( drb, _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
|
|
@@ -270,6 +345,29 @@ 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);
|
|
+ }
|
|
+}
|
|
+
|
|
/* Move locking out to get reasonable span performance (10x better
|
|
* than doing this in HW_LOCK above). WaitForIdle() is the main
|
|
* culprit.
|
|
@@ -278,45 +376,63 @@ do { \
|
|
static void radeonSpanRenderStart(GLcontext * ctx)
|
|
{
|
|
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
|
|
+ int i;
|
|
#ifdef COMPILE_R300
|
|
r300ContextPtr r300 = (r300ContextPtr) rmesa;
|
|
R300_FIREVERTICES(r300);
|
|
#else
|
|
RADEON_FIREVERTICES(rmesa);
|
|
#endif
|
|
- LOCK_HARDWARE(rmesa);
|
|
- radeonWaitForIdleLocked(rmesa);
|
|
|
|
- /* Read the first pixel in the frame buffer. This should
|
|
- * be a noop, right? In fact without this conform fails as reading
|
|
- * from the framebuffer sometimes produces old results -- the
|
|
- * on-card read cache gets mixed up and doesn't notice that the
|
|
- * framebuffer has been updated.
|
|
- *
|
|
- * Note that we should probably be reading some otherwise unused
|
|
- * region of VRAM, otherwise we might get incorrect results when
|
|
- * reading pixels from the top left of the screen.
|
|
- *
|
|
- * I found this problem on an R420 with glean's texCube test.
|
|
- * Note that the R200 span code also *writes* the first pixel in the
|
|
- * framebuffer, but I've found this to be unnecessary.
|
|
- * -- Nicolai Hähnle, June 2008
|
|
- */
|
|
- {
|
|
- int p;
|
|
- driRenderbuffer *drb =
|
|
- (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0];
|
|
- volatile int *buf =
|
|
- (volatile int *)(rmesa->dri.screen->pFB + drb->offset);
|
|
- p = *buf;
|
|
+ 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)
|
|
@@ -330,20 +446,17 @@ void radeonInitSpanFuncs(GLcontext * ctx)
|
|
/**
|
|
* Plug in the Get/Put routines for the given driRenderbuffer.
|
|
*/
|
|
-void radeonSetSpanFunctions(driRenderbuffer * drb, const GLvisual * vis)
|
|
+void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
|
|
{
|
|
- if (drb->Base.InternalFormat == GL_RGBA) {
|
|
- if (vis->redBits == 5 && vis->greenBits == 6
|
|
- && vis->blueBits == 5) {
|
|
- radeonInitPointers_RGB565(&drb->Base);
|
|
- } else {
|
|
- radeonInitPointers_ARGB8888(&drb->Base);
|
|
- }
|
|
- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
|
|
- radeonInitDepthPointers_z16(&drb->Base);
|
|
- } else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
|
|
- radeonInitDepthPointers_z24_s8(&drb->Base);
|
|
- } else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
|
|
- radeonInitStencilPointers_z24_s8(&drb->Base);
|
|
+ if (rrb->base.InternalFormat == GL_RGB5) {
|
|
+ radeonInitPointers_RGB565(&rrb->base);
|
|
+ } else if (rrb->base.InternalFormat == GL_RGBA8) {
|
|
+ radeonInitPointers_ARGB8888(&rrb->base);
|
|
+ } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT16) {
|
|
+ radeonInitDepthPointers_z16(&rrb->base);
|
|
+ } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT24) {
|
|
+ radeonInitDepthPointers_z24_s8(&rrb->base);
|
|
+ } else if (rrb->base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
|
|
+ radeonInitStencilPointers_z24_s8(&rrb->base);
|
|
}
|
|
}
|
|
diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c
|
|
index c401da6..14d489b 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)) {
|
|
@@ -223,14 +225,6 @@ void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state)
|
|
void radeonInitState(radeonContextPtr radeon)
|
|
{
|
|
radeon->Fallback = 0;
|
|
-
|
|
- if (radeon->glCtx->Visual.doubleBufferMode && radeon->sarea->pfCurrentPage == 0) {
|
|
- radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
|
|
- radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
|
|
- } else {
|
|
- radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
|
|
- radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
|
|
- }
|
|
}
|
|
|
|
|
|
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
|
|
new file mode 100644
|
|
index 0000000..3aa1d86
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
|
|
@@ -0,0 +1,724 @@
|
|
+/*
|
|
+ * Copyright © 2008 Nicolai Haehnle
|
|
+ * Copyright © 2008 Dave Airlie
|
|
+ * 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 <aet@rasterburn.org>
|
|
+ * Nicolai Haehnle <prefect_@gmx.net>
|
|
+ * Dave Airlie
|
|
+ * Jérôme Glisse <glisse@freedesktop.org>
|
|
+ */
|
|
+#include <stdio.h>
|
|
+#include <stdint.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <errno.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/mman.h>
|
|
+#include <sys/ioctl.h>
|
|
+#include "xf86drm.h"
|
|
+#include "drm.h"
|
|
+#include "radeon_drm.h"
|
|
+#include "radeon_bo.h"
|
|
+#include "radeon_bo_legacy.h"
|
|
+#include "radeon_ioctl.h"
|
|
+#include "texmem.h"
|
|
+
|
|
+struct bo_legacy {
|
|
+ struct radeon_bo base;
|
|
+ driTextureObject tobj_base;
|
|
+ int map_count;
|
|
+ uint32_t pending;
|
|
+ int is_pending;
|
|
+ int validated;
|
|
+ int static_bo;
|
|
+ int got_dri_texture_obj;
|
|
+ int dirty;
|
|
+ uint32_t offset;
|
|
+ driTextureObject dri_texture_obj;
|
|
+ void *ptr;
|
|
+ struct bo_legacy *next, *prev;
|
|
+ struct bo_legacy *pnext, *pprev;
|
|
+};
|
|
+
|
|
+struct bo_manager_legacy {
|
|
+ struct radeon_bo_manager base;
|
|
+ unsigned nhandle;
|
|
+ unsigned nfree_handles;
|
|
+ unsigned cfree_handles;
|
|
+ uint32_t current_age;
|
|
+ struct bo_legacy bos;
|
|
+ struct bo_legacy pending_bos;
|
|
+ uint32_t fb_location;
|
|
+ uint32_t texture_offset;
|
|
+ unsigned dma_alloc_size;
|
|
+ unsigned cpendings;
|
|
+ driTextureObject texture_swapped;
|
|
+ driTexHeap *texture_heap;
|
|
+ struct radeon_screen *screen;
|
|
+ unsigned *free_handles;
|
|
+};
|
|
+
|
|
+static void bo_legacy_tobj_destroy(void *data, driTextureObject *t)
|
|
+{
|
|
+ struct bo_legacy *bo_legacy;
|
|
+
|
|
+ bo_legacy = (struct bo_legacy*)((char*)t)-sizeof(struct radeon_bo);
|
|
+ bo_legacy->got_dri_texture_obj = 0;
|
|
+ bo_legacy->validated = 0;
|
|
+}
|
|
+
|
|
+static int legacy_new_handle(struct bo_manager_legacy *bom, uint32_t *handle)
|
|
+{
|
|
+ uint32_t tmp;
|
|
+
|
|
+ *handle = 0;
|
|
+ if (bom->nhandle == 0xFFFFFFFF) {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (bom->cfree_handles > 0) {
|
|
+ tmp = bom->free_handles[--bom->cfree_handles];
|
|
+ while (!bom->free_handles[bom->cfree_handles - 1]) {
|
|
+ bom->cfree_handles--;
|
|
+ if (bom->cfree_handles <= 0) {
|
|
+ bom->cfree_handles = 0;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ bom->cfree_handles = 0;
|
|
+ tmp = bom->nhandle++;
|
|
+ }
|
|
+ assert(tmp);
|
|
+ *handle = tmp;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int legacy_free_handle(struct bo_manager_legacy *bom, uint32_t handle)
|
|
+{
|
|
+ uint32_t *handles;
|
|
+
|
|
+ if (!handle) {
|
|
+ return 0;
|
|
+ }
|
|
+ if (handle == (bom->nhandle - 1)) {
|
|
+ int i;
|
|
+
|
|
+ bom->nhandle--;
|
|
+ for (i = bom->cfree_handles - 1; i >= 0; i--) {
|
|
+ if (bom->free_handles[i] == (bom->nhandle - 1)) {
|
|
+ bom->nhandle--;
|
|
+ bom->free_handles[i] = 0;
|
|
+ }
|
|
+ }
|
|
+ while (!bom->free_handles[bom->cfree_handles - 1]) {
|
|
+ bom->cfree_handles--;
|
|
+ if (bom->cfree_handles <= 0) {
|
|
+ bom->cfree_handles = 0;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+ if (bom->cfree_handles < bom->nfree_handles) {
|
|
+ bom->free_handles[bom->cfree_handles++] = handle;
|
|
+ return 0;
|
|
+ }
|
|
+ bom->nfree_handles += 0x100;
|
|
+ handles = (uint32_t*)realloc(bom->free_handles, bom->nfree_handles * 4);
|
|
+ if (handles == NULL) {
|
|
+ bom->nfree_handles -= 0x100;
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ bom->free_handles = handles;
|
|
+ bom->free_handles[bom->cfree_handles++] = handle;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void legacy_get_current_age(struct bo_manager_legacy *boml)
|
|
+{
|
|
+ drm_radeon_getparam_t gp;
|
|
+ int r;
|
|
+
|
|
+ gp.param = RADEON_PARAM_LAST_CLEAR;
|
|
+ gp.value = (int *)&boml->current_age;
|
|
+ r = drmCommandWriteRead(boml->base.fd, DRM_RADEON_GETPARAM,
|
|
+ &gp, sizeof(gp));
|
|
+ if (r) {
|
|
+ fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r);
|
|
+ exit(1);
|
|
+ }
|
|
+}
|
|
+
|
|
+static int legacy_is_pending(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ if (bo_legacy->is_pending <= 0) {
|
|
+ bo_legacy->is_pending = 0;
|
|
+ return 0;
|
|
+ }
|
|
+ if (boml->current_age >= bo_legacy->pending) {
|
|
+ if (boml->pending_bos.pprev == bo_legacy) {
|
|
+ boml->pending_bos.pprev = bo_legacy->pprev;
|
|
+ }
|
|
+ bo_legacy->pprev->pnext = bo_legacy->pnext;
|
|
+ if (bo_legacy->pnext) {
|
|
+ bo_legacy->pnext->pprev = bo_legacy->pprev;
|
|
+ }
|
|
+ while (bo_legacy->is_pending--) {
|
|
+ radeon_bo_unref(bo);
|
|
+ }
|
|
+ bo_legacy->is_pending = 0;
|
|
+ boml->cpendings--;
|
|
+ return 0;
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static int legacy_wait_pending(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ if (!bo_legacy->is_pending) {
|
|
+ return 0;
|
|
+ }
|
|
+ /* FIXME: lockup and userspace busy looping that's all the folks */
|
|
+ legacy_get_current_age(boml);
|
|
+ while (legacy_is_pending(bo)) {
|
|
+ usleep(10);
|
|
+ legacy_get_current_age(boml);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void legacy_track_pending(struct bo_manager_legacy *boml)
|
|
+{
|
|
+ struct bo_legacy *bo_legacy;
|
|
+ struct bo_legacy *next;
|
|
+
|
|
+ legacy_get_current_age(boml);
|
|
+ bo_legacy = boml->pending_bos.pnext;
|
|
+ while (bo_legacy) {
|
|
+ next = bo_legacy->pnext;
|
|
+ if (legacy_is_pending(&(bo_legacy->base))) {
|
|
+ }
|
|
+ bo_legacy = next;
|
|
+ }
|
|
+}
|
|
+
|
|
+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;
|
|
+
|
|
+ bo_legacy = (struct bo_legacy*)calloc(1, sizeof(struct bo_legacy));
|
|
+ if (bo_legacy == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+ bo_legacy->base.bom = (struct radeon_bo_manager*)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;
|
|
+ bo_legacy->next = NULL;
|
|
+ bo_legacy->prev = NULL;
|
|
+ bo_legacy->got_dri_texture_obj = 0;
|
|
+ bo_legacy->pnext = NULL;
|
|
+ bo_legacy->pprev = NULL;
|
|
+ bo_legacy->next = boml->bos.next;
|
|
+ bo_legacy->prev = &boml->bos;
|
|
+ boml->bos.next = bo_legacy;
|
|
+ if (bo_legacy->next) {
|
|
+ bo_legacy->next->prev = bo_legacy;
|
|
+ }
|
|
+ return bo_legacy;
|
|
+}
|
|
+
|
|
+static int bo_dma_alloc(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+ drm_radeon_mem_alloc_t alloc;
|
|
+ unsigned size;
|
|
+ int base_offset;
|
|
+ int r;
|
|
+
|
|
+ /* align size on 4Kb */
|
|
+ size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1);
|
|
+ alloc.region = RADEON_MEM_REGION_GART;
|
|
+ alloc.alignment = bo_legacy->base.alignment;
|
|
+ alloc.size = size;
|
|
+ alloc.region_offset = &base_offset;
|
|
+ r = drmCommandWriteRead(bo->bom->fd,
|
|
+ DRM_RADEON_ALLOC,
|
|
+ &alloc,
|
|
+ sizeof(alloc));
|
|
+ if (r) {
|
|
+ /* ptr is set to NULL if dma allocation failed */
|
|
+ bo_legacy->ptr = NULL;
|
|
+ exit(0);
|
|
+ return r;
|
|
+ }
|
|
+ bo_legacy->ptr = boml->screen->gartTextures.map + base_offset;
|
|
+ bo_legacy->offset = boml->screen->gart_texture_offset + base_offset;
|
|
+ bo->size = size;
|
|
+ boml->dma_alloc_size += size;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int bo_dma_free(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+ drm_radeon_mem_free_t memfree;
|
|
+ int r;
|
|
+
|
|
+ if (bo_legacy->ptr == NULL) {
|
|
+ /* ptr is set to NULL if dma allocation failed */
|
|
+ return 0;
|
|
+ }
|
|
+ legacy_get_current_age(boml);
|
|
+ memfree.region = RADEON_MEM_REGION_GART;
|
|
+ memfree.region_offset = bo_legacy->offset;
|
|
+ memfree.region_offset -= boml->screen->gart_texture_offset;
|
|
+ r = drmCommandWrite(boml->base.fd,
|
|
+ DRM_RADEON_FREE,
|
|
+ &memfree,
|
|
+ sizeof(memfree));
|
|
+ if (r) {
|
|
+ fprintf(stderr, "Failed to free bo[%p] at %08x\n",
|
|
+ &bo_legacy->base, memfree.region_offset);
|
|
+ fprintf(stderr, "ret = %s\n", strerror(-r));
|
|
+ return r;
|
|
+ }
|
|
+ boml->dma_alloc_size -= bo_legacy->base.size;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void bo_free(struct bo_legacy *bo_legacy)
|
|
+{
|
|
+ struct bo_manager_legacy *boml;
|
|
+
|
|
+ if (bo_legacy == NULL) {
|
|
+ return;
|
|
+ }
|
|
+ boml = (struct bo_manager_legacy *)bo_legacy->base.bom;
|
|
+ bo_legacy->prev->next = bo_legacy->next;
|
|
+ if (bo_legacy->next) {
|
|
+ bo_legacy->next->prev = bo_legacy->prev;
|
|
+ }
|
|
+ if (!bo_legacy->static_bo) {
|
|
+ legacy_free_handle(boml, bo_legacy->base.handle);
|
|
+ if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) {
|
|
+ /* dma buffers */
|
|
+ bo_dma_free(&bo_legacy->base);
|
|
+ } else {
|
|
+ /* free backing store */
|
|
+ free(bo_legacy->ptr);
|
|
+ }
|
|
+ }
|
|
+ memset(bo_legacy, 0 , sizeof(struct bo_legacy));
|
|
+ free(bo_legacy);
|
|
+}
|
|
+
|
|
+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;
|
|
+ struct bo_legacy *bo_legacy;
|
|
+ int r;
|
|
+
|
|
+ if (handle) {
|
|
+ bo_legacy = boml->bos.next;
|
|
+ while (bo_legacy) {
|
|
+ if (bo_legacy->base.handle == handle) {
|
|
+ radeon_bo_ref(&(bo_legacy->base));
|
|
+ return (struct radeon_bo*)bo_legacy;
|
|
+ }
|
|
+ bo_legacy = bo_legacy->next;
|
|
+ }
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ 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.domains & RADEON_GEM_DOMAIN_GTT) {
|
|
+ legacy_track_pending(boml);
|
|
+ /* dma buffers */
|
|
+ r = bo_dma_alloc(&(bo_legacy->base));
|
|
+ if (r) {
|
|
+ fprintf(stderr, "Ran out of GART memory (for %d)!\n", size);
|
|
+ fprintf(stderr, "Please consider adjusting GARTSize option.\n");
|
|
+ bo_free(bo_legacy);
|
|
+ exit(-1);
|
|
+ return NULL;
|
|
+ }
|
|
+ } else {
|
|
+ bo_legacy->ptr = malloc(bo_legacy->base.size);
|
|
+ if (bo_legacy->ptr == NULL) {
|
|
+ bo_free(bo_legacy);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ radeon_bo_ref(&(bo_legacy->base));
|
|
+ return (struct radeon_bo*)bo_legacy;
|
|
+}
|
|
+
|
|
+static void bo_ref(struct radeon_bo *bo)
|
|
+{
|
|
+}
|
|
+
|
|
+static struct radeon_bo *bo_unref(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ if (bo->cref <= 0) {
|
|
+ bo_legacy->prev->next = bo_legacy->next;
|
|
+ if (bo_legacy->next) {
|
|
+ bo_legacy->next->prev = bo_legacy->prev;
|
|
+ }
|
|
+ if (!bo_legacy->is_pending) {
|
|
+ bo_free(bo_legacy);
|
|
+ }
|
|
+ return NULL;
|
|
+ }
|
|
+ return bo;
|
|
+}
|
|
+
|
|
+static int bo_map(struct radeon_bo *bo, int write)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ legacy_wait_pending(bo);
|
|
+ bo_legacy->validated = 0;
|
|
+ bo_legacy->dirty = 1;
|
|
+ bo_legacy->map_count++;
|
|
+ bo->ptr = bo_legacy->ptr;
|
|
+ /* Read the first pixel in the frame buffer. This should
|
|
+ * be a noop, right? In fact without this conform fails as reading
|
|
+ * from the framebuffer sometimes produces old results -- the
|
|
+ * on-card read cache gets mixed up and doesn't notice that the
|
|
+ * framebuffer has been updated.
|
|
+ *
|
|
+ * Note that we should probably be reading some otherwise unused
|
|
+ * region of VRAM, otherwise we might get incorrect results when
|
|
+ * reading pixels from the top left of the screen.
|
|
+ *
|
|
+ * I found this problem on an R420 with glean's texCube test.
|
|
+ * Note that the R200 span code also *writes* the first pixel in the
|
|
+ * framebuffer, but I've found this to be unnecessary.
|
|
+ * -- Nicolai Hähnle, June 2008
|
|
+ */
|
|
+ {
|
|
+ int p;
|
|
+ volatile int *buf = (int*)boml->screen->driScreen->pFB;
|
|
+ p = *buf;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int bo_unmap(struct radeon_bo *bo)
|
|
+{
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ if (--bo_legacy->map_count > 0) {
|
|
+ return 0;
|
|
+ }
|
|
+ bo->ptr = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct radeon_bo_funcs bo_legacy_funcs = {
|
|
+ bo_open,
|
|
+ bo_ref,
|
|
+ bo_unref,
|
|
+ bo_map,
|
|
+ bo_unmap
|
|
+};
|
|
+
|
|
+static int bo_vram_validate(struct radeon_bo *bo,
|
|
+ uint32_t *soffset,
|
|
+ uint32_t *eoffset)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+ int r;
|
|
+
|
|
+ if (!bo_legacy->got_dri_texture_obj) {
|
|
+ make_empty_list(&bo_legacy->dri_texture_obj);
|
|
+ bo_legacy->dri_texture_obj.totalSize = bo->size;
|
|
+ r = driAllocateTexture(&boml->texture_heap, 1,
|
|
+ &bo_legacy->dri_texture_obj);
|
|
+ if (r) {
|
|
+ uint8_t *segfault=NULL;
|
|
+ fprintf(stderr, "Ouch! vram_validate failed %d\n", r);
|
|
+ *segfault=1;
|
|
+ return -1;
|
|
+ }
|
|
+ bo_legacy->offset = boml->texture_offset +
|
|
+ bo_legacy->dri_texture_obj.memBlock->ofs;
|
|
+ bo_legacy->got_dri_texture_obj = 1;
|
|
+ bo_legacy->dirty = 1;
|
|
+ }
|
|
+ if (bo_legacy->dirty) {
|
|
+ /* Copy to VRAM using a blit.
|
|
+ * All memory is 4K aligned. We're using 1024 pixels wide blits.
|
|
+ */
|
|
+ drm_radeon_texture_t tex;
|
|
+ drm_radeon_tex_image_t tmp;
|
|
+ int ret;
|
|
+
|
|
+ tex.offset = bo_legacy->offset;
|
|
+ tex.image = &tmp;
|
|
+ assert(!(tex.offset & 1023));
|
|
+
|
|
+ tmp.x = 0;
|
|
+ tmp.y = 0;
|
|
+ if (bo->size < 4096) {
|
|
+ tmp.width = (bo->size + 3) / 4;
|
|
+ tmp.height = 1;
|
|
+ } else {
|
|
+ tmp.width = 1024;
|
|
+ tmp.height = (bo->size + 4095) / 4096;
|
|
+ }
|
|
+ tmp.data = bo_legacy->ptr;
|
|
+ tex.format = RADEON_TXFORMAT_ARGB8888;
|
|
+ tex.width = tmp.width;
|
|
+ tex.height = tmp.height;
|
|
+ tex.pitch = MAX2(tmp.width / 16, 1);
|
|
+ do {
|
|
+ ret = drmCommandWriteRead(bo->bom->fd,
|
|
+ DRM_RADEON_TEXTURE,
|
|
+ &tex,
|
|
+ sizeof(drm_radeon_texture_t));
|
|
+ if (ret) {
|
|
+ if (RADEON_DEBUG & DEBUG_IOCTL)
|
|
+ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
|
+ usleep(1);
|
|
+ }
|
|
+ } while (ret == -EAGAIN);
|
|
+ bo_legacy->dirty = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int radeon_bo_legacy_validate(struct radeon_bo *bo,
|
|
+ uint32_t *soffset,
|
|
+ uint32_t *eoffset)
|
|
+{
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+ int r;
|
|
+
|
|
+ if (bo_legacy->map_count) {
|
|
+ fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
|
|
+ bo, bo->size, bo_legacy->map_count);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (bo_legacy->static_bo || bo_legacy->validated) {
|
|
+ *soffset = bo_legacy->offset;
|
|
+ *eoffset = bo_legacy->offset + bo->size;
|
|
+ return 0;
|
|
+ }
|
|
+ if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) {
|
|
+ r = bo_vram_validate(bo, soffset, eoffset);
|
|
+ if (r) {
|
|
+ return r;
|
|
+ }
|
|
+ }
|
|
+ *soffset = bo_legacy->offset;
|
|
+ *eoffset = bo_legacy->offset + bo->size;
|
|
+ bo_legacy->validated = 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
|
|
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
|
|
+
|
|
+ bo_legacy->pending = pending;
|
|
+ bo_legacy->is_pending += 1;
|
|
+ /* add to pending list */
|
|
+ radeon_bo_ref(bo);
|
|
+ if (bo_legacy->is_pending > 1) {
|
|
+ return;
|
|
+ }
|
|
+ bo_legacy->pprev = boml->pending_bos.pprev;
|
|
+ bo_legacy->pnext = NULL;
|
|
+ bo_legacy->pprev->pnext = bo_legacy;
|
|
+ boml->pending_bos.pprev = bo_legacy;
|
|
+ boml->cpendings++;
|
|
+}
|
|
+
|
|
+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;
|
|
+
|
|
+ if (bom == NULL) {
|
|
+ return;
|
|
+ }
|
|
+ bo_legacy = boml->bos.next;
|
|
+ while (bo_legacy) {
|
|
+ struct bo_legacy *next;
|
|
+
|
|
+ next = bo_legacy->next;
|
|
+ bo_free(bo_legacy);
|
|
+ bo_legacy = next;
|
|
+ }
|
|
+ free(boml->free_handles);
|
|
+ free(boml);
|
|
+}
|
|
+
|
|
+struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *scrn)
|
|
+{
|
|
+ struct bo_manager_legacy *bom;
|
|
+ struct bo_legacy *bo;
|
|
+ unsigned size;
|
|
+
|
|
+ bom = (struct bo_manager_legacy*)
|
|
+ calloc(1, sizeof(struct bo_manager_legacy));
|
|
+ if (bom == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ bom->texture_heap = driCreateTextureHeap(0,
|
|
+ bom,
|
|
+ scrn->texSize[0],
|
|
+ 12,
|
|
+ RADEON_NR_TEX_REGIONS,
|
|
+ (drmTextureRegionPtr)scrn->sarea->tex_list[0],
|
|
+ &scrn->sarea->tex_age[0],
|
|
+ &bom->texture_swapped,
|
|
+ sizeof(struct bo_legacy),
|
|
+ &bo_legacy_tobj_destroy);
|
|
+ bom->texture_offset = scrn->texOffset[0];
|
|
+
|
|
+ bom->base.funcs = &bo_legacy_funcs;
|
|
+ bom->base.fd = scrn->driScreen->fd;
|
|
+ bom->bos.next = NULL;
|
|
+ bom->bos.prev = NULL;
|
|
+ bom->pending_bos.pprev = &bom->pending_bos;
|
|
+ bom->pending_bos.pnext = NULL;
|
|
+ bom->screen = scrn;
|
|
+ bom->fb_location = scrn->fbLocation;
|
|
+ bom->nhandle = 1;
|
|
+ bom->cfree_handles = 0;
|
|
+ bom->nfree_handles = 0x400;
|
|
+ bom->free_handles = (uint32_t*)malloc(bom->nfree_handles * 4);
|
|
+ if (bom->free_handles == NULL) {
|
|
+ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /* biggest framebuffer size */
|
|
+ size = 4096*4096*4;
|
|
+ /* allocate front */
|
|
+ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ if (bo == NULL) {
|
|
+ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
|
+ return NULL;
|
|
+ }
|
|
+ if (scrn->sarea->tiling_enabled) {
|
|
+ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
|
|
+ }
|
|
+ bo->static_bo = 1;
|
|
+ bo->offset = bom->screen->frontOffset + bom->fb_location;
|
|
+ bo->base.handle = bo->offset;
|
|
+ bo->ptr = scrn->driScreen->pFB + bom->screen->frontOffset;
|
|
+ if (bo->base.handle > bom->nhandle) {
|
|
+ bom->nhandle = bo->base.handle + 1;
|
|
+ }
|
|
+ /* allocate back */
|
|
+ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ if (bo == NULL) {
|
|
+ radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
|
|
+ return NULL;
|
|
+ }
|
|
+ if (scrn->sarea->tiling_enabled) {
|
|
+ bo->base.flags = RADEON_BO_FLAGS_MACRO_TILE;
|
|
+ }
|
|
+ bo->static_bo = 1;
|
|
+ bo->offset = bom->screen->backOffset + bom->fb_location;
|
|
+ bo->base.handle = bo->offset;
|
|
+ bo->ptr = scrn->driScreen->pFB + bom->screen->backOffset;
|
|
+ if (bo->base.handle > bom->nhandle) {
|
|
+ bom->nhandle = bo->base.handle + 1;
|
|
+ }
|
|
+ /* allocate depth */
|
|
+ bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
|
|
+ if (bo == NULL) {
|
|
+ radeon_bo_manager_legacy_dtor((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_MICRO_TILE;
|
|
+ }
|
|
+ bo->static_bo = 1;
|
|
+ bo->offset = bom->screen->depthOffset + bom->fb_location;
|
|
+ bo->base.handle = bo->offset;
|
|
+ bo->ptr = scrn->driScreen->pFB + bom->screen->depthOffset;
|
|
+ if (bo->base.handle > bom->nhandle) {
|
|
+ bom->nhandle = bo->base.handle + 1;
|
|
+ }
|
|
+ return (struct radeon_bo_manager*)bom;
|
|
+}
|
|
+
|
|
+void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom)
|
|
+{
|
|
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
|
|
+ DRI_AGE_TEXTURES(boml->texture_heap);
|
|
+}
|
|
+
|
|
+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->domains & RADEON_GEM_DOMAIN_GTT)) {
|
|
+ return 0;
|
|
+ }
|
|
+ return bo->size;
|
|
+}
|
|
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
|
|
new file mode 100644
|
|
index 0000000..208171e
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
|
|
@@ -0,0 +1,47 @@
|
|
+/*
|
|
+ * 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 <aet@rasterburn.org>
|
|
+ * Nicolai Haehnle <prefect_@gmx.net>
|
|
+ * Jérôme Glisse <glisse@freedesktop.org>
|
|
+ */
|
|
+#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);
|
|
+int radeon_bo_legacy_validate(struct radeon_bo *bo,
|
|
+ uint32_t *soffset,
|
|
+ uint32_t *eoffset);
|
|
+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);
|
|
+
|
|
+#endif
|
|
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer.h b/src/mesa/drivers/dri/radeon/radeon_buffer.h
|
|
new file mode 100644
|
|
index 0000000..62cdfad
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer.h
|
|
@@ -0,0 +1,49 @@
|
|
+/*
|
|
+ * 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 <ajax@redhat.com>
|
|
+ */
|
|
+
|
|
+#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_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
|
|
new file mode 100644
|
|
index 0000000..11b9f89
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
|
|
@@ -0,0 +1,404 @@
|
|
+/*
|
|
+ * 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 <aet@rasterburn.org>
|
|
+ * Nicolai Haehnle <prefect_@gmx.net>
|
|
+ * Jérôme Glisse <glisse@freedesktop.org>
|
|
+ */
|
|
+#include <errno.h>
|
|
+#include "r300_reg.h"
|
|
+#include "r300_emit.h"
|
|
+#include "r300_cmdbuf.h"
|
|
+#include "radeon_cs.h"
|
|
+#include "radeon_cs_legacy.h"
|
|
+#include "radeon_bo_legacy.h"
|
|
+#include "radeon_context.h"
|
|
+
|
|
+struct cs_manager_legacy {
|
|
+ struct radeon_cs_manager base;
|
|
+ struct radeon_context *ctx;
|
|
+ /* hack for scratch stuff */
|
|
+ uint32_t pending_age;
|
|
+ uint32_t pending_count;
|
|
+};
|
|
+
|
|
+struct cs_reloc_legacy {
|
|
+ struct radeon_cs_reloc base;
|
|
+ uint32_t cindices;
|
|
+ uint32_t *indices;
|
|
+};
|
|
+
|
|
+
|
|
+static struct radeon_cs *cs_create(struct radeon_cs_manager *csm,
|
|
+ uint32_t ndw)
|
|
+{
|
|
+ struct radeon_cs *cs;
|
|
+
|
|
+ cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs));
|
|
+ if (cs == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+ cs->csm = csm;
|
|
+ cs->ndw = (ndw + 0x3FF) & (~0x3FF);
|
|
+ cs->packets = (uint32_t*)malloc(4*cs->ndw);
|
|
+ if (cs->packets == NULL) {
|
|
+ free(cs);
|
|
+ return NULL;
|
|
+ }
|
|
+ cs->relocs_total_size = 0;
|
|
+ return cs;
|
|
+}
|
|
+
|
|
+static int cs_write_dword(struct radeon_cs *cs, uint32_t dword)
|
|
+{
|
|
+ if (cs->cdw >= cs->ndw) {
|
|
+ uint32_t tmp, *ptr;
|
|
+ tmp = (cs->cdw + 1 + 0x3FF) & (~0x3FF);
|
|
+ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
|
|
+ if (ptr == NULL) {
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ cs->packets = ptr;
|
|
+ cs->ndw = tmp;
|
|
+ }
|
|
+ cs->packets[cs->cdw++] = dword;
|
|
+ if (cs->section) {
|
|
+ cs->section_cdw++;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_write_reloc(struct radeon_cs *cs,
|
|
+ struct radeon_bo *bo,
|
|
+ uint32_t read_domain,
|
|
+ uint32_t write_domain,
|
|
+ uint32_t flags)
|
|
+{
|
|
+ struct cs_reloc_legacy *relocs;
|
|
+ int i;
|
|
+
|
|
+ relocs = (struct cs_reloc_legacy *)cs->relocs;
|
|
+ /* check domains */
|
|
+ if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
|
|
+ /* in one CS a bo can only be in read or write domain but not
|
|
+ * in read & write domain at the same sime
|
|
+ */
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (read_domain == RADEON_GEM_DOMAIN_CPU) {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (write_domain == RADEON_GEM_DOMAIN_CPU) {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ /* check if bo is already referenced */
|
|
+ for(i = 0; i < cs->crelocs; i++) {
|
|
+ uint32_t *indices;
|
|
+
|
|
+ if (relocs[i].base.bo->handle == bo->handle) {
|
|
+ /* Check domains must be in read or write. As we check already
|
|
+ * checked that in argument one of the read or write domain was
|
|
+ * set we only need to check that if previous reloc as the read
|
|
+ * domain set then the read_domain should also be set for this
|
|
+ * new relocation.
|
|
+ */
|
|
+ if (relocs[i].base.read_domain && !read_domain) {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (relocs[i].base.write_domain && !write_domain) {
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ relocs[i].base.read_domain |= read_domain;
|
|
+ relocs[i].base.write_domain |= write_domain;
|
|
+ /* save indice */
|
|
+ relocs[i].cindices += 1;
|
|
+ indices = (uint32_t*)realloc(relocs[i].indices,
|
|
+ relocs[i].cindices * 4);
|
|
+ if (indices == NULL) {
|
|
+ relocs[i].cindices -= 1;
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ relocs[i].indices = indices;
|
|
+ relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1;
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ /* add bo to reloc */
|
|
+ relocs = (struct cs_reloc_legacy*)
|
|
+ realloc(cs->relocs,
|
|
+ sizeof(struct cs_reloc_legacy) * (cs->crelocs + 1));
|
|
+ if (relocs == NULL) {
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ cs->relocs = relocs;
|
|
+ relocs[cs->crelocs].base.bo = bo;
|
|
+ relocs[cs->crelocs].base.read_domain = read_domain;
|
|
+ relocs[cs->crelocs].base.write_domain = write_domain;
|
|
+ relocs[cs->crelocs].base.flags = flags;
|
|
+ relocs[cs->crelocs].indices = (uint32_t*)malloc(4);
|
|
+ if (relocs[cs->crelocs].indices == NULL) {
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ relocs[cs->crelocs].indices[0] = cs->cdw - 1;
|
|
+ relocs[cs->crelocs].cindices = 1;
|
|
+ cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
|
|
+ cs->crelocs++;
|
|
+ radeon_bo_ref(bo);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_begin(struct radeon_cs *cs,
|
|
+ uint32_t ndw,
|
|
+ const char *file,
|
|
+ const char *func,
|
|
+ int line)
|
|
+{
|
|
+ if (cs->section) {
|
|
+ fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
|
|
+ cs->section_file, cs->section_func, cs->section_line);
|
|
+ fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
|
|
+ file, func, line);
|
|
+ return -EPIPE;
|
|
+ }
|
|
+ cs->section = 1;
|
|
+ cs->section_ndw = ndw;
|
|
+ cs->section_cdw = 0;
|
|
+ cs->section_file = file;
|
|
+ cs->section_func = func;
|
|
+ cs->section_line = line;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_end(struct radeon_cs *cs,
|
|
+ const char *file,
|
|
+ const char *func,
|
|
+ int line)
|
|
+
|
|
+{
|
|
+ if (!cs->section) {
|
|
+ fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
|
|
+ file, func, line);
|
|
+ return -EPIPE;
|
|
+ }
|
|
+ cs->section = 0;
|
|
+ if (cs->section_ndw != cs->section_cdw) {
|
|
+ fprintf(stderr, "CS section size missmatch start at (%s,%s,%d)\n",
|
|
+ cs->section_file, cs->section_func, cs->section_line);
|
|
+ fprintf(stderr, "CS section end at (%s,%s,%d)\n",
|
|
+ file, func, line);
|
|
+ return -EPIPE;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_process_relocs(struct radeon_cs *cs)
|
|
+{
|
|
+ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
|
|
+ struct cs_reloc_legacy *relocs;
|
|
+ int i, j, r;
|
|
+
|
|
+ if (!IS_R300_CLASS(csm->ctx->radeonScreen)) {
|
|
+ /* FIXME: r300 only right now */
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ csm = (struct cs_manager_legacy*)cs->csm;
|
|
+ relocs = (struct cs_reloc_legacy *)cs->relocs;
|
|
+ for (i = 0; i < cs->crelocs; i++) {
|
|
+ for (j = 0; j < relocs[i].cindices; j++) {
|
|
+ uint32_t soffset, eoffset;
|
|
+
|
|
+ r = radeon_bo_legacy_validate(relocs[i].base.bo,
|
|
+ &soffset, &eoffset);
|
|
+ if (r) {
|
|
+ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
|
|
+ relocs[i].base.bo, soffset, eoffset);
|
|
+ return r;
|
|
+ }
|
|
+ cs->packets[relocs[i].indices[j]] += soffset;
|
|
+ if (cs->packets[relocs[i].indices[j]] >= eoffset) {
|
|
+ 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",
|
|
+ relocs[i].base.bo,
|
|
+ cs->packets[relocs[i].indices[j]],
|
|
+ eoffset);
|
|
+ exit(0);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_set_age(struct radeon_cs *cs)
|
|
+{
|
|
+ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
|
|
+ struct cs_reloc_legacy *relocs;
|
|
+ int i;
|
|
+
|
|
+ relocs = (struct cs_reloc_legacy *)cs->relocs;
|
|
+ for (i = 0; i < cs->crelocs; i++) {
|
|
+ radeon_bo_legacy_pending(relocs[i].base.bo, csm->pending_age);
|
|
+ radeon_bo_unref(relocs[i].base.bo);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_emit(struct radeon_cs *cs)
|
|
+{
|
|
+ struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
|
|
+ drm_radeon_cmd_buffer_t cmd;
|
|
+ drm_r300_cmd_header_t age;
|
|
+ uint64_t ull;
|
|
+ int r;
|
|
+
|
|
+ /* please flush pipe do all pending work */
|
|
+ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen,
|
|
+ R300_SC_SCREENDOOR, 1));
|
|
+ cs_write_dword(cs, 0x0);
|
|
+ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen,
|
|
+ R300_SC_SCREENDOOR, 1));
|
|
+ cs_write_dword(cs, 0x00FFFFFF);
|
|
+ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen,
|
|
+ R300_SC_HYPERZ, 1));
|
|
+ cs_write_dword(cs, 0x0);
|
|
+ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen,
|
|
+ R300_US_CONFIG, 1));
|
|
+ cs_write_dword(cs, 0x0);
|
|
+ cs_write_dword(cs, cmdpacket0(csm->ctx->radeonScreen,
|
|
+ R300_ZB_CNTL, 1));
|
|
+ cs_write_dword(cs, 0x0);
|
|
+ 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(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(csm->ctx->radeonScreen,
|
|
+ R300_WAIT_3D | R300_WAIT_3D_CLEAN));
|
|
+
|
|
+ /* append buffer age */
|
|
+ age.scratch.cmd_type = R300_CMD_SCRATCH;
|
|
+ /* Scratch register 2 corresponds to what radeonGetAge polls */
|
|
+ csm->pending_age = 0;
|
|
+ csm->pending_count = 1;
|
|
+ ull = (uint64_t) (intptr_t) &csm->pending_age;
|
|
+ age.scratch.reg = 2;
|
|
+ age.scratch.n_bufs = 1;
|
|
+ age.scratch.flags = 0;
|
|
+ radeon_cs_write_dword(cs, age.u);
|
|
+ radeon_cs_write_dword(cs, ull & 0xffffffff);
|
|
+ radeon_cs_write_dword(cs, ull >> 32);
|
|
+ radeon_cs_write_dword(cs, 0);
|
|
+
|
|
+ r = cs_process_relocs(cs);
|
|
+ if (r) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ cmd.buf = (char *)cs->packets;
|
|
+ cmd.bufsz = cs->cdw * 4;
|
|
+ if (csm->ctx->state.scissor.enabled) {
|
|
+ cmd.nbox = csm->ctx->state.scissor.numClipRects;
|
|
+ cmd.boxes = (drm_clip_rect_t *) csm->ctx->state.scissor.pClipRects;
|
|
+ } else {
|
|
+ cmd.nbox = csm->ctx->numClipRects;
|
|
+ cmd.boxes = (drm_clip_rect_t *) csm->ctx->pClipRects;
|
|
+ }
|
|
+
|
|
+ r = drmCommandWrite(cs->csm->fd, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
|
|
+ if (r) {
|
|
+ return r;
|
|
+ }
|
|
+ cs_set_age(cs);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_destroy(struct radeon_cs *cs)
|
|
+{
|
|
+ free(cs->relocs);
|
|
+ free(cs->packets);
|
|
+ free(cs);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_erase(struct radeon_cs *cs)
|
|
+{
|
|
+ free(cs->relocs);
|
|
+ cs->relocs_total_size = 0;
|
|
+ cs->relocs = NULL;
|
|
+ cs->crelocs = 0;
|
|
+ cs->cdw = 0;
|
|
+ cs->section = 0;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cs_need_flush(struct radeon_cs *cs)
|
|
+{
|
|
+ /* FIXME: we should get the texture heap size */
|
|
+ return (cs->relocs_total_size > (7*1024*1024));
|
|
+}
|
|
+
|
|
+static void cs_print(struct radeon_cs *cs, FILE *file)
|
|
+{
|
|
+}
|
|
+
|
|
+static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
|
|
+ cs_create,
|
|
+ cs_write_dword,
|
|
+ cs_write_reloc,
|
|
+ cs_begin,
|
|
+ cs_end,
|
|
+ cs_emit,
|
|
+ cs_destroy,
|
|
+ cs_erase,
|
|
+ cs_need_flush,
|
|
+ cs_print
|
|
+};
|
|
+
|
|
+struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)
|
|
+{
|
|
+ struct cs_manager_legacy *csm;
|
|
+
|
|
+ csm = (struct cs_manager_legacy*)
|
|
+ calloc(1, sizeof(struct cs_manager_legacy));
|
|
+ if (csm == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+ csm->base.funcs = &radeon_cs_legacy_funcs;
|
|
+ csm->base.fd = ctx->dri.fd;
|
|
+ csm->ctx = ctx;
|
|
+ csm->pending_age = 1;
|
|
+ return (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
|
|
new file mode 100644
|
|
index 0000000..71a4dad
|
|
--- /dev/null
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
|
|
@@ -0,0 +1,41 @@
|
|
+/*
|
|
+ * 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 <aet@rasterburn.org>
|
|
+ * Nicolai Haehnle <prefect_@gmx.net>
|
|
+ * Jérôme Glisse <glisse@freedesktop.org>
|
|
+ */
|
|
+#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_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 5f32dd5..d579509 100644
|
|
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
|
|
@@ -35,6 +35,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
* \author Gareth Hughes <gareth@valinux.com>
|
|
*/
|
|
|
|
+#include <errno.h>
|
|
#include "main/glheader.h"
|
|
#include "main/imports.h"
|
|
#include "main/mtypes.h"
|
|
@@ -45,6 +46,7 @@ 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"
|
|
#if !RADEON_COMMON
|
|
#include "radeon_context.h"
|
|
#include "radeon_span.h"
|
|
@@ -70,6 +72,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
/* Radeon configuration
|
|
*/
|
|
#include "xmlpool.h"
|
|
+#include "radeon_bo_legacy.h"
|
|
+#include "radeon_bo_gem.h"
|
|
|
|
#if !RADEON_COMMON /* R100 */
|
|
PUBLIC const char __driConfigOptions[] =
|
|
@@ -346,6 +350,14 @@ static const __DRItexOffsetExtension r300texOffsetExtension = {
|
|
{ __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
|
|
r300SetTexOffset,
|
|
};
|
|
+
|
|
+void r300SetTexBuffer(__DRIcontext *pDRICtx,
|
|
+ GLint target,
|
|
+ __DRIdrawable *dPriv);
|
|
+static const __DRItexBufferExtension r300TexBufferExtension = {
|
|
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
|
|
+ r300SetTexBuffer,
|
|
+};
|
|
#endif
|
|
|
|
/* Create the device specific screen private data struct.
|
|
@@ -355,7 +367,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
{
|
|
radeonScreenPtr screen;
|
|
RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
|
|
- unsigned char *RADEONMMIO;
|
|
+ unsigned char *RADEONMMIO = NULL;
|
|
int i;
|
|
int ret;
|
|
uint32_t temp;
|
|
@@ -387,6 +399,21 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP);
|
|
{
|
|
int ret;
|
|
+
|
|
+#ifdef RADEON_PARAM_KERNEL_MM
|
|
+ ret = radeonGetParam( sPriv->fd, RADEON_PARAM_KERNEL_MM,
|
|
+ &screen->kernel_mm);
|
|
+
|
|
+ if (ret && ret != -EINVAL) {
|
|
+ FREE( screen );
|
|
+ fprintf(stderr, "drm_radeon_getparam_t (RADEON_OFFSET): %d\n", ret);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (ret == -EINVAL)
|
|
+ screen->kernel_mm = 0;
|
|
+#endif
|
|
+
|
|
ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET,
|
|
&screen->gart_buffer_offset);
|
|
|
|
@@ -420,58 +447,60 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
|
|
}
|
|
|
|
- screen->mmio.handle = dri_priv->registerHandle;
|
|
- screen->mmio.size = dri_priv->registerSize;
|
|
- if ( drmMap( sPriv->fd,
|
|
- screen->mmio.handle,
|
|
- screen->mmio.size,
|
|
- &screen->mmio.map ) ) {
|
|
- FREE( screen );
|
|
- __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- RADEONMMIO = screen->mmio.map;
|
|
-
|
|
- screen->status.handle = dri_priv->statusHandle;
|
|
- screen->status.size = dri_priv->statusSize;
|
|
- if ( drmMap( sPriv->fd,
|
|
- screen->status.handle,
|
|
- screen->status.size,
|
|
- &screen->status.map ) ) {
|
|
- drmUnmap( screen->mmio.map, screen->mmio.size );
|
|
- FREE( screen );
|
|
- __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
|
|
- return NULL;
|
|
- }
|
|
- screen->scratch = (__volatile__ uint32_t *)
|
|
- ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
|
-
|
|
- screen->buffers = drmMapBufs( sPriv->fd );
|
|
- if ( !screen->buffers ) {
|
|
- drmUnmap( screen->status.map, screen->status.size );
|
|
- drmUnmap( screen->mmio.map, screen->mmio.size );
|
|
- FREE( screen );
|
|
- __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
|
|
- screen->gartTextures.handle = dri_priv->gartTexHandle;
|
|
- screen->gartTextures.size = dri_priv->gartTexMapSize;
|
|
- if ( drmMap( sPriv->fd,
|
|
- screen->gartTextures.handle,
|
|
- screen->gartTextures.size,
|
|
- (drmAddressPtr)&screen->gartTextures.map ) ) {
|
|
+ if (!screen->kernel_mm) {
|
|
+ screen->mmio.handle = dri_priv->registerHandle;
|
|
+ screen->mmio.size = dri_priv->registerSize;
|
|
+ if ( drmMap( sPriv->fd,
|
|
+ screen->mmio.handle,
|
|
+ screen->mmio.size,
|
|
+ &screen->mmio.map ) ) {
|
|
+ FREE( screen );
|
|
+ __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ RADEONMMIO = screen->mmio.map;
|
|
+
|
|
+ screen->status.handle = dri_priv->statusHandle;
|
|
+ screen->status.size = dri_priv->statusSize;
|
|
+ if ( drmMap( sPriv->fd,
|
|
+ screen->status.handle,
|
|
+ screen->status.size,
|
|
+ &screen->status.map ) ) {
|
|
+ drmUnmap( screen->mmio.map, screen->mmio.size );
|
|
+ FREE( screen );
|
|
+ __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
|
|
+ return NULL;
|
|
+ }
|
|
+ screen->scratch = (__volatile__ uint32_t *)
|
|
+ ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
|
|
+
|
|
+ screen->buffers = drmMapBufs( sPriv->fd );
|
|
+ if ( !screen->buffers ) {
|
|
+ drmUnmap( screen->status.map, screen->status.size );
|
|
+ drmUnmap( screen->mmio.map, screen->mmio.size );
|
|
+ FREE( screen );
|
|
+ __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
|
|
+ screen->gartTextures.handle = dri_priv->gartTexHandle;
|
|
+ screen->gartTextures.size = dri_priv->gartTexMapSize;
|
|
+ if ( drmMap( sPriv->fd,
|
|
+ screen->gartTextures.handle,
|
|
+ screen->gartTextures.size,
|
|
+ (drmAddressPtr)&screen->gartTextures.map ) ) {
|
|
drmUnmapBufs( screen->buffers );
|
|
drmUnmap( screen->status.map, screen->status.size );
|
|
drmUnmap( screen->mmio.map, screen->mmio.size );
|
|
FREE( screen );
|
|
__driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
|
|
return NULL;
|
|
- }
|
|
-
|
|
- screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
|
|
+ }
|
|
+
|
|
+ screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
|
|
+ }
|
|
}
|
|
|
|
screen->chip_flags = 0;
|
|
@@ -838,7 +867,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
ret = radeonGetParam( sPriv->fd, RADEON_PARAM_FB_LOCATION,
|
|
&temp);
|
|
if (ret) {
|
|
- if (screen->chip_family < CHIP_FAMILY_RS690)
|
|
+ if (screen->chip_family < CHIP_FAMILY_RS690 && !screen->kernel_mm)
|
|
screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
|
|
else {
|
|
FREE( screen );
|
|
@@ -960,6 +989,85 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
|
|
screen->driScreen = sPriv;
|
|
screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
|
|
+ screen->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
|
|
+ screen->sarea_priv_offset);
|
|
+
|
|
+ if (screen->kernel_mm)
|
|
+ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
|
|
+ else
|
|
+ screen->bom = radeon_bo_manager_legacy_ctor(screen);
|
|
+ if (screen->bom == NULL) {
|
|
+ free(screen);
|
|
+ return NULL;
|
|
+ }
|
|
+ return screen;
|
|
+}
|
|
+
|
|
+static radeonScreenPtr
|
|
+radeonCreateScreen2(__DRIscreenPrivate *sPriv)
|
|
+{
|
|
+ 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->kernel_mm = 1;
|
|
+ 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;
|
|
+
|
|
+ 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
|
|
+
|
|
+#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;
|
|
+ screen->extensions[i++] = &r300TexBufferExtension.base;
|
|
+#endif
|
|
+
|
|
+ screen->extensions[i++] = NULL;
|
|
+ sPriv->extensions = screen->extensions;
|
|
+
|
|
+ screen->driScreen = sPriv;
|
|
+ screen->bom = radeon_bo_manager_gem_ctor(sPriv->fd);
|
|
+ if (screen->bom == NULL) {
|
|
+ free(screen);
|
|
+ return NULL;
|
|
+ }
|
|
return screen;
|
|
}
|
|
|
|
@@ -968,23 +1076,30 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
|
|
static void
|
|
radeonDestroyScreen( __DRIscreenPrivate *sPriv )
|
|
{
|
|
- radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
|
|
-
|
|
- if (!screen)
|
|
- return;
|
|
-
|
|
- 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 );
|
|
+ radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
|
|
+
|
|
+ if (!screen)
|
|
+ return;
|
|
+
|
|
+ if (screen->kernel_mm) {
|
|
+ radeon_tracker_print(&screen->bom->tracker, stderr);
|
|
+ radeon_bo_manager_gem_dtor(screen->bom);
|
|
+ } else {
|
|
+ radeon_bo_manager_legacy_dtor(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 all option information */
|
|
+ driDestroyOptionInfo (&screen->optionCache);
|
|
|
|
- FREE( screen );
|
|
- sPriv->private = NULL;
|
|
+ FREE( screen );
|
|
+ sPriv->private = NULL;
|
|
}
|
|
|
|
|
|
@@ -993,15 +1108,176 @@ 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;
|
|
+}
|
|
+
|
|
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
|
|
+static GLboolean
|
|
+radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
|
+ GLenum intFormat, GLuint w, GLuint h)
|
|
+{
|
|
+ rb->Width = w;
|
|
+ rb->Height = h;
|
|
+ rb->_ActualFormat = intFormat;
|
|
+
|
|
+ return GL_TRUE;
|
|
+}
|
|
+
|
|
+
|
|
+static struct radeon_renderbuffer *
|
|
+radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
|
|
+{
|
|
+ struct radeon_renderbuffer *ret;
|
|
+
|
|
+ ret = CALLOC_STRUCT(radeon_renderbuffer);
|
|
+ if (!ret)
|
|
+ return NULL;
|
|
+
|
|
+ _mesa_init_renderbuffer(&ret->base, 0);
|
|
+
|
|
+ /* XXX format junk */
|
|
+ switch (format) {
|
|
+ case GL_RGB5:
|
|
+ ret->base._ActualFormat = GL_RGB5;
|
|
+ ret->base._BaseFormat = GL_RGBA;
|
|
+ ret->base.RedBits = 5;
|
|
+ ret->base.GreenBits = 6;
|
|
+ ret->base.BlueBits = 5;
|
|
+ ret->base.DataType = GL_UNSIGNED_BYTE;
|
|
+ break;
|
|
+ case GL_RGBA8:
|
|
+ ret->base._ActualFormat = GL_RGBA8;
|
|
+ ret->base._BaseFormat = GL_RGBA;
|
|
+ ret->base.RedBits = 8;
|
|
+ ret->base.GreenBits = 8;
|
|
+ ret->base.BlueBits = 8;
|
|
+ ret->base.AlphaBits = 8;
|
|
+ ret->base.DataType = GL_UNSIGNED_BYTE;
|
|
+ break;
|
|
+ case GL_STENCIL_INDEX8_EXT:
|
|
+ ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT;
|
|
+ ret->base._BaseFormat = GL_STENCIL_INDEX;
|
|
+ ret->base.StencilBits = 8;
|
|
+ ret->base.DataType = GL_UNSIGNED_BYTE;
|
|
+ break;
|
|
+ case GL_DEPTH_COMPONENT16:
|
|
+ ret->base._ActualFormat = GL_DEPTH_COMPONENT16;
|
|
+ ret->base._BaseFormat = GL_DEPTH_COMPONENT;
|
|
+ ret->base.DepthBits = 16;
|
|
+ ret->base.DataType = GL_UNSIGNED_SHORT;
|
|
+ break;
|
|
+ case GL_DEPTH_COMPONENT24:
|
|
+ ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
|
+ ret->base._BaseFormat = GL_DEPTH_COMPONENT;
|
|
+ ret->base.DepthBits = 24;
|
|
+ ret->base.DataType = GL_UNSIGNED_INT;
|
|
+ break;
|
|
+ case GL_DEPTH24_STENCIL8_EXT:
|
|
+ ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
|
+ ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT;
|
|
+ ret->base.DepthBits = 24;
|
|
+ ret->base.StencilBits = 8;
|
|
+ ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT;
|
|
+ break;
|
|
+ default:
|
|
+ fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format);
|
|
+ _mesa_delete_renderbuffer(&ret->base);
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- return GL_TRUE;
|
|
+ ret->dPriv = driDrawPriv;
|
|
+ ret->base.InternalFormat = format;
|
|
+
|
|
+ ret->base.AllocStorage = radeon_alloc_window_storage;
|
|
+
|
|
+ radeonSetSpanFunctions(ret);
|
|
+
|
|
+ ret->bo = NULL;
|
|
+ return ret;
|
|
}
|
|
|
|
+/**
|
|
+ * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
|
|
+ *
|
|
+ * \todo This function (and its interface) will need to be updated to support
|
|
+ * pbuffers.
|
|
+ */
|
|
+static GLboolean
|
|
+radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
|
+ __DRIdrawablePrivate *driDrawPriv,
|
|
+ const __GLcontextModes *mesaVis,
|
|
+ GLboolean isPixmap )
|
|
+{
|
|
+ radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
|
|
+
|
|
+ const GLboolean swDepth = GL_FALSE;
|
|
+ const GLboolean swAlpha = GL_FALSE;
|
|
+ const GLboolean swAccum = mesaVis->accumRedBits > 0;
|
|
+ const GLboolean swStencil = mesaVis->stencilBits > 0 &&
|
|
+ mesaVis->depthBits != 24;
|
|
+ GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
|
|
+ GLenum depthFormat = GL_NONE;
|
|
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
|
|
+
|
|
+ if (mesaVis->depthBits == 16)
|
|
+ depthFormat = GL_DEPTH_COMPONENT16;
|
|
+ else if (mesaVis->depthBits == 24)
|
|
+ depthFormat = GL_DEPTH_COMPONENT24;
|
|
+
|
|
+ /* front color renderbuffer */
|
|
+ {
|
|
+ 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 */
|
|
+ if (mesaVis->doubleBufferMode) {
|
|
+ struct radeon_renderbuffer *back =
|
|
+ radeon_create_renderbuffer(rgbFormat, driDrawPriv);
|
|
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base);
|
|
+ back->has_surface = 1;
|
|
+ }
|
|
+
|
|
+ /* depth renderbuffer */
|
|
+ if (depthFormat != GL_NONE) {
|
|
+ struct radeon_renderbuffer *depth =
|
|
+ radeon_create_renderbuffer(depthFormat, driDrawPriv);
|
|
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base);
|
|
+ depth->has_surface = screen->depthHasSurface;
|
|
+ }
|
|
+
|
|
+ /* stencil renderbuffer */
|
|
+ if (mesaVis->stencilBits > 0 && !swStencil) {
|
|
+ struct radeon_renderbuffer *stencil =
|
|
+ radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
|
|
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base);
|
|
+ stencil->has_surface = screen->depthHasSurface;
|
|
+ }
|
|
+
|
|
+ _mesa_add_soft_renderbuffers(fb,
|
|
+ GL_FALSE, /* color */
|
|
+ swDepth,
|
|
+ swStencil,
|
|
+ swAccum,
|
|
+ swAlpha,
|
|
+ GL_FALSE /* aux */);
|
|
+ driDrawPriv->driverPrivate = (void *) fb;
|
|
+
|
|
+ return (driDrawPriv->driverPrivate != NULL);
|
|
+}
|
|
+#else
|
|
|
|
/**
|
|
* Create the Mesa framebuffer and renderbuffers for a given window/drawable.
|
|
@@ -1062,7 +1338,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
|
|
@@ -1073,7 +1349,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 */
|
|
@@ -1086,7 +1362,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,
|
|
@@ -1101,11 +1377,30 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
|
return (driDrawPriv->driverPrivate != NULL);
|
|
}
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
static void
|
|
radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
|
{
|
|
+ struct radeon_renderbuffer *rb;
|
|
+ GLframebuffer *fb;
|
|
+
|
|
+ fb = (void*)driDrawPriv->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_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
|
|
}
|
|
|
|
@@ -1197,13 +1492,48 @@ radeonInitScreen(__DRIscreenPrivate *psp)
|
|
if (!radeonInitDriver(psp))
|
|
return NULL;
|
|
|
|
+ /* for now fill in all modes */
|
|
return radeonFillInModes( psp,
|
|
dri_priv->bpp,
|
|
(dri_priv->bpp == 16) ? 16 : 24,
|
|
- (dri_priv->bpp == 16) ? 0 : 8,
|
|
- (dri_priv->backOffset != dri_priv->depthOffset) );
|
|
+ (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)
|
|
+{
|
|
+ /* 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;
|
|
+ }
|
|
+
|
|
+ /* for now fill in all modes */
|
|
+ return radeonFillInModes( psp, 24, 24, 8, 1);
|
|
+}
|
|
|
|
/**
|
|
* Get information about previous buffer swaps.
|
|
@@ -1252,6 +1582,8 @@ const struct __DriverAPIRec driDriverAPI = {
|
|
.WaitForSBC = NULL,
|
|
.SwapBuffersMSC = NULL,
|
|
.CopySubBuffer = radeonCopySubBuffer,
|
|
+ /* DRI2 */
|
|
+ .InitScreen2 = radeonInitScreen2,
|
|
};
|
|
#else
|
|
const struct __DriverAPIRec driDriverAPI = {
|
|
@@ -1272,3 +1604,4 @@ const struct __DriverAPIRec driDriverAPI = {
|
|
.CopySubBuffer = r200CopySubBuffer,
|
|
};
|
|
#endif
|
|
+
|
|
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
|
|
index b84c70b..3287e12 100644
|
|
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
|
|
@@ -46,6 +46,7 @@ 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 {
|
|
@@ -54,7 +55,7 @@ typedef struct {
|
|
drmAddress map; /* Mapping of the DRM region */
|
|
} radeonRegionRec, *radeonRegionPtr;
|
|
|
|
-typedef struct {
|
|
+typedef struct radeon_screen {
|
|
int chip_family;
|
|
int chip_flags;
|
|
int cpp;
|
|
@@ -103,9 +104,12 @@ typedef struct {
|
|
/* Configuration cache with default values for all contexts */
|
|
driOptionCache optionCache;
|
|
|
|
- const __DRIextension *extensions[8];
|
|
+ const __DRIextension *extensions[16];
|
|
|
|
int num_gb_pipes;
|
|
+ int kernel_mm;
|
|
+ drm_radeon_sarea_t *sarea; /* Private SAREA data */
|
|
+ struct radeon_bo_manager *bom;
|
|
} radeonScreenRec, *radeonScreenPtr;
|
|
|
|
#define IS_R100_CLASS(screen) \
|
|
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.h b/src/mesa/drivers/dri/radeon/radeon_span.h
|
|
index 9abe086..1650a9b 100644
|
|
--- a/src/mesa/drivers/dri/radeon/radeon_span.h
|
|
+++ b/src/mesa/drivers/dri/radeon/radeon_span.h
|
|
@@ -44,7 +44,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
#include "drirenderbuffer.h"
|
|
|
|
+#include "radeon_buffer.h"
|
|
+
|
|
extern void radeonInitSpanFuncs(GLcontext * ctx);
|
|
-extern void radeonSetSpanFunctions(driRenderbuffer * rb, const GLvisual * vis);
|
|
|
|
+#if COMPILE_R300
|
|
+extern void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
|
|
+#else
|
|
+extern void radeonSetSpanFunctions(driRenderbuffer * rb, const GLvisual * vis);
|
|
+#endif
|
|
#endif
|