Merge branch 'r300-swtcl'
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__);
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user