static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
+ plane -= GL_CLIP_PLANE0;
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
OUT_RING_CACHEf(equation[0]);
OUT_RING_CACHEf(equation[1]);
case GL_CLIP_PLANE3:
case GL_CLIP_PLANE4:
case GL_CLIP_PLANE5:
- BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
- OUT_RING_CACHE(state);
+ if (NOUVEAU_CARD_USING_SHADERS) {
+ nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
+ if (nvs)
+ nvs->translated = GL_FALSE;
+ } else {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+ OUT_RING_CACHE(state);
+ }
break;
case GL_COLOR_LOGIC_OP:
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
OUT_RING_CACHE(state);
break;
case GL_FOG:
+ if (NOUVEAU_CARD_USING_SHADERS)
+ break;
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
OUT_RING_CACHE(state);
break;
// case GL_MAP2_VERTEX_4:
// case GL_MINMAX:
case GL_NORMALIZE:
- BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
- OUT_RING_CACHE(state);
+ if (nmesa->screen->card->type != NV_44) {
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+ OUT_RING_CACHE(state);
+ }
break;
// case GL_POINT_SMOOTH:
case GL_POLYGON_OFFSET_POINT:
static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ if (NOUVEAU_CARD_USING_SHADERS)
+ return;
+
switch(pname)
{
- case GL_FOG_MODE:
- //BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
- //OUT_RING_CACHE (params);
+ case GL_FOG_MODE:
+ {
+ int mode = 0;
+ /* The modes are different in GL and the card. */
+ switch(ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ mode = 0x804;
break;
- /* TODO: unsure about the rest.*/
- default:
+ case GL_EXP:
+ mode = 0x802;
break;
+ case GL_EXP2:
+ mode = 0x803;
+ break;
+ }
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+ OUT_RING_CACHE (mode);
+ break;
+ }
+ case GL_FOG_COLOR:
+ {
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1);
+ /* nvidia ignores the alpha channel */
+ OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
+ break;
+ }
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ {
+ GLfloat f=0., c=0.;
+ switch(ctx->Fog.Mode)
+ {
+ case GL_LINEAR:
+ f = -1.0/(ctx->Fog.End - ctx->Fog.Start);
+ c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953;
+ break;
+ case GL_EXP:
+ f = -0.090168*ctx->Fog.Density;
+ c = 1.5;
+ case GL_EXP2:
+ f = -0.212330*ctx->Fog.Density;
+ c = 1.5;
+ }
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1);
+ OUT_RING_CACHE(f);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1);
+ OUT_RING_CACHE(c);
+ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1);
+ OUT_RING_CACHE(0); /* Is this always the same? */
+ break;
+ }
+// case GL_FOG_COORD_SRC:
+ default:
+ break;
}
-
}
static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode)
// void (*IndexMask)(GLcontext *ctx, GLuint mask);
enum {
+ SPOTLIGHT_NO_UPDATE,
SPOTLIGHT_UPDATE_EXPONENT,
SPOTLIGHT_UPDATE_DIRECTION,
SPOTLIGHT_UPDATE_ALL
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
GLint p = light - GL_LIGHT0;
struct gl_light *l = &ctx->Light.Light[p];
- int spotlightUpdate = -1;
+ int spotlight_update = SPOTLIGHT_NO_UPDATE;
if (NOUVEAU_CARD_USING_SHADERS)
return;
OUT_RING_CACHEf(params[2]);
break;
case GL_SPOT_DIRECTION:
- spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION;
+ spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
break;
case GL_SPOT_EXPONENT:
- spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT;
+ spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
break;
case GL_SPOT_CUTOFF:
- spotlightUpdate = SPOTLIGHT_UPDATE_ALL;
+ spotlight_update = SPOTLIGHT_UPDATE_ALL;
break;
case GL_CONSTANT_ATTENUATION:
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
break;
}
- switch(spotlightUpdate) {
+ switch(spotlight_update) {
case SPOTLIGHT_UPDATE_DIRECTION:
{
GLfloat x,y,z;
- x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0];
- y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1];
- z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2];
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
OUT_RING_CACHEf(x);
OUT_RING_CACHEf(y);
case SPOTLIGHT_UPDATE_ALL:
{
GLfloat cc,lc,qc, x,y,z, c;
+ GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
cc = 1.0; /* FIXME: These need to be correctly computed */
lc = 0.0;
qc = 2.0;
- x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0];
- y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1];
- z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2];
- c = -2.0 * (0.5 + l->_CosCutoff);
+ x = spot_light_coef_a * l->_NormDirection[0];
+ y = spot_light_coef_a * l->_NormDirection[1];
+ z = spot_light_coef_a * l->_NormDirection[2];
+ c = spot_light_coef_a + 1.0;
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
OUT_RING_CACHEf(cc);
OUT_RING_CACHEf(lc);
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
GLubyte ubWidth;
- CLAMPED_FLOAT_TO_UBYTE(ubWidth, width);
+ ubWidth = (GLubyte)(width * 8.0) & 0xFF;
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1);
OUT_RING_CACHE(ubWidth);
/** Set rasterization mode */
void (*RenderMode)(GLcontext *ctx, GLenum mode );
+/* Translate GL coords to window coords, clamping w/h to the
+ * dimensions of the window.
+ */
+static void nv30WindowCoords(nouveauContextPtr nmesa,
+ GLuint x, GLuint y, GLuint w, GLuint h,
+ GLuint *wX, GLuint *wY, GLuint *wW, GLuint *wH)
+{
+ if ((x+w) > nmesa->drawW)
+ w = nmesa->drawW - x;
+ (*wX) = x + nmesa->drawX;
+ (*wW) = w;
+
+ if ((y+h) > nmesa->drawH)
+ h = nmesa->drawH - y;
+ (*wY) = (nmesa->drawH - y) - h + nmesa->drawY;
+ (*wH) = h;
+}
+
/** Define the scissor box */
static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
- nouveau_renderbuffer *nrb;
-
- /* Adjust offsets if drawing to a window */
- nrb = nouveau_current_draw_buffer(ctx);
- if (nrb && nrb->map) {
- x += nrb->dPriv->x;
- y += nrb->dPriv->y;
- }
+ GLuint wX, wY, wW, wH;
/* There's no scissor enable bit, so adjust the scissor to cover the
* maximum draw buffer bounds
*/
if (!ctx->Scissor.Enabled) {
- x = y = 0;
- w = h = 4095;
+ wX = nmesa->drawX;
+ wY = nmesa->drawY;
+ wW = nmesa->drawW;
+ wH = nmesa->drawH;
+ } else {
+ nv30WindowCoords(nmesa, x, y, w, h, &wX, &wY, &wW, &wH);
}
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
- OUT_RING_CACHE(((w) << 16) | x);
- OUT_RING_CACHE(((h) << 16) | y);
+ OUT_RING_CACHE ((wW << 16) | wX);
+ OUT_RING_CACHE ((wH << 16) | wY);
}
/** Select flat or smooth shading */
static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
- BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
- /*XXX: This SHOULD work.*/
- OUT_RING_CACHEp(mat->m, 16);
+
+ if (!NOUVEAU_CARD_USING_SHADERS) {
+ BEGIN_RING_CACHE(NvSub3D,
+ NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+ /*XXX: This SHOULD work.*/
+ OUT_RING_CACHEp(mat->m, 16);
+ }
}
static void nv30WindowMoved(nouveauContextPtr nmesa)
{
GLcontext *ctx = nmesa->glCtx;
- nouveau_renderbuffer *nrb;
GLfloat *v = nmesa->viewport.m;
- GLuint w = ctx->Viewport.Width;
- GLuint h = ctx->Viewport.Height;
- GLuint x = ctx->Viewport.X;
- GLuint y = ctx->Viewport.Y;
-
- /* Adjust offsets if drawing to a window */
- nrb = nouveau_current_draw_buffer(ctx);
- if (nrb && nrb->map) {
- x += nrb->dPriv->x;
- y += nrb->dPriv->y;
- }
+ GLuint wX, wY, wW, wH;
+ nv30WindowCoords(nmesa, ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height,
+ &wX, &wY, &wW, &wH);
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
- OUT_RING_CACHE((w << 16) | x);
- OUT_RING_CACHE((h << 16) | y);
+ OUT_RING_CACHE ((wW << 16) | wX);
+ OUT_RING_CACHE ((wH << 16) | wY);
+
/* something to do with clears, possibly doesn't belong here */
BEGIN_RING_CACHE(NvSub3D,
NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
- OUT_RING_CACHE(((w+x) << 16) | x);
- OUT_RING_CACHE(((h+y) << 16) | y);
+ OUT_RING_CACHE(((nmesa->drawX + nmesa->drawW) << 16) | nmesa->drawX);
+ OUT_RING_CACHE(((nmesa->drawY + nmesa->drawH) << 16) | nmesa->drawY);
+
/* viewport transform */
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
OUT_RING_CACHEf (v[MAT_TX]);
static GLboolean nv30InitCard(nouveauContextPtr nmesa)
{
- /* Need some love.. */
- return GL_FALSE;
+ int i;
+ nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaTT);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
+ OUT_RING(NvDmaFB);
+ OUT_RING(NvDmaFB);
+ BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/
+ OUT_RING(NvDmaFB);
+
+ for(i = 0x2c8; i <= 0x2fc; i += 4)
+ {
+ BEGIN_RING_SIZE(NvSub3D, i, 1);
+ OUT_RING(0x0);
+ }
+
+ BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
+ OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1);
+ OUT_RING(0x00100000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1454, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
+ OUT_RING(3);
+
+ /* NEW */
+ BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
+ OUT_RING(0);
+ BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
+ OUT_RING(0);
+ OUT_RING(0);
+ OUT_RING(0x3f800000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0x0000ffff);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
+ OUT_RING(0); OUT_RING(0); OUT_RING(0);
+/*
+ BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
+ OUT_RING(0);
+ OUT_RING(0);
+*/
+ BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
+ OUT_RING(0);
+ OUT_RING(1);
+ OUT_RING(2);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
+ OUT_RING(0x00001200);
+
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
+ OUT_RING (0);
+
+ return GL_TRUE;
}
static GLboolean nv40InitCard(nouveauContextPtr nmesa)
OUT_RING(NvDmaFB);
BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
OUT_RING(1);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3);
+ OUT_RING(0x00000010);
+ OUT_RING(0x01000100);
+ OUT_RING(0xff800006);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1);
+ OUT_RING(0x06144321);
BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
OUT_RING(0xedcba987);
OUT_RING(0x00000021);
- BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
- OUT_RING(0x03008000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1);
+ OUT_RING(0x00171615);
+ BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1);
+ OUT_RING(0x001b1a19);
+
+ BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1);
+ OUT_RING(0x0020ffff);
+ BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1);
+ OUT_RING(0x00d30000);
+ BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1);
+ OUT_RING(0x00000001);
return GL_TRUE;
}
-static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
- nouveau_renderbuffer **color,
- nouveau_renderbuffer *depth)
-{
- nouveau_renderbuffer *nrb;
- GLuint x, y, w, h;
-
- /* Adjust offsets if drawing to a window */
- nrb = nouveau_current_draw_buffer(nmesa->glCtx);
- w = nrb->mesa.Width;
- h = nrb->mesa.Height;
- if (nrb && nrb->map) {
- x = nrb->dPriv->x;
- y = nrb->dPriv->y;
- } else {
- x = 0;
- y = 0;
- }
-
- if (num_color != 1)
- return GL_FALSE;
- BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
- OUT_RING (((w+x)<<16)|x);
- OUT_RING (((h+y)<<16)|y);
- OUT_RING (0x148);
- OUT_RING (color[0]->pitch);
- OUT_RING (color[0]->offset);
-
- if (depth) {
- BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
- OUT_RING (depth->offset);
- BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
- OUT_RING (depth->pitch);
- }
-
- return GL_TRUE;
+static GLboolean
+nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth)
+{
+ GLuint x, y, w, h;
+
+ w = color[0]->mesa.Width;
+ h = color[0]->mesa.Height;
+ x = nmesa->drawX;
+ y = nmesa->drawY;
+
+ if (num_color != 1)
+ return GL_FALSE;
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
+ OUT_RING (((w+x)<<16)|x);
+ OUT_RING (((h+y)<<16)|y);
+ if (color[0]->mesa._ActualFormat == GL_RGBA8)
+ OUT_RING (0x148);
+ else
+ OUT_RING (0x143);
+ if (nmesa->screen->card->type >= NV_40)
+ OUT_RING (color[0]->pitch);
+ else
+ OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0));
+ OUT_RING (color[0]->offset);
+
+ if (depth) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
+ OUT_RING (depth->offset);
+ if (nmesa->screen->card->type >= NV_40) {
+ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
+ OUT_RING (depth->pitch);
+ }
+ }
+
+ return GL_TRUE;
}
void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
func->FrontFace = nv30FrontFace;
func->DepthFunc = nv30DepthFunc;
func->DepthMask = nv30DepthMask;
+ func->DepthRange = nv30DepthRange;
func->Enable = nv30Enable;
func->Fogfv = nv30Fogfv;
func->Hint = nv30Hint;