#include "main/imports.h"
#include "main/macros.h"
#include "main/context.h"
+#include "main/simple_list.h"
#include "swrast/swrast.h"
-#include "radeon_buffer.h"
+#include "radeon_common.h"
+#include "radeon_lock.h"
#include "r300_context.h"
-#include "radeon_ioctl.h"
#include "r300_ioctl.h"
#include "r300_cmdbuf.h"
#include "r300_state.h"
#include "r300_vertprog.h"
#include "radeon_reg.h"
#include "r300_emit.h"
-#include "r300_fragprog.h"
#include "r300_context.h"
#include "vblank.h"
#define CLEARBUFFER_DEPTH 0x2
#define CLEARBUFFER_STENCIL 0x4
+#if 1
+
+/**
+ * Fragment program helper macros
+ */
+
+/* Produce unshifted source selectors */
+#define FP_TMP(idx) (idx)
+#define FP_CONST(idx) ((idx) | (1 << 5))
+
+/* Produce source/dest selector dword */
+#define FP_SELC_MASK_NO 0
+#define FP_SELC_MASK_X 1
+#define FP_SELC_MASK_Y 2
+#define FP_SELC_MASK_XY 3
+#define FP_SELC_MASK_Z 4
+#define FP_SELC_MASK_XZ 5
+#define FP_SELC_MASK_YZ 6
+#define FP_SELC_MASK_XYZ 7
+
+#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
+ (((destidx) << R300_ALU_DSTC_SHIFT) | \
+ (FP_SELC_MASK_##regmask << 23) | \
+ (FP_SELC_MASK_##outmask << 26) | \
+ ((src0) << R300_ALU_SRC0C_SHIFT) | \
+ ((src1) << R300_ALU_SRC1C_SHIFT) | \
+ ((src2) << R300_ALU_SRC2C_SHIFT))
+
+#define FP_SELA_MASK_NO 0
+#define FP_SELA_MASK_W 1
+
+#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
+ (((destidx) << R300_ALU_DSTA_SHIFT) | \
+ (FP_SELA_MASK_##regmask << 23) | \
+ (FP_SELA_MASK_##outmask << 24) | \
+ ((src0) << R300_ALU_SRC0A_SHIFT) | \
+ ((src1) << R300_ALU_SRC1A_SHIFT) | \
+ ((src2) << R300_ALU_SRC2A_SHIFT))
+
+/* Produce unshifted argument selectors */
+#define FP_ARGC(source) R300_ALU_ARGC_##source
+#define FP_ARGA(source) R300_ALU_ARGA_##source
+#define FP_ABS(arg) ((arg) | (1 << 6))
+#define FP_NEG(arg) ((arg) ^ (1 << 5))
+
+/* Produce instruction dword */
+#define FP_INSTRC(opcode,arg0,arg1,arg2) \
+ (R300_ALU_OUTC_##opcode | \
+ ((arg0) << R300_ALU_ARG0C_SHIFT) | \
+ ((arg1) << R300_ALU_ARG1C_SHIFT) | \
+ ((arg2) << R300_ALU_ARG2C_SHIFT))
+
+#define FP_INSTRA(opcode,arg0,arg1,arg2) \
+ (R300_ALU_OUTA_##opcode | \
+ ((arg0) << R300_ALU_ARG0A_SHIFT) | \
+ ((arg1) << R300_ALU_ARG1A_SHIFT) | \
+ ((arg2) << R300_ALU_ARG2A_SHIFT))
+
+#endif
+
+static void r300EmitClearState(GLcontext * ctx);
+
static void r300ClearBuffer(r300ContextPtr r300, int flags,
struct radeon_renderbuffer *rrb,
struct radeon_renderbuffer *rrbd)
{
BATCH_LOCALS(&r300->radeon);
GLcontext *ctx = r300->radeon.glCtx;
- __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+ __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
GLuint cbpitch = 0;
r300ContextPtr rmesa = r300;
}
/* TODO in bufmgr */
- cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
- end_3d(rmesa);
+ cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
+ end_3d(&rmesa->radeon);
if (flags & CLEARBUFFER_COLOR) {
assert(rrb != 0);
}
#if 1
if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) {
- assert(rrbd != 0);
- cbpitch = (rrbd->pitch / rrbd->cpp);
+ uint32_t zbpitch = (rrbd->pitch / rrbd->cpp);
if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
- cbpitch |= R300_DEPTHMACROTILE_ENABLE;
+ zbpitch |= R300_DEPTHMACROTILE_ENABLE;
}
if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
- cbpitch |= R300_DEPTHMICROTILE_TILED;
+ zbpitch |= R300_DEPTHMICROTILE_TILED;
}
BEGIN_BATCH_NO_AUTOSTATE(6);
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);
+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1);
+ if (!r300->radeon.radeonScreen->kernel_mm)
+ OUT_BATCH(zbpitch);
+ else
+ OUT_BATCH_RELOC(zbpitch, rrbd->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
}
#endif
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);
+ cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
R300_STATECHANGE(r300, cb);
R300_STATECHANGE(r300, cmk);
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
BATCH_LOCALS(&r300->radeon);
- __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+ __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
int i;
- int has_tcl = 1;
+ int has_tcl;
int is_r500 = 0;
GLuint vap_cntl;
- if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
- has_tcl = 0;
+ has_tcl = r300->options.hw_tcl_enabled;
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
is_r500 = 1;
R500_ALU_RGBA_G_SWIZ_0 |
R500_ALU_RGBA_B_SWIZ_0 |
R500_ALU_RGBA_A_SWIZ_0;
-
+
r500fp.cmd[7] = 0;
- emit_r500fp(ctx, &r500fp);
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ emit_r500fp(ctx, &r500fp);
+ } else {
+ int dwords = r500fp.check(ctx,&r500fp);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(r500fp.cmd, dwords);
+ END_BATCH();
+ }
+
}
BEGIN_BATCH(2);
struct radeon_state_atom vpu;
uint32_t _cmd[10];
R300_STATECHANGE(r300, pvs);
+ R300_STATECHANGE(r300, vap_flush);
R300_STATECHANGE(r300, vpi);
BEGIN_BATCH(4);
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);
+ PVS_SRC_REG_INPUT, NEGATE_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);
+ PVS_SRC_REG_INPUT, NEGATE_NONE);
vpu.cmd[4] = 0x0;
vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf,
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);
+ NEGATE_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);
+ PVS_SRC_REG_INPUT, NEGATE_NONE);
vpu.cmd[8] = 0x0;
- emit_vpu(ctx, &vpu);
+
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ int dwords = r300->hw.vap_flush.check(ctx,&r300->hw.vap_flush);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(r300->hw.vap_flush.cmd, dwords);
+ END_BATCH();
+ emit_vpu(ctx, &vpu);
+ } else {
+ int dwords = vpu.check(ctx,&vpu);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(vpu.cmd, dwords);
+ END_BATCH();
+ }
+
}
}
-/**
- * Buffer clear
- */
-static void r300Clear(GLcontext * ctx, GLbitfield mask)
+static int r300KernelClear(GLcontext *ctx, GLuint flags)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
- __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
- GLframebuffer *fb = dPriv->driverPrivate;
+ __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
+ struct radeon_framebuffer *rfb = dPriv->driverPrivate;
struct radeon_renderbuffer *rrb;
struct radeon_renderbuffer *rrbd;
- int flags = 0;
- int bits = 0;
+ int bits = 0, ret;
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "r300Clear\n");
-
- {
- LOCK_HARDWARE(&r300->radeon);
- UNLOCK_HARDWARE(&r300->radeon);
- if (dPriv->numClipRects == 0)
- 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);
+ /* Make sure it fits there. */
+ radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
- if (mask & BUFFER_BIT_FRONT_LEFT) {
- flags |= BUFFER_BIT_FRONT_LEFT;
- mask &= ~BUFFER_BIT_FRONT_LEFT;
+ if (flags & BUFFER_BIT_COLOR0) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
}
- if (mask & BUFFER_BIT_BACK_LEFT) {
- flags |= BUFFER_BIT_BACK_LEFT;
- mask &= ~BUFFER_BIT_BACK_LEFT;
+ if (flags & BUFFER_BIT_FRONT_LEFT) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
}
- if (mask & BUFFER_BIT_DEPTH) {
- bits |= CLEARBUFFER_DEPTH;
- mask &= ~BUFFER_BIT_DEPTH;
+ if (flags & BUFFER_BIT_BACK_LEFT) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
}
- if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) {
- bits |= CLEARBUFFER_STENCIL;
- mask &= ~BUFFER_BIT_STENCIL;
+ rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+ if (rrbd) {
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM);
}
- if (mask) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "%s: swrast clear, mask: %x\n",
- __FUNCTION__, mask);
- _swrast_Clear(ctx, mask);
- }
+ ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs);
+ if (ret)
+ return -1;
- /* Make sure it fits there. */
rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
if (flags || bits)
r300EmitClearState(ctx);
- rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+
+ rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+ if (rrbd && (flags & BUFFER_BIT_DEPTH))
+ bits |= CLEARBUFFER_DEPTH;
+
+ if (rrbd && (flags & BUFFER_BIT_STENCIL))
+ bits |= CLEARBUFFER_STENCIL;
+
+ if (flags & BUFFER_BIT_COLOR0) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
+ r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
+ bits = 0;
+ }
if (flags & BUFFER_BIT_FRONT_LEFT) {
- rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
bits = 0;
}
if (flags & BUFFER_BIT_BACK_LEFT) {
- rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
bits = 0;
}
r300ClearBuffer(r300, bits, NULL, rrbd);
COMMIT_BATCH();
+ return 0;
}
-void r300Flush(GLcontext * ctx)
+/**
+ * Buffer clear
+ */
+static void r300Clear(GLcontext * ctx, GLbitfield mask)
{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
+ const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+ GLbitfield swrast_mask = 0, tri_mask = 0;
+ int i, ret;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s\n", __FUNCTION__);
+ fprintf(stderr, "r300Clear\n");
+
+ if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+ LOCK_HARDWARE(&r300->radeon);
+ UNLOCK_HARDWARE(&r300->radeon);
+ if (dPriv->numClipRects == 0)
+ return;
+ }
- if (rmesa->radeon.dma.flush) {
- rmesa->radeon.dma.flush(ctx);
+ /* 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 (colorMask == ~0)
+ tri_mask |= (mask & BUFFER_BITS_COLOR);
+ else
+ tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
+
+
+ /* HW stencil */
+ if (mask & BUFFER_BIT_STENCIL) {
+ tri_mask |= BUFFER_BIT_STENCIL;
+ }
+
+ /* HW depth */
+ if (mask & BUFFER_BIT_DEPTH) {
+ tri_mask |= BUFFER_BIT_DEPTH;
+ }
+
+ /* If we're doing a tri pass for depth/stencil, include a likely color
+ * buffer with it.
+ */
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ GLuint bufBit = 1 << i;
+ if ((tri_mask) & bufBit) {
+ if (!fb->Attachment[i].Renderbuffer->ClassID) {
+ tri_mask &= ~bufBit;
+ swrast_mask |= bufBit;
+ }
+ }
}
-
- if (rmesa->radeon.cmdbuf.cs->cdw) {
- rcommonFlushCmdBuf(&rmesa->radeon, __FUNCTION__);
+
+ /* SW fallback clearing */
+ swrast_mask = mask & ~tri_mask;
+
+ ret = 0;
+ if (tri_mask) {
+ if (r300->radeon.radeonScreen->kernel_mm)
+ radeonUserClear(ctx, tri_mask);
+ else {
+ /* if kernel clear fails due to size restraints fallback */
+ ret = r300KernelClear(ctx, tri_mask);
+ if (ret < 0)
+ swrast_mask |= tri_mask;
+ }
+ }
+
+ if (swrast_mask) {
+ if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "%s: swrast clear, mask: %x\n",
+ __FUNCTION__, swrast_mask);
+ _swrast_Clear(ctx, swrast_mask);
}
}
{
functions->Clear = r300Clear;
functions->Finish = radeonFinish;
- functions->Flush = r300Flush;
+ functions->Flush = radeonFlush;
}