From: Aapo Tahkola Date: Fri, 14 Jan 2005 21:53:00 +0000 (+0000) Subject: Added fixes for filter modes and support for anisotropy filters. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ffe7496ac37a61b94c1db676e105fda2c3e6eb18;p=mesa.git Added fixes for filter modes and support for anisotropy filters. Wrap modes would work perfectly but i messed up something when cleaning up the code :/ Border color code is incomplete because i forgot to check how to set border size :) --- diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 3d8f4e97118..92f107b9db9 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -452,6 +452,9 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE( tex.unknown5, variable, mtu+1, "tex_unknown5", 0 ); r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK5_0, 0); + + ALLOC_STATE( tex.border_color, variable, mtu+1, "tex_border_color", 0 ); + r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_BORDER_COLOR_0, 0); /* Setup the atom linked list */ @@ -531,6 +534,7 @@ void r300InitCmdBuf(r300ContextPtr r300) insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.offset); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown4); insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown5); + insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.border_color); r300->hw.is_dirty = GL_TRUE; r300->hw.all_dirty = GL_TRUE; diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index a561f31118e..6a7427b168b 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -441,7 +441,8 @@ struct r300_hw_state { struct r300_state_atom format; struct r300_state_atom offset; struct r300_state_atom unknown4; - struct r300_state_atom unknown5; + struct r300_state_atom unknown5; + struct r300_state_atom border_color; } tex; struct r300_state_atom txe; /* tex enable (4104) */ }; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index d701ccc2f46..1244579964a 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -565,31 +565,44 @@ I am fairly certain that they are correct unless stated otherwise in comments. // TX_OFFSET_0 + (4*N) */ #define R300_TX_FILTER_0 0x4400 # define R300_TX_REPEAT 0 -# define R300_TX_CLAMP_TO_EDGE 1 -# define R300_TX_CLAMP 2 -# define R300_TX_CLAMP_TO_BORDER 3 - -# define R300_TX_WRAP_S_SHIFT 1 -# define R300_TX_WRAP_S_MASK (3 << 1) -# define R300_TX_WRAP_T_SHIFT 4 -# define R300_TX_WRAP_T_MASK (3 << 4) +# define R300_TX_MIRRORED 1 +# define R300_TX_CLAMP 4 +# define R300_TX_CLAMP_TO_EDGE 2 +# define R300_TX_CLAMP_TO_BORDER 6 +# define R300_TX_WRAP_S_SHIFT 0 +# define R300_TX_WRAP_S_MASK (7 << 0) +# define R300_TX_WRAP_T_SHIFT 3 +# define R300_TX_WRAP_T_MASK (7 << 3) +# define R300_TX_WRAP_Q_SHIFT 6 +# define R300_TX_WRAP_Q_MASK (7 << 6) # define R300_TX_MAG_FILTER_NEAREST (1 << 9) # define R300_TX_MAG_FILTER_LINEAR (2 << 9) # define R300_TX_MAG_FILTER_MASK (3 << 9) # define R300_TX_MIN_FILTER_NEAREST (1 << 11) # define R300_TX_MIN_FILTER_LINEAR (2 << 11) -/* TODO: Test and verify R300_TX_MIN_FILTER_MASK */ -# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 12) -# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 12) -# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 12) -# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 12) -# define R300_TX_MIN_FILTER_ANISO_NEAREST (8 << 12) -# define R300_TX_MIN_FILTER_ANISO_LINEAR (9 << 12) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 12) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 12) - -# define R300_TX_MIN_FILTER_MASK (0x0000f800) +# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) +# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) +# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) +# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) + +/* NOTE: NEAREST doesnt seem to exist. + Im not seting MAG_FILTER_MASK and (3 << 11) on for all + anisotropy modes because that would void selected mag filter */ +# define R300_TX_MIN_FILTER_ANISO_NEAREST ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_LINEAR ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST ((1 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR ((2 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) +# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) ) +# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) +# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21) +# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21) +# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21) +# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) +# define R300_TX_MAX_ANISO_MASK (14 << 21) + #define R300_TX_UNK1_0 0x4440 +# define R300_LOD_BIAS_MASK 0x1fff + #define R300_TX_SIZE_0 0x4480 # define R300_TX_WIDTHMASK_SHIFT 0 # define R300_TX_WIDTHMASK_MASK (2047 << 0) @@ -684,6 +697,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. /* END */ #define R300_TX_UNK4_0 0x4580 #define R300_TX_UNK5_0 0x45C0 +#define R300_TX_BORDER_COLOR_0 0x45F0 //ff00ff00 == { 0, 1.0, 0, 1.0 } + /* END */ /* BEGIN: Fragment program instruction set diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 56dad7c0cfc..652418af6ab 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -983,6 +983,7 @@ void r300_setup_textures(GLcontext *ctx) R300_STATECHANGE(r300, tex.offset); R300_STATECHANGE(r300, tex.unknown4); R300_STATECHANGE(r300, tex.unknown5); + R300_STATECHANGE(r300, tex.border_color); r300->state.texture.tc_count=0; @@ -1011,10 +1012,12 @@ void r300_setup_textures(GLcontext *ctx) max_texture_unit=i; r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter; + /* Turn off rest of the bits that are wrong. Im going to get rid of this soon, dont worry :) */ + t->filter &= R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK + |R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | + R300_TX_WRAP_Q_MASK | R300_TX_MAX_ANISO_MASK; - /* Turn off rest of the bits that are wrong */ - t->filter &= R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK; + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter; /* No idea why linear filtered textures shake when puting random data */ /*r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=(rand()%0xffffffff) & (~0x1fff);*/ @@ -1023,6 +1026,7 @@ void r300_setup_textures(GLcontext *ctx) r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset; r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0; r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0; + r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color; /* We don't know how to set this yet */ //value from r300_lib.c for RGB24 @@ -1096,6 +1100,7 @@ void r300_setup_textures(GLcontext *ctx) ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1; + ((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit); diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 33a8fa1e5ca..884d42cf472 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -60,46 +60,42 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * \param swrap Wrap mode for the \a s texture coordinate * \param twrap Wrap mode for the \a t texture coordinate */ - + static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap) { GLboolean is_clamp = GL_FALSE; - GLboolean is_clamp_to_border = GL_FALSE; - -/* Most of these seem to be incorrect so disable for now */ -#if 0 + unsigned long hw_swrap=0, hw_twrap=0, hw_qwrap=0; + t->filter &= - ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D); - + ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_Q_MASK); + switch (swrap) { case GL_REPEAT: - t->filter |= R200_CLAMP_S_WRAP; + hw_swrap |= R300_TX_REPEAT; break; case GL_CLAMP: - t->filter |= R200_CLAMP_S_CLAMP_GL; + hw_swrap |= R300_TX_CLAMP; is_clamp = GL_TRUE; break; case GL_CLAMP_TO_EDGE: - t->filter |= R200_CLAMP_S_CLAMP_LAST; + hw_swrap |= R300_TX_CLAMP_TO_EDGE; break; case GL_CLAMP_TO_BORDER: - t->filter |= R200_CLAMP_S_CLAMP_GL; - is_clamp_to_border = GL_TRUE; + hw_swrap |= R300_TX_CLAMP_TO_BORDER; break; case GL_MIRRORED_REPEAT: - t->filter |= R200_CLAMP_S_MIRROR; + hw_swrap |= R300_TX_REPEAT | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_EXT: - t->filter |= R200_CLAMP_S_MIRROR_CLAMP_GL; + hw_swrap |= R300_TX_CLAMP | R300_TX_MIRRORED; is_clamp = GL_TRUE; break; case GL_MIRROR_CLAMP_TO_EDGE_EXT: - t->filter |= R200_CLAMP_S_MIRROR_CLAMP_LAST; + hw_swrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_TO_BORDER_EXT: - t->filter |= R200_CLAMP_S_MIRROR_CLAMP_GL; - is_clamp_to_border = GL_TRUE; + hw_swrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED; break; default: _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); @@ -107,76 +103,72 @@ static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap, switch (twrap) { case GL_REPEAT: - t->filter |= R200_CLAMP_T_WRAP; + hw_twrap |= R300_TX_REPEAT; break; case GL_CLAMP: - t->filter |= R200_CLAMP_T_CLAMP_GL; + hw_twrap |= R300_TX_CLAMP; is_clamp = GL_TRUE; break; case GL_CLAMP_TO_EDGE: - t->filter |= R200_CLAMP_T_CLAMP_LAST; + hw_twrap |= R300_TX_CLAMP_TO_EDGE; break; case GL_CLAMP_TO_BORDER: - t->filter |= R200_CLAMP_T_CLAMP_GL | R200_BORDER_MODE_D3D; - is_clamp_to_border = GL_TRUE; + hw_twrap |= R300_TX_CLAMP_TO_BORDER; break; case GL_MIRRORED_REPEAT: - t->filter |= R200_CLAMP_T_MIRROR; + hw_twrap |= R300_TX_REPEAT | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_EXT: - t->filter |= R200_CLAMP_T_MIRROR_CLAMP_GL; + hw_twrap |= R300_TX_CLAMP | R300_TX_MIRRORED; is_clamp = GL_TRUE; break; case GL_MIRROR_CLAMP_TO_EDGE_EXT: - t->filter |= R200_CLAMP_T_MIRROR_CLAMP_LAST; + hw_twrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_TO_BORDER_EXT: - t->filter |= R200_CLAMP_T_MIRROR_CLAMP_GL; - is_clamp_to_border = GL_TRUE; + hw_twrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED; break; default: _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__); } - t->format_x &= ~R200_CLAMP_Q_MASK; - switch (rwrap) { case GL_REPEAT: - t->format_x |= R200_CLAMP_Q_WRAP; + hw_qwrap |= R300_TX_REPEAT; break; case GL_CLAMP: - t->format_x |= R200_CLAMP_Q_CLAMP_GL; + hw_qwrap |= R300_TX_CLAMP; is_clamp = GL_TRUE; break; case GL_CLAMP_TO_EDGE: - t->format_x |= R200_CLAMP_Q_CLAMP_LAST; + hw_qwrap |= R300_TX_CLAMP_TO_EDGE; break; case GL_CLAMP_TO_BORDER: - t->format_x |= R200_CLAMP_Q_CLAMP_GL; - is_clamp_to_border = GL_TRUE; + hw_qwrap |= R300_TX_CLAMP_TO_BORDER; break; case GL_MIRRORED_REPEAT: - t->format_x |= R200_CLAMP_Q_MIRROR; + hw_qwrap |= R300_TX_REPEAT | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_EXT: - t->format_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL; + hw_qwrap |= R300_TX_CLAMP | R300_TX_MIRRORED; is_clamp = GL_TRUE; break; case GL_MIRROR_CLAMP_TO_EDGE_EXT: - t->format_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST; + hw_qwrap |= R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; break; case GL_MIRROR_CLAMP_TO_BORDER_EXT: - t->format_x |= R200_CLAMP_Q_MIRROR_CLAMP_GL; - is_clamp_to_border = GL_TRUE; + hw_qwrap |= R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED; break; default: _mesa_problem(NULL, "bad R wrap mode in %s", __FUNCTION__); } - if (is_clamp_to_border) { - t->filter |= R200_BORDER_MODE_D3D; - } - + t->filter |= hw_swrap << R300_TX_WRAP_S_SHIFT; + t->filter |= hw_twrap << R300_TX_WRAP_T_SHIFT; + t->filter |= hw_qwrap << R300_TX_WRAP_Q_SHIFT; + +#if 0 + t->format_x &= ~R200_CLAMP_Q_MASK; t->border_fallback = (is_clamp && is_clamp_to_border); #endif } @@ -184,22 +176,19 @@ static void r300SetTexWrap(r300TexObjPtr t, GLenum swrap, GLenum twrap, static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max) { -/* Needs testing */ -#if 0 - t->filter &= ~R200_MAX_ANISO_MASK; + t->filter &= ~R300_TX_MAX_ANISO_MASK; if (max == 1.0) { - t->filter |= R200_MAX_ANISO_1_TO_1; + t->filter |= R300_TX_MAX_ANISO_1_TO_1; } else if (max <= 2.0) { - t->filter |= R200_MAX_ANISO_2_TO_1; + t->filter |= R300_TX_MAX_ANISO_2_TO_1; } else if (max <= 4.0) { - t->filter |= R200_MAX_ANISO_4_TO_1; + t->filter |= R300_TX_MAX_ANISO_4_TO_1; } else if (max <= 8.0) { - t->filter |= R200_MAX_ANISO_8_TO_1; + t->filter |= R300_TX_MAX_ANISO_8_TO_1; } else { - t->filter |= R200_MAX_ANISO_16_TO_1; + t->filter |= R300_TX_MAX_ANISO_16_TO_1; } -#endif } /** @@ -212,14 +201,14 @@ static void r300SetTexMaxAnisotropy(r300TexObjPtr t, GLfloat max) static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf) { - GLuint anisotropy = 0; //(t->filter & R200_MAX_ANISO_MASK); + GLuint anisotropy = (t->filter & R300_TX_MAX_ANISO_MASK); t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK); #if 0 //t->format_x &= ~R200_VOLUME_FILTER_MASK; #endif - if (anisotropy == R200_MAX_ANISO_1_TO_1) { + if (anisotropy == R300_TX_MAX_ANISO_1_TO_1) { switch (minf) { case GL_NEAREST: t->filter |= R300_TX_MIN_FILTER_NEAREST; @@ -836,7 +825,7 @@ static void r300TexEnv(GLcontext * ctx, GLenum target, GLfloat bias, min; GLuint b; - /* The R200's LOD bias is a signed 2's complement value with a + /* The R300's LOD bias is a signed 2's complement value with a * range of -16.0 <= bias < 16.0. * * NOTE: Add a small bias to the bias for conform mipsel.c test. @@ -847,13 +836,9 @@ static void r300TexEnv(GLcontext * ctx, GLenum target, "no_neg_lod_bias") ? 0.0 : -16.0; bias = CLAMP(bias, min, 16.0); -#define R300_LOD_BIAS_MASK 0x1fff - - /* 1.0 is 0x00000100 and 10.0 is 0x00000a00 --aet */ - + /* 0.0 - 16.0 == 0x0 - 0x1000 */ + /* 0.0 - -16.0 == 0x1001 - 0x1fff */ b = 0x1000 / 16.0 * bias; - /* No clue about negative biases but this would - seem logical if positive max is 0x1000 */ b &= R300_LOD_BIAS_MASK; if(b != (rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] & R300_LOD_BIAS_MASK)){