Implement rendering of (flat color) QUAD primitives as an experiment.

This commit is contained in:
Vladimir Dergachev 2004-12-27 17:18:48 +00:00
parent 83fcf49647
commit 99edafd4e8
3 changed files with 238 additions and 14 deletions

View file

@ -1,5 +1,6 @@
# src/mesa/drivers/dri/r300/Makefile
TOP = ../../../../..
include $(TOP)/configs/current
@ -31,6 +32,7 @@ DRIVER_SOURCES = \
r300_cmdbuf.c \
r300_state.c \
r300_render.c \
r300_lib.c \
\
r200_context.c \
r200_ioctl.c \

View file

@ -0,0 +1,140 @@
#ifndef __EMIT_H__
#define __EMIT_H__
#include "glheader.h"
#include "r300_context.h"
#include "r300_cmdbuf.h"
/* convenience macros */
#define RADEON_CP_PACKET0 0x00000000
#define RADEON_CP_PACKET1 0x40000000
#define RADEON_CP_PACKET2 0x80000000
#define RADEON_CP_PACKET3 0xC0000000
#define RADEON_CP_PACKET3_NOP 0xC0001000
#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900
#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00
#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00
#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300
#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400
#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600
#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800
#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900
#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00
#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00
#define RADEON_CP_PACKET3_3D_DRAW_VBUF_2 0xC0003400
#define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500
#define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600
#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100
#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200
#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300
#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400
#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500
#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800
#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00
#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00
#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003202
#define RADEON_CP_PACKET3_3D_CLEAR_CMASK 0xC0003802
#define RADEON_CP_PACKET3_3D_CLEAR_HIZ 0xC0003702
#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
/* Glue to R300 Mesa driver */
#define LOCAL_VARS int cmd_reserved=0;\
int cmd_written=0; \
drm_radeon_cmd_header_t *cmd=NULL;
#define PREFIX_VOID r300ContextPtr rmesa
#define PREFIX PREFIX_VOID ,
#define PASS_PREFIX_VOID rmesa
#define PASS_PREFIX rmesa ,
typedef GLuint CARD32;
/* This files defines functions for accessing R300 hardware.
It needs to be customized to whatever code r300_lib.c is used
in */
void static inline check_space(int dwords)
{
}
static __inline__ uint32_t cmducs(int reg, int count)
{
drm_r300_cmd_header_t cmd;
cmd.unchecked_state.cmd_type = R300_CMD_UNCHECKED_STATE;
cmd.unchecked_state.count = count;
cmd.unchecked_state.reghi = ((unsigned int)reg & 0xFF00) >> 8;
cmd.unchecked_state.reglo = ((unsigned int)reg & 0x00FF);
return cmd.u;
}
static __inline__ uint32_t cmdvpu(int addr, int count)
{
drm_r300_cmd_header_t cmd;
cmd.vpu.cmd_type = R300_CMD_VPU;
cmd.vpu.count = count;
cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
return cmd.u;
}
/* Prepare to write a register value to register at address reg.
If num_extra > 0 then the following extra values are written
to registers with address +4, +8 and so on.. */
#define reg_start(reg, num_extra) \
{ \
int _n; \
_n=(num_extra); \
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
(_n+2), \
__FUNCTION__); \
cmd_reserved=_n+2; \
cmd_written=1; \
cmd[0].i=cmducs((reg), _n+1); \
}
/* Prepare to write a register value to register at address reg.
If num_extra > 0 then the following extra values are written
into the same register. */
#define reg_start_pump(reg, num_extra) \
{ \
fprintf(stderr, "I am not defined.. Error ! in %s::%s at line %d\n", \
__FILE__, __FUNCTION__, __LINE__); \
exit(-1); \
}
/* Emit CARD32 freestyle*/
#define e32(dword) { \
if(cmd_written<cmd_reserved){\
cmd[cmd_written].i=(dword); \
cmd_written++; \
} else { \
fprintf(stderr, "e32 but no previous packet declaration.. Aborting! in %s::%s at line %d\n", \
__FILE__, __FUNCTION__, __LINE__); \
exit(-1); \
} \
}
#define efloat(f) e32(r300PackFloat32(f))
#define vsf_start_fragment(dest, length) \
{ \
int _n; \
_n=(length); \
cmd=(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, \
(_n+1), \
__FUNCTION__); \
cmd_reserved=_n+2; \
cmd_written=1; \
cmd[0].i=cmdvpu((dest), _n/4); \
}
#endif

View file

@ -53,6 +53,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_reg.h"
#include "r300_program.h"
#include "r300_lib.h"
/**********************************************************************
* Hardware rasterization
@ -62,25 +64,47 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
**********************************************************************/
/**
* Called by the pipeline manager to render a batch of primitives.
* We can return true to pass on to the next stage (i.e. software
* rasterization) or false to indicate that the pipeline has finished
* after we render something.
*/
static GLboolean r300_run_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
static void r300_render_primitive(r300ContextPtr rmesa,
GLcontext *ctx,
int start,
int end,
int prim)
{
r300ContextPtr mmesa = R300_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
if (RADEON_DEBUG == DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
int k;
ADAPTOR adaptor;
LOCAL_VARS
if(end<=start)return; /* do we need to watch for this ? */
adaptor=TWO_PIPE_ADAPTOR;
adaptor.color_offset[0]=rmesa->radeon.radeonScreen->backOffset+rmesa->radeon.radeonScreen->fbLocation;
adaptor.color_pitch[0]=(rmesa->radeon.radeonScreen->backPitch) | (0xc0<<16);
for(i=0; i < VB->PrimitiveCount; i++){
switch (VB->Primitive[i].mode & PRIM_MODE_MASK) {
adaptor.depth_offset=rmesa->radeon.radeonScreen->depthOffset;
adaptor.depth_pitch=rmesa->radeon.radeonScreen->depthPitch | (0x2 << 16);
init_3d(PASS_PREFIX &adaptor);
init_flat_primitive(PASS_PREFIX &adaptor);
set_scissors(PASS_PREFIX 0, 0, 2647, 1941);
set_cliprect(PASS_PREFIX 0, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 1, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 2, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 3, 0, 0, 2647,1941);
reg_start(R300_RE_OCCLUSION_CNTL, 0);
e32(R300_OCCLUSION_ON);
set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0);
set_init21(PASS_PREFIX 0.0,1.0);
fprintf(stderr, "[%d-%d]", start, end);
switch (prim & PRIM_MODE_MASK) {
case GL_LINES:
fprintf(stderr, "L ");
break;
@ -101,6 +125,34 @@ static GLboolean r300_run_render(GLcontext *ctx,
break;
case GL_QUADS:
fprintf(stderr, "Q ");
for(i=start+3;i<end;i+=4){
start_primitive(PASS_PREFIX R300_VAP_VF_CNTL__PRIM_QUADS);
for(k=-3;k<=0;k++){
#if 1
fprintf(stderr, "* (%f %f %f) (%f %f %f)\n",
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[0],
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[1],
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[2],
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[0],
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[1],
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[2]
);
#endif
emit_flat_vertex(PASS_PREFIX
/* coordinates */
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[0],
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[1],
VEC_ELT(VB->ObjPtr, GLfloat, i+k)[2],
/* colors */
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[0],
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[1],
VEC_ELT(VB->ColorPtr[0], GLfloat, i+k)[2]
);
}
end_primitive(PASS_PREFIX_VOID);
}
break;
case GL_QUAD_STRIP:
fprintf(stderr, "QS ");
@ -109,10 +161,40 @@ static GLboolean r300_run_render(GLcontext *ctx,
fprintf(stderr, "%02x ", VB->Primitive[i].mode & PRIM_MODE_MASK);
break;
}
end_3d(PASS_PREFIX_VOID);
}
/**
* Called by the pipeline manager to render a batch of primitives.
* We can return true to pass on to the next stage (i.e. software
* rasterization) or false to indicate that the pipeline has finished
* after we render something.
*/
static GLboolean r300_run_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
if (RADEON_DEBUG == DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
for(i=0; i < VB->PrimitiveCount; i++){
GLuint prim = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
r300_render_primitive(rmesa, ctx, start, start + length, prim);
}
fprintf(stderr, "\n");
#if 0
return GL_TRUE;
#else
return GL_FALSE;
#endif
#if 0
mgaContextPtr mmesa = MGA_CONTEXT(ctx);