X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fnouveau%2Fnv30_state.c;h=cd3ee9868805f8cab3c84f55391276caac72c541;hb=3cc4e9815d4962e5f5e7b23bae1cf9b82092bb52;hp=e30dc8a37c360e6849a7e71b335b4b40d5cb818a;hpb=aadcf1a9ff7e3f92977380d16b4ad2e676d7eb18;p=mesa.git diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e30dc8a37c3..cd3ee986880 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) 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]); @@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) 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); @@ -233,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) 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; @@ -293,8 +306,10 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // 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: @@ -346,17 +361,71 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) 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) @@ -367,6 +436,7 @@ 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 @@ -377,7 +447,7 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa 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; @@ -410,13 +480,13 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa 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); @@ -434,13 +504,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa 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); @@ -462,13 +533,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa 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); @@ -500,7 +572,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) 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); @@ -567,30 +639,45 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** 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 */ @@ -671,36 +758,34 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, 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]); @@ -718,8 +803,67 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) 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) @@ -736,51 +880,67 @@ 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) @@ -802,6 +962,7 @@ 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;