summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-07-01 18:50:14 +1000
committerDave Airlie <airlied@linux.ie>2007-07-01 18:50:14 +1000
commitf556b7f84c47d9b32d7daa3e1559c92e47305eb2 (patch)
tree5ccd842445b69844ef70b6ae80c10ff0eee7cbbd
parentf4b103dc993491355ec3e3640d9cb060138175c2 (diff)
parent646ed82e6b2c092c6db364bf87d6881f39e83eec (diff)
Merge branch 'r300-swtcl'
-rw-r--r--src/mesa/drivers/dri/r300/Makefile1
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c10
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h67
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c60
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.h10
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c24
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c30
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c16
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.h7
-rw-r--r--src/mesa/drivers/dri/r300/r300_swtcl.c707
-rw-r--r--src/mesa/drivers/dri/r300/r300_swtcl.h45
13 files changed, 917 insertions, 63 deletions
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index c1d223c760..44248964fd 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -41,6 +41,7 @@ DRIVER_SOURCES = \
r300_fragprog.c \
r300_shader.c \
r300_emit.c \
+ r300_swtcl.c \
$(EGL_SOURCES)
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 7055286ba9..6adf141321 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -54,7 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_state.h"
// Set this to 1 for extremely verbose debugging of command buffers
-#define DEBUG_CMDBUF 0
+#define DEBUG_CMDBUF 1
/**
* Send the current command buffer via ioctl to the hardware.
@@ -321,8 +321,12 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.unk221C.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_221C, 1);
ALLOC_STATE(vap_clip, always, 5, 0);
r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_CLIP_X_0, 4);
- ALLOC_STATE(unk2288, always, 2, 0);
- r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1);
+
+ if (has_tcl) {
+ ALLOC_STATE(unk2288, always, 2, 0);
+ r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 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);
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 9ea14ab4c7..04e3fffa5d 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -63,6 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_ioctl.h"
#include "r300_tex.h"
#include "r300_emit.h"
+#include "r300_swtcl.h"
#ifdef USER_BUFFERS
#include "r300_mem.h"
@@ -363,6 +364,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
radeonInitSpanFuncs(ctx);
r300InitCmdBuf(r300);
r300InitState(r300);
+ r300InitSwtcl(ctx);
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index afd3dd384b..6615bc79fb 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -587,6 +587,11 @@ struct r300_vertex_shader_state {
extern int hw_tcl_on;
+#define COLOR_IS_RGBA
+#define TAG(x) r300##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp)
@@ -783,7 +788,8 @@ struct r300_state {
GLuint *Elts;
struct r300_dma_region elt_dma;
- DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for.
+ 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 */
struct r300_stencilbuffer_state stencil;
@@ -794,6 +800,62 @@ struct r300_state {
#define R300_FALLBACK_TCL 1
#define R300_FALLBACK_RAST 2
+/* r300_swtcl.c
+ */
+struct r300_swtcl_info {
+ GLuint RenderIndex;
+
+ /**
+ * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is
+ * installed in the Mesa state vector.
+ */
+ GLuint vertex_size;
+
+ /**
+ * Attributes instructing the Mesa TCL pipeline where / how to put vertex
+ * data in the hardware buffer.
+ */
+ struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+
+ /**
+ * Number of elements of \c ::vertex_attrs that are actually used.
+ */
+ GLuint vertex_attr_count;
+
+ /**
+ * Cached pointer to the buffer where Mesa will store vertex data.
+ */
+ GLubyte *verts;
+
+ /* Fallback rasterization functions
+ */
+ // r200_point_func draw_point;
+ // r200_line_func draw_line;
+ // r200_tri_func draw_tri;
+
+ GLuint hw_primitive;
+ GLenum render_primitive;
+ GLuint numverts;
+
+ /**
+ * Offset of the 4UB color data within a hardware (swtcl) vertex.
+ */
+ GLuint coloroffset;
+
+ /**
+ * Offset of the 3UB specular color data within a hardware (swtcl) vertex.
+ */
+ GLuint specoffset;
+
+ /**
+ * Should Mesa project vertex data or will the hardware do it?
+ */
+ GLboolean needproj;
+
+ struct r300_dma_region indexed_verts;
+};
+
+
/**
* \brief R300 context structure.
*/
@@ -832,6 +894,9 @@ struct r300_context {
GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
GLboolean disable_lowimpact_fallback;
+
+ DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */
+ struct r300_swtcl_info swtcl;
};
struct r300_buffer_object {
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 4670c28a02..229439dfa8 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -217,14 +217,14 @@ static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,
dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1);
dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16;
if (i + 2 == nr) {
- dw |= (1 << (13 + 16));
+ dw |= (R300_VAP_INPUT_ROUTE_END << 16);
}
dst[i >> 1] = dw;
}
if (nr & 1) {
dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[nr - 1]] << 8) | (attribptr[tab[nr - 1]]->size - 1);
- dw |= 1 << 13;
+ dw |= R300_VAP_INPUT_ROUTE_END;
dst[nr >> 1] = dw;
}
@@ -239,7 +239,7 @@ static GLuint r300VAPInputRoute1Swizzle(int swizzle[4])
(swizzle[3] << R300_INPUT_ROUTE_W_SHIFT);
}
-static GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr)
+GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr)
{
GLuint i;
@@ -255,14 +255,14 @@ static GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr)
return (nr + 1) >> 1;
}
-static GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead)
+GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead)
{
/* No idea what this value means. I have seen other values written to
* this register... */
return 0x5555;
}
-static GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
+GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLuint i, vic_1 = 0;
@@ -286,7 +286,7 @@ static GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
return vic_1;
}
-static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
+GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
{
GLuint ret = 0;
@@ -315,7 +315,7 @@ static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
return ret;
}
-static GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten)
+GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten)
{
GLuint i, ret = 0;
@@ -358,9 +358,11 @@ int r300EmitArrays(GLcontext * ctx)
DECLARE_RENDERINPUTS(render_inputs_bitset);
RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset);
+ vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr;
+
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));
+ //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0));
if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) {
InputsRead |= 1 << VERT_ATTRIB_POS;
@@ -392,20 +394,18 @@ int r300EmitArrays(GLcontext * ctx)
}
}
- if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
- /* Fixed, apply to vir0 only */
- memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int));
- inputs = vir_inputs;
- if (InputsRead & VERT_ATTRIB_POS)
- inputs[VERT_ATTRIB_POS] = 0;
- if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
- inputs[VERT_ATTRIB_COLOR0] = 2;
- if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
- inputs[VERT_ATTRIB_COLOR1] = 3;
- for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
- if (InputsRead & (1 << i))
- inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
- }
+ /* Fixed, apply to vir0 only */
+ memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int));
+ inputs = vir_inputs;
+ if (InputsRead & VERT_ATTRIB_POS)
+ inputs[VERT_ATTRIB_POS] = 0;
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
+ inputs[VERT_ATTRIB_COLOR0] = 2;
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
+ inputs[VERT_ATTRIB_COLOR1] = 3;
+ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++)
+ if (InputsRead & (1 << i))
+ inputs[i] = 6 + (i - VERT_ATTRIB_TEX0);
RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset);
}
@@ -532,3 +532,19 @@ void r300ReleaseArrays(GLcontext * ctx)
r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
}
}
+
+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_UNKNOWN_0A);
+
+ reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
+ e32(R300_RB3D_ZCACHE_UNKNOWN_03);
+
+
+}
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 2f79ee3a23..a6d69ec5ff 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -225,5 +225,15 @@ 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);
+
+extern void r300EmitCacheFlush(r300ContextPtr rmesa);
+
+extern GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr);
+extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead);
+extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead);
+extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten);
+extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 15c2cf3ad7..90f5027c9a 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -172,11 +172,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
- reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
- e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
-
- reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
- e32(R300_RB3D_ZCACHE_UNKNOWN_03);
+ r300EmitCacheFlush(rmesa);
cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
}
@@ -412,19 +408,22 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
void r300Flush(GLcontext * ctx)
{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
- if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
- r300FlushCmdBuf(r300, __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"
-static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
+void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
{
struct r300_dma_buffer *dmabuf;
size = MAX2(size, RADEON_BUFFER_SIZE * 16);
@@ -436,9 +435,12 @@ static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size)
rmesa->dma.flush(rmesa);
}
- if (rmesa->dma.current.buf)
+ 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__);
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h
index 7a19a2cf3f..e1143fb6c3 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.h
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.h
@@ -56,4 +56,5 @@ extern void r300AllocDmaRegion(r300ContextPtr rmesa,
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
+extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size);
#endif /* __R300_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 83999307b5..7d8defd1cd 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -79,7 +79,7 @@ extern int future_hw_tcl_on;
/**
* \brief Convert a OpenGL primitive type into a R300 primitive type.
*/
-static int r300PrimitiveType(r300ContextPtr rmesa, GLcontext * ctx, int prim)
+int r300PrimitiveType(r300ContextPtr rmesa, int prim)
{
switch (prim & PRIM_MODE_MASK) {
case GL_POINTS:
@@ -119,7 +119,7 @@ static int r300PrimitiveType(r300ContextPtr rmesa, GLcontext * ctx, int prim)
}
}
-static int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
+int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
{
int verts_off = 0;
@@ -261,7 +261,7 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
- type = r300PrimitiveType(rmesa, ctx, prim);
+ type = r300PrimitiveType(rmesa, prim);
num_verts = r300NumVerts(rmesa, end - start, prim);
if (type < 0 || num_verts <= 0)
@@ -287,29 +287,20 @@ static GLboolean r300RunRender(GLcontext * ctx,
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
int i;
- int cmd_reserved = 0;
- int cmd_written = 0;
- drm_radeon_cmd_header_t *cmd = NULL;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
+
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
- if (hw_tcl_on == GL_FALSE)
- vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr;
r300UpdateShaders(rmesa);
if (r300EmitArrays(ctx))
return GL_TRUE;
r300UpdateShaderStates(rmesa);
- reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
- e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
-
- reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
- e32(R300_RB3D_ZCACHE_UNKNOWN_03);
-
+ r300EmitCacheFlush(rmesa);
r300EmitState(rmesa);
for (i = 0; i < vb->PrimitiveCount; i++) {
@@ -319,11 +310,7 @@ static GLboolean r300RunRender(GLcontext * ctx,
r300RunRenderPrimitive(rmesa, ctx, start, end, prim);
}
- reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0);
- e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
-
- reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0);
- e32(R300_RB3D_ZCACHE_UNKNOWN_03);
+ r300EmitCacheFlush(rmesa);
#ifdef USER_BUFFERS
r300UseArrays(ctx);
@@ -384,12 +371,17 @@ static int r300Fallback(GLcontext * ctx)
static GLboolean r300RunNonTCLRender(GLcontext * ctx,
struct tnl_pipeline_stage *stage)
{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
if (r300Fallback(ctx) >= R300_FALLBACK_RAST)
return GL_TRUE;
+ if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
+ return GL_TRUE;
+
return r300RunRender(ctx, stage);
}
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 310102fcc5..b5cf21d644 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1782,13 +1782,15 @@ static void r300ResetHwState(r300ContextPtr r300)
r300->hw.vap_clip.cmd[4] = r300PackFloat32(1.0); /* Y */
/* XXX: Other families? */
- switch (r300->radeon.radeonScreen->chip_family) {
- case CHIP_FAMILY_R300:
- r300->hw.unk2288.cmd[1] = R300_2288_R300;
- break;
- default:
- r300->hw.unk2288.cmd[1] = R300_2288_RV350;
- break;
+ if (has_tcl) {
+ switch (r300->radeon.radeonScreen->chip_family) {
+ case CHIP_FAMILY_R300:
+ r300->hw.unk2288.cmd[1] = R300_2288_R300;
+ break;
+ default:
+ r300->hw.unk2288.cmd[1] = R300_2288_RV350;
+ break;
+ }
}
r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE
diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h
index 21a49b7f36..365f7ecd0c 100644
--- a/src/mesa/drivers/dri/r300/r300_state.h
+++ b/src/mesa/drivers/dri/r300/r300_state.h
@@ -37,8 +37,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_context.h"
+#define R300_NEWPRIM( rmesa ) \
+ do { \
+ if ( rmesa->dma.flush ) \
+ rmesa->dma.flush( rmesa ); \
+ } while (0)
+
#define R300_STATECHANGE(r300, atom) \
do { \
+ R300_NEWPRIM(r300); \
r300->hw.atom.dirty = GL_TRUE; \
r300->hw.is_dirty = GL_TRUE; \
} while(0)
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
new file mode 100644
index 0000000000..48122546c2
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
@@ -0,0 +1,707 @@
+/**************************************************************************
+
+Copyright (C) 2007 Dave Airlie
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Dave Airlie <airlied@linux.ie>
+ */
+
+/* derived from r200 swtcl path */
+
+
+
+#include "glheader.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "enums.h"
+#include "image.h"
+#include "imports.h"
+#include "macros.h"
+
+#include "swrast/s_context.h"
+#include "swrast/s_fog.h"
+#include "swrast_setup/swrast_setup.h"
+#include "math/m_translate.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+#include "r300_context.h"
+#include "r300_swtcl.h"
+#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 r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr);
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \
+ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \
+ rmesa->swtcl.vertex_attr_count++; \
+} while (0)
+
+#define EMIT_PAD( N ) \
+do { \
+ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \
+ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \
+ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \
+ rmesa->swtcl.vertex_attr_count++; \
+} while (0)
+
+/* this differs from the VIR0 in emit.c - TODO merge them using another option */
+static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,
+ int *inputs, GLint * tab, GLuint nr)
+{
+ GLuint i, dw;
+
+ /* type, inputs, stop bit, size */
+ for (i = 0; i + 1 < nr; i += 2) {
+ dw = (inputs[tab[i]] << 8) | 0x3;
+ dw |= ((inputs[tab[i + 1]] << 8) | 0x3) << 16;
+ if (i + 2 == nr) {
+ dw |= (R300_VAP_INPUT_ROUTE_END << 16);
+ }
+ dst[i >> 1] = dw;
+ }
+
+ if (nr & 1) {
+ dw = (inputs[tab[nr - 1]] << 8) | 0x3;
+ dw |= R300_VAP_INPUT_ROUTE_END;
+ dst[nr >> 1] = dw;
+ }
+
+ return (nr + 1) >> 1;
+}
+
+static void r300SetVertexFormat( GLcontext *ctx )
+{
+ r300ContextPtr rmesa = R300_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ 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];
+ GLint tab[VERT_ATTRIB_MAX];
+ int swizzle[VERT_ATTRIB_MAX][4];
+ GLuint i, nr;
+
+ DECLARE_RENDERINPUTS(render_inputs_bitset);
+ RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset);
+ RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
+ RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset);
+
+ /* Important:
+ */
+ if ( VB->NdcPtr != NULL ) {
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+ }
+ else {
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
+ }
+
+ assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
+ rmesa->swtcl.vertex_attr_count = 0;
+
+ /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
+ * build up a hardware vertex.
+ */
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS)) {
+ vap_vte_cntl |= R300_VTX_W0_FMT;
+ InputsRead |= 1 << VERT_ATTRIB_POS;
+ OutputsWritten |= 1 << VERT_RESULT_HPOS;
+ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
+ } else
+ EMIT_PAD(4 * sizeof(float));
+
+ offset = 4;
+
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
+ EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
+ vap_fmt_0 |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+ offset += 1;
+ }
+
+ rmesa->swtcl.coloroffset = offset;
+ if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) {
+ InputsRead |= 1 << VERT_ATTRIB_COLOR0;
+ OutputsWritten |= 1 << VERT_RESULT_COL0;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F );
+ } else
+ EMIT_PAD(4*sizeof(float));
+
+ offset += 4;
+
+ rmesa->swtcl.specoffset = 0;
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+ rmesa->swtcl.specoffset = offset;
+ EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F );
+ InputsRead |= 1 << VERT_ATTRIB_COLOR1;
+ OutputsWritten |= 1 << VERT_RESULT_COL1;
+ }
+
+ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
+ int i;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
+ InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
+ OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
+ EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_4F );
+ }
+ }
+ }
+
+ for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (InputsRead & (1 << i)) {
+ inputs[i] = nr++;
+ } else {
+ inputs[i] = -1;
+ }
+ }
+
+ /* Fixed, apply to vir0 only */
+ if (InputsRead & VERT_ATTRIB_POS)
+ inputs[VERT_ATTRIB_POS] = 0;
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR0))
+ inputs[VERT_ATTRIB_COLOR0] = 2;
+ if (InputsRead & (1 << VERT_ATTRIB_COLOR1))
+ inputs[VERT_ATTRIB_COLOR1] = 3;
+ 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;
+ swizzle[i][3] = SWIZZLE_ONE;
+
+ for (ci = 0; ci < VB->AttribPtr[tab[i]]->size; ci++) {
+ swizzle[i][ci] = ci;
+ }
+ }
+
+ R300_NEWPRIM(rmesa);
+ 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],
+ VB->AttribPtr, inputs, tab, nr);
+ R300_STATECHANGE(rmesa, vir[1]);
+ ((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] = r300VAPOutputCntl1(ctx, OutputsWritten);
+
+ rmesa->swtcl.vertex_size =
+ _tnl_install_attrs( ctx,
+ rmesa->swtcl.vertex_attrs,
+ rmesa->swtcl.vertex_attr_count,
+ NULL, 0 );
+
+ rmesa->swtcl.vertex_size /= 4;
+
+ RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset );
+
+ vte = rmesa->hw.vte.cmd[1];
+ R300_STATECHANGE(rmesa, vte);
+ rmesa->hw.vte.cmd[1] = vte;
+ rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size;
+}
+
+
+/* Flush vertices in the current dma region.
+ */
+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;
+ }
+}
+
+/* Alloc space in the current dma region.
+ */
+static void *
+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;
+ }
+}
+
+static GLuint reduced_prim[] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_LINES,
+ GL_LINES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+ GL_TRIANGLES,
+};
+
+static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
+static void r300RenderPrimitive( GLcontext *ctx, GLenum prim );
+//static void r300ResetLineStipple( GLcontext *ctx );
+
+/***********************************************************************
+ * Emit primitives as inline vertices *
+ ***********************************************************************/
+
+
+#define HAVE_POINTS 1
+#define HAVE_LINES 1
+#define HAVE_LINE_STRIPS 1
+#define HAVE_TRIANGLES 1
+#define HAVE_TRI_STRIPS 1
+#define HAVE_TRI_STRIP_1 0
+#define HAVE_TRI_FANS 1
+#define HAVE_QUADS 0
+#define HAVE_QUAD_STRIPS 0
+#define HAVE_POLYGONS 1
+#define HAVE_ELTS 1
+
+#undef LOCAL_VARS
+#undef ALLOC_VERTS
+#define CTX_ARG r300ContextPtr rmesa
+#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size
+#define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 )
+#define LOCAL_VARS \
+ 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 DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS))
+#define PRINT_VERTEX(x)
+#undef TAG
+#define TAG(x) r300_##x
+#include "tnl_dd/t_dd_triemit.h"
+
+
+
+/***********************************************************************
+ * Macros for t_dd_tritmp.h to draw basic primitives *
+ ***********************************************************************/
+
+#define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d )
+#define TRI( a, b, c ) r300_triangle( rmesa, a, b, c )
+#define LINE( a, b ) r300_line( rmesa, a, b )
+#define POINT( a ) r300_point( rmesa, a )
+
+/***********************************************************************
+ * Build render functions from dd templates *
+ ***********************************************************************/
+
+#define R300_TWOSIDE_BIT 0x01
+#define R300_UNFILLED_BIT 0x02
+#define R300_MAX_TRIFUNC 0x04
+
+static struct {
+ tnl_points_func points;
+ tnl_line_func line;
+ tnl_triangle_func triangle;
+ tnl_quad_func quad;
+} rast_tab[R300_MAX_TRIFUNC];
+
+#define DO_FALLBACK 0
+#define DO_UNFILLED (IND & R300_UNFILLED_BIT)
+#define DO_TWOSIDE (IND & R300_TWOSIDE_BIT)
+#define DO_FLAT 0
+#define DO_OFFSET 0
+#define DO_TRI 1
+#define DO_QUAD 1
+#define DO_LINE 1
+#define DO_POINTS 1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA 1
+#define HAVE_SPEC 1
+#define HAVE_BACK_COLORS 0
+#define HAVE_HW_FLATSHADE 1
+#define TAB rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->v.x
+#define VERT_Y(_v) _v->v.y
+#define VERT_Z(_v) _v->v.z
+#define AREA_IS_CCW( a ) (a < 0)
+#define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int)))
+
+/* Only used to pull back colors into vertices (ie, we know color is
+ * floating point).
+ */
+#define R300_COLOR( dst, src ) \
+do { \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \
+} while (0)
+
+#define VERT_SET_RGBA( v, c ) if (coloroffset) R300_COLOR( v->ub4[coloroffset], c )
+#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset]
+#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset]
+#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx]
+
+#define R300_SPEC( dst, src ) \
+do { \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \
+ UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \
+} while (0)
+
+#define VERT_SET_SPEC( v, c ) if (specoffset) R300_SPEC( v->ub4[specoffset], c )
+#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset])
+#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
+
+#undef LOCAL_VARS
+#undef TAG
+#undef INIT
+
+#define LOCAL_VARS(n) \
+ r300ContextPtr rmesa = R300_CONTEXT(ctx); \
+ GLuint color[n], spec[n]; \
+ GLuint coloroffset = rmesa->swtcl.coloroffset; \
+ GLuint specoffset = rmesa->swtcl.specoffset; \
+ (void) color; (void) spec; (void) coloroffset; (void) specoffset;
+
+/***********************************************************************
+ * Helpers for rendering unfilled primitives *
+ ***********************************************************************/
+
+#define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] )
+#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
+#undef TAG
+#define TAG(x) x
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+
+/***********************************************************************
+ * Generate GL render functions *
+ ***********************************************************************/
+
+
+#define IND (0)
+#define TAG(x) x
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (R300_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (R300_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+
+
+static void init_rast_tab( void )
+{
+ init();
+ init_twoside();
+ init_unfilled();
+ init_twoside_unfilled();
+}
+
+/**********************************************************************/
+/* Render unclipped begin/end objects */
+/**********************************************************************/
+
+#define RENDER_POINTS( start, count ) \
+ for ( ; start < count ; start++) \
+ r300_point( rmesa, VERT(start) )
+#define RENDER_LINE( v0, v1 ) \
+ r300_line( rmesa, VERT(v0), VERT(v1) )
+#define RENDER_TRI( v0, v1, v2 ) \
+ r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+ r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
+#define INIT(x) do { \
+ r300RenderPrimitive( ctx, x ); \
+} while (0)
+#undef LOCAL_VARS
+#define LOCAL_VARS \
+ r300ContextPtr rmesa = R300_CONTEXT(ctx); \
+ const GLuint vertsize = rmesa->swtcl.vertex_size; \
+ const char *r300verts = (char *)rmesa->swtcl.verts; \
+ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
+ const GLboolean stipple = ctx->Line.StippleFlag; \
+ (void) elt; (void) stipple;
+#define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
+#define RESET_OCCLUSION
+#define PRESERVE_VB_DEFS
+#define ELT(x) (x)
+#define TAG(x) r300_##x##_verts
+#include "tnl/t_vb_rendertmp.h"
+#undef ELT
+#undef TAG
+#define TAG(x) r300_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl/t_vb_rendertmp.h"
+
+
+
+
+/**********************************************************************/
+/* Choose render functions */
+/**********************************************************************/
+static void r300ChooseRenderState( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ GLuint index = 0;
+ GLuint flags = ctx->_TriangleCaps;
+
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
+
+ if (index != rmesa->swtcl.RenderIndex) {
+ tnl->Driver.Render.Points = rast_tab[index].points;
+ tnl->Driver.Render.Line = rast_tab[index].line;
+ tnl->Driver.Render.ClippedLine = rast_tab[index].line;
+ tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+ tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+ if (index == 0) {
+ tnl->Driver.Render.PrimTabVerts = r300_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = r300_render_tab_elts;
+ tnl->Driver.Render.ClippedPolygon = r300_fast_clipped_poly;
+ } else {
+ tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+ tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
+ }
+
+ rmesa->swtcl.RenderIndex = index;
+ }
+}
+
+
+static void r300RenderStart(GLcontext *ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT( ctx );
+ // fprintf(stderr, "%s\n", __FUNCTION__);
+
+ r300ChooseRenderState(ctx);
+ r300SetVertexFormat(ctx);
+
+ r300UpdateShaderStates(rmesa);
+
+ r300EmitCacheFlush(rmesa);
+
+ if (rmesa->dma.flush != 0 &&
+ rmesa->dma.flush != flush_last_swtcl_prim)
+ rmesa->dma.flush( rmesa );
+
+}
+
+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;
+ }
+}
+
+static void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
+{
+
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ rmesa->swtcl.render_primitive = prim;
+
+ if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+ return;
+
+ r300RasterPrimitive( ctx, reduced_prim[prim] );
+ // fprintf(stderr, "%s\n", __FUNCTION__);
+
+}
+
+static void r300ResetLineStipple(GLcontext *ctx)
+{
+
+
+}
+
+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;
+ tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple;
+ 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,
+ 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;
+
+ _tnl_invalidate_vertex_state( ctx, ~0 );
+ _tnl_invalidate_vertices( ctx, ~0 );
+ RENDERINPUTS_ZERO( rmesa->tnl_index_bitset );
+
+ _tnl_need_projected_coords( ctx, GL_FALSE );
+ r300ChooseRenderState(ctx);
+}
+
+void r300DestroySwtcl(GLcontext *ctx)
+{
+}
+
+void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset)
+{
+ int cmd_reserved = 0;
+ int cmd_written = 0;
+
+ 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);
+}
+
+void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
+{
+
+ int cmd_reserved = 0;
+ int cmd_written = 0;
+ 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);
+}
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.h b/src/mesa/drivers/dri/r300/r300_swtcl.h
new file mode 100644
index 0000000000..2ea6ceded7
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.h
@@ -0,0 +1,45 @@
+/*
+Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com> - original r200 code
+ * Dave Airlie <airlied@linux.ie>
+ */
+
+#ifndef __R300_SWTCL_H__
+#define __R300_SWTCL_H__
+
+#include "mtypes.h"
+#include "swrast/swrast.h"
+#include "r300_context.h"
+
+extern void r300InitSwtcl( GLcontext *ctx );
+extern void r300DestroySwtcl( GLcontext *ctx );
+
+#endif