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 :)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) */
|
||||
};
|
||||
|
||||
@@ -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_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_MIN_FILTER_MASK (0x0000f800)
|
||||
#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
|
||||
|
||||
@@ -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<<i);
|
||||
|
||||
r300->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);
|
||||
|
||||
@@ -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)){
|
||||
|
||||
Reference in New Issue
Block a user