diff options
author | Roland Scheidegger <sroland@vmware.com> | 2009-03-12 15:01:16 +0100 |
---|---|---|
committer | Roland Scheidegger <sroland@vmware.com> | 2009-03-12 15:01:16 +0100 |
commit | 114152e068ec919feb0a57a1259c2ada970b9f02 (patch) | |
tree | f424d1c9f88ddf36c94991906879f3a71ca1c36a | |
parent | b7d841b59e9087c0ba8c2726897ab1506375e4e6 (diff) |
mesa: add support for ATI_envmap_bumpmap
add new entrypoints, new texture format, etc
translate in texenvprogram.c for drivers using the mesa-generated tex env
fragment program
also handled in swrast, but not tested (cannot work due to negative texel
results not handled correctly)
-rw-r--r-- | src/mesa/glapi/gl_API.xml | 50 | ||||
-rw-r--r-- | src/mesa/main/api_exec.c | 6 | ||||
-rw-r--r-- | src/mesa/main/config.h | 3 | ||||
-rw-r--r-- | src/mesa/main/context.c | 3 | ||||
-rw-r--r-- | src/mesa/main/dlist.c | 46 | ||||
-rw-r--r-- | src/mesa/main/extensions.c | 2 | ||||
-rw-r--r-- | src/mesa/main/image.c | 153 | ||||
-rw-r--r-- | src/mesa/main/image.h | 7 | ||||
-rw-r--r-- | src/mesa/main/macros.h | 7 | ||||
-rw-r--r-- | src/mesa/main/mipmap.c | 14 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 5 | ||||
-rw-r--r-- | src/mesa/main/texenv.c | 174 | ||||
-rw-r--r-- | src/mesa/main/texenv.h | 11 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.c | 99 | ||||
-rw-r--r-- | src/mesa/main/texformat.c | 42 | ||||
-rw-r--r-- | src/mesa/main/texformat.h | 14 | ||||
-rw-r--r-- | src/mesa/main/texformat_tmp.h | 17 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 39 | ||||
-rw-r--r-- | src/mesa/main/texstate.c | 20 | ||||
-rw-r--r-- | src/mesa/main/texstore.c | 91 | ||||
-rw-r--r-- | src/mesa/main/texstore.h | 2 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.c | 28 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.h | 2 | ||||
-rw-r--r-- | src/mesa/swrast/s_texcombine.c | 95 |
24 files changed, 906 insertions, 24 deletions
diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 8212fc24770..cc3e3ae6bff 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml | |||
@@ -11681,6 +11681,56 @@ | |||
11681 | <enum name="DEPTH_STENCIL_TO_BGRA_NV" value="0x886F"/> | 11681 | <enum name="DEPTH_STENCIL_TO_BGRA_NV" value="0x886F"/> |
11682 | </category> | 11682 | </category> |
11683 | 11683 | ||
11684 | <category name="GL_ATI_envmap_bumpmap" number="244"> | ||
11685 | <enum name="BUMP_ROT_MATRIX_ATI" count="4" value="0x8775"> | ||
11686 | <size name="TexBumpParameterfv"/> | ||
11687 | <size name="TexBumpParameteriv"/> | ||
11688 | <size name="GetTexBumpParameterfv" mode="get"/> | ||
11689 | <size name="GetTexBumpParameteriv" mode="get"/> | ||
11690 | </enum> | ||
11691 | <enum name="BUMP_ROT_MATRIX_SIZE_ATI" count="1" value="0x8776"> | ||
11692 | <size name="GetTexBumpParameterfv" mode="get"/> | ||
11693 | <size name="GetTexBumpParameteriv" mode="get"/> | ||
11694 | </enum> | ||
11695 | <enum name="BUMP_NUM_TEX_UNITS_ATI" count="1" value="0x8777"> | ||
11696 | <size name="GetTexBumpParameterfv" mode="get"/> | ||
11697 | <size name="GetTexBumpParameteriv" mode="get"/> | ||
11698 | </enum> | ||
11699 | <enum name="BUMP_TEX_UNITS_ATI" count="-1" value="0x8778"> | ||
11700 | <size name="GetTexBumpParameterfv" mode="get"/> | ||
11701 | <size name="GetTexBumpParameteriv" mode="get"/> | ||
11702 | </enum> | ||
11703 | <enum name="DUDV_ATI" value="0x8779"/> | ||
11704 | <enum name="DU8DV8_ATI" value="0x877A"/> | ||
11705 | <enum name="BUMP_ENVMAP_ATI" value="0x877B"/> | ||
11706 | <enum name="BUMP_TARGET_ATI" count="1" value="0x877C"> | ||
11707 | <size name="TexEnviv"/> | ||
11708 | <size name="TexEnvfv"/> | ||
11709 | <size name="GetTexEnviv" mode="get"/> | ||
11710 | <size name="GetTexEnvfv" mode="get"/> | ||
11711 | </enum> | ||
11712 | <function name="TexBumpParameterfvATI" offset="assign"> | ||
11713 | <param name="pname" type="GLenum"/> | ||
11714 | <param name="param" type="const GLfloat *" variable_param="pname"/> | ||
11715 | <glx ignore="true"/> | ||
11716 | </function> | ||
11717 | <function name="TexBumpParameterivATI" offset="assign"> | ||
11718 | <param name="pname" type="GLenum"/> | ||
11719 | <param name="param" type="const GLint *" variable_param="pname"/> | ||
11720 | <glx ignore="true"/> | ||
11721 | </function> | ||
11722 | <function name="GetTexBumpParameterfvATI" offset="assign"> | ||
11723 | <param name="pname" type="GLenum"/> | ||
11724 | <param name="param" type="GLfloat *" variable_param="pname"/> | ||
11725 | <glx ignore="true"/> | ||
11726 | </function> | ||
11727 | <function name="GetTexBumpParameterivATI" offset="assign"> | ||
11728 | <param name="pname" type="GLenum"/> | ||
11729 | <param name="param" type="GLint *" variable_param="pname"/> | ||
11730 | <glx ignore="true"/> | ||
11731 | </function> | ||
11732 | </category> | ||
11733 | |||
11684 | <category name="GL_ATI_fragment_shader" number="245"> | 11734 | <category name="GL_ATI_fragment_shader" number="245"> |
11685 | <function name="GenFragmentShadersATI" offset="assign"> | 11735 | <function name="GenFragmentShadersATI" offset="assign"> |
11686 | <return type="GLuint"/> | 11736 | <return type="GLuint"/> |
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index e0715817add..6f66ff47a08 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c | |||
@@ -839,6 +839,12 @@ _mesa_init_exec_table(struct _glapi_table *exec) | |||
839 | SET_SetFragmentShaderConstantATI(exec, _mesa_SetFragmentShaderConstantATI); | 839 | SET_SetFragmentShaderConstantATI(exec, _mesa_SetFragmentShaderConstantATI); |
840 | #endif | 840 | #endif |
841 | 841 | ||
842 | /* GL_ATI_envmap_bumpmap */ | ||
843 | SET_GetTexBumpParameterivATI(exec, _mesa_GetTexBumpParameterivATI); | ||
844 | SET_GetTexBumpParameterfvATI(exec, _mesa_GetTexBumpParameterfvATI); | ||
845 | SET_TexBumpParameterivATI(exec, _mesa_TexBumpParameterivATI); | ||
846 | SET_TexBumpParameterfvATI(exec, _mesa_TexBumpParameterfvATI); | ||
847 | |||
842 | #if FEATURE_EXT_framebuffer_object | 848 | #if FEATURE_EXT_framebuffer_object |
843 | SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT); | 849 | SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT); |
844 | SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT); | 850 | SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT); |
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 282ad9514c2..fc31155b35b 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h | |||
@@ -232,7 +232,8 @@ | |||
232 | #define MAX_COLOR_ATTACHMENTS 8 | 232 | #define MAX_COLOR_ATTACHMENTS 8 |
233 | /*@}*/ | 233 | /*@}*/ |
234 | 234 | ||
235 | 235 | /** For GL_ATI_envmap_bump - support bump mapping on first 8 units */ | |
236 | #define SUPPORTED_ATI_BUMP_UNITS 0xff | ||
236 | 237 | ||
237 | /** | 238 | /** |
238 | * \name Mesa-specific parameters | 239 | * \name Mesa-specific parameters |
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 9fd9e769d29..84bf0205a8e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c | |||
@@ -589,6 +589,9 @@ _mesa_init_constants(GLcontext *ctx) | |||
589 | /* GL_ARB_framebuffer_object */ | 589 | /* GL_ARB_framebuffer_object */ |
590 | ctx->Const.MaxSamples = 0; | 590 | ctx->Const.MaxSamples = 0; |
591 | 591 | ||
592 | /* GL_ATI_envmap_bumpmap */ | ||
593 | ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS; | ||
594 | |||
592 | /* sanity checks */ | 595 | /* sanity checks */ |
593 | ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, | 596 | ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, |
594 | ctx->Const.MaxTextureCoordUnits)); | 597 | ctx->Const.MaxTextureCoordUnits)); |
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index d4bd56be83a..ebcef0268a4 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c | |||
@@ -320,6 +320,8 @@ typedef enum | |||
320 | /* GL_ARB_draw_buffers */ | 320 | /* GL_ARB_draw_buffers */ |
321 | OPCODE_DRAW_BUFFERS_ARB, | 321 | OPCODE_DRAW_BUFFERS_ARB, |
322 | /* GL_ATI_fragment_shader */ | 322 | /* GL_ATI_fragment_shader */ |
323 | OPCODE_TEX_BUMP_PARAMETER_ATI, | ||
324 | /* GL_ATI_fragment_shader */ | ||
323 | OPCODE_BIND_FRAGMENT_SHADER_ATI, | 325 | OPCODE_BIND_FRAGMENT_SHADER_ATI, |
324 | OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, | 326 | OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, |
325 | /* OpenGL 2.0 */ | 327 | /* OpenGL 2.0 */ |
@@ -4803,6 +4805,36 @@ save_DrawBuffersARB(GLsizei count, const GLenum * buffers) | |||
4803 | } | 4805 | } |
4804 | } | 4806 | } |
4805 | 4807 | ||
4808 | static void GLAPIENTRY | ||
4809 | save_TexBumpParameterfvATI(GLenum pname, const GLfloat *param) | ||
4810 | { | ||
4811 | GET_CURRENT_CONTEXT(ctx); | ||
4812 | Node *n; | ||
4813 | |||
4814 | n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_BUMP_PARAMETER_ATI, 5); | ||
4815 | if (n) { | ||
4816 | n[1].ui = pname; | ||
4817 | n[2].f = param[0]; | ||
4818 | n[3].f = param[1]; | ||
4819 | n[4].f = param[2]; | ||
4820 | n[5].f = param[3]; | ||
4821 | } | ||
4822 | if (ctx->ExecuteFlag) { | ||
4823 | CALL_TexBumpParameterfvATI(ctx->Exec, (pname, param)); | ||
4824 | } | ||
4825 | } | ||
4826 | |||
4827 | static void GLAPIENTRY | ||
4828 | save_TexBumpParameterivATI(GLenum pname, const GLint *param) | ||
4829 | { | ||
4830 | GLfloat p[4]; | ||
4831 | p[0] = INT_TO_FLOAT(param[0]); | ||
4832 | p[1] = INT_TO_FLOAT(param[1]); | ||
4833 | p[2] = INT_TO_FLOAT(param[2]); | ||
4834 | p[3] = INT_TO_FLOAT(param[3]); | ||
4835 | save_TexBumpParameterfvATI(pname, p); | ||
4836 | } | ||
4837 | |||
4806 | #if FEATURE_ATI_fragment_shader | 4838 | #if FEATURE_ATI_fragment_shader |
4807 | static void GLAPIENTRY | 4839 | static void GLAPIENTRY |
4808 | save_BindFragmentShaderATI(GLuint id) | 4840 | save_BindFragmentShaderATI(GLuint id) |
@@ -6505,6 +6537,16 @@ execute_list(GLcontext *ctx, GLuint list) | |||
6505 | n[9].i, n[10].e)); | 6537 | n[9].i, n[10].e)); |
6506 | break; | 6538 | break; |
6507 | #endif | 6539 | #endif |
6540 | case OPCODE_TEX_BUMP_PARAMETER_ATI: | ||
6541 | { | ||
6542 | GLfloat values[4]; | ||
6543 | GLuint i, pname = n[1].ui; | ||
6544 | |||
6545 | for (i = 0; i < 4; i++) | ||
6546 | values[i] = n[1 + i].f; | ||
6547 | CALL_TexBumpParameterfvATI(ctx->Exec, (pname, values)); | ||
6548 | } | ||
6549 | break; | ||
6508 | #if FEATURE_ATI_fragment_shader | 6550 | #if FEATURE_ATI_fragment_shader |
6509 | case OPCODE_BIND_FRAGMENT_SHADER_ATI: | 6551 | case OPCODE_BIND_FRAGMENT_SHADER_ATI: |
6510 | CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); | 6552 | CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); |
@@ -8043,6 +8085,10 @@ _mesa_init_dlist_table(struct _glapi_table *table) | |||
8043 | SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV); | 8085 | SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV); |
8044 | #endif | 8086 | #endif |
8045 | 8087 | ||
8088 | /* 244. GL_ATI_envmap_bumpmap */ | ||
8089 | SET_TexBumpParameterivATI(table, save_TexBumpParameterivATI); | ||
8090 | SET_TexBumpParameterfvATI(table, save_TexBumpParameterfvATI); | ||
8091 | |||
8046 | /* 245. GL_ATI_fragment_shader */ | 8092 | /* 245. GL_ATI_fragment_shader */ |
8047 | #if FEATURE_ATI_fragment_shader | 8093 | #if FEATURE_ATI_fragment_shader |
8048 | SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI); | 8094 | SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI); |
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index fbca924ad3d..2d2bf517843 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c | |||
@@ -137,6 +137,7 @@ static const struct { | |||
137 | { ON, "GL_APPLE_packed_pixels", F(APPLE_packed_pixels) }, | 137 | { ON, "GL_APPLE_packed_pixels", F(APPLE_packed_pixels) }, |
138 | { OFF, "GL_APPLE_vertex_array_object", F(APPLE_vertex_array_object) }, | 138 | { OFF, "GL_APPLE_vertex_array_object", F(APPLE_vertex_array_object) }, |
139 | { OFF, "GL_ATI_blend_equation_separate", F(EXT_blend_equation_separate) }, | 139 | { OFF, "GL_ATI_blend_equation_separate", F(EXT_blend_equation_separate) }, |
140 | { OFF, "GL_ATI_envmap_bumpmap", F(ATI_envmap_bumpmap) }, | ||
140 | { OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)}, | 141 | { OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)}, |
141 | { OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)}, | 142 | { OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)}, |
142 | { OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)}, | 143 | { OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)}, |
@@ -229,6 +230,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) | |||
229 | /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/ | 230 | /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/ |
230 | #endif | 231 | #endif |
231 | ctx->Extensions.APPLE_vertex_array_object = GL_TRUE; | 232 | ctx->Extensions.APPLE_vertex_array_object = GL_TRUE; |
233 | ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE; | ||
232 | #if FEATURE_ATI_fragment_shader | 234 | #if FEATURE_ATI_fragment_shader |
233 | ctx->Extensions.ATI_fragment_shader = GL_TRUE; | 235 | ctx->Extensions.ATI_fragment_shader = GL_TRUE; |
234 | #endif | 236 | #endif |
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 4d86c547775..ed0811660d2 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c | |||
@@ -293,6 +293,8 @@ _mesa_components_in_format( GLenum format ) | |||
293 | return 2; | 293 | return 2; |
294 | case GL_DEPTH_STENCIL_EXT: | 294 | case GL_DEPTH_STENCIL_EXT: |
295 | return 2; | 295 | return 2; |
296 | case GL_DUDV_ATI: | ||
297 | return 2; | ||
296 | default: | 298 | default: |
297 | return -1; | 299 | return -1; |
298 | } | 300 | } |
@@ -503,6 +505,20 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type ) | |||
503 | return GL_TRUE; | 505 | return GL_TRUE; |
504 | else | 506 | else |
505 | return GL_FALSE; | 507 | return GL_FALSE; |
508 | case GL_DUDV_ATI: | ||
509 | case GL_DU8DV8_ATI: | ||
510 | switch (type) { | ||
511 | case GL_BYTE: | ||
512 | case GL_UNSIGNED_BYTE: | ||
513 | case GL_SHORT: | ||
514 | case GL_UNSIGNED_SHORT: | ||
515 | case GL_INT: | ||
516 | case GL_UNSIGNED_INT: | ||
517 | case GL_FLOAT: | ||
518 | return GL_TRUE; | ||
519 | default: | ||
520 | return GL_FALSE; | ||
521 | } | ||
506 | default: | 522 | default: |
507 | ; /* fall-through */ | 523 | ; /* fall-through */ |
508 | } | 524 | } |
@@ -1674,8 +1690,19 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
1674 | GLfloat luminance[MAX_WIDTH]; | 1690 | GLfloat luminance[MAX_WIDTH]; |
1675 | const GLint comps = _mesa_components_in_format(dstFormat); | 1691 | const GLint comps = _mesa_components_in_format(dstFormat); |
1676 | GLuint i; | 1692 | GLuint i; |
1677 | 1693 | /* clamping only applies to colors, not the dudv values, but still need | |
1678 | if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) { | 1694 | it if converting to unsigned values (which doesn't make much sense) */ |
1695 | if (dstFormat == GL_DUDV_ATI || dstFormat == GL_DU8DV8_ATI) { | ||
1696 | switch (dstType) { | ||
1697 | case GL_UNSIGNED_BYTE: | ||
1698 | case GL_UNSIGNED_SHORT: | ||
1699 | case GL_UNSIGNED_INT: | ||
1700 | transferOps |= IMAGE_CLAMP_BIT; | ||
1701 | break; | ||
1702 | /* actually might want clamp to [-1,1] otherwise but shouldn't matter? */ | ||
1703 | } | ||
1704 | } | ||
1705 | else if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) { | ||
1679 | /* need to clamp to [0, 1] */ | 1706 | /* need to clamp to [0, 1] */ |
1680 | transferOps |= IMAGE_CLAMP_BIT; | 1707 | transferOps |= IMAGE_CLAMP_BIT; |
1681 | } | 1708 | } |
@@ -1774,6 +1801,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
1774 | dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); | 1801 | dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); |
1775 | } | 1802 | } |
1776 | break; | 1803 | break; |
1804 | case GL_DUDV_ATI: | ||
1805 | case GL_DU8DV8_ATI: | ||
1806 | for (i=0;i<n;i++) { | ||
1807 | dst[i*2+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); | ||
1808 | dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); | ||
1809 | } | ||
1810 | break; | ||
1777 | default: | 1811 | default: |
1778 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 1812 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
1779 | } | 1813 | } |
@@ -1847,6 +1881,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
1847 | dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]); | 1881 | dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]); |
1848 | } | 1882 | } |
1849 | break; | 1883 | break; |
1884 | case GL_DUDV_ATI: | ||
1885 | case GL_DU8DV8_ATI: | ||
1886 | for (i=0;i<n;i++) { | ||
1887 | dst[i*2+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]); | ||
1888 | dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]); | ||
1889 | } | ||
1890 | break; | ||
1850 | default: | 1891 | default: |
1851 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 1892 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
1852 | } | 1893 | } |
@@ -1920,6 +1961,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
1920 | CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]); | 1961 | CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]); |
1921 | } | 1962 | } |
1922 | break; | 1963 | break; |
1964 | case GL_DUDV_ATI: | ||
1965 | case GL_DU8DV8_ATI: | ||
1966 | for (i=0;i<n;i++) { | ||
1967 | dst[i*2+0] = FLOAT_TO_USHORT(rgba[i][RCOMP]); | ||
1968 | dst[i*2+1] = FLOAT_TO_USHORT(rgba[i][GCOMP]); | ||
1969 | } | ||
1970 | break; | ||
1923 | default: | 1971 | default: |
1924 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 1972 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
1925 | } | 1973 | } |
@@ -1993,6 +2041,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
1993 | dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]); | 2041 | dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]); |
1994 | } | 2042 | } |
1995 | break; | 2043 | break; |
2044 | case GL_DUDV_ATI: | ||
2045 | case GL_DU8DV8_ATI: | ||
2046 | for (i=0;i<n;i++) { | ||
2047 | dst[i*2+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]); | ||
2048 | dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]); | ||
2049 | } | ||
2050 | break; | ||
1996 | default: | 2051 | default: |
1997 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 2052 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
1998 | } | 2053 | } |
@@ -2066,6 +2121,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
2066 | dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]); | 2121 | dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]); |
2067 | } | 2122 | } |
2068 | break; | 2123 | break; |
2124 | case GL_DUDV_ATI: | ||
2125 | case GL_DU8DV8_ATI: | ||
2126 | for (i=0;i<n;i++) { | ||
2127 | dst[i*2+0] = FLOAT_TO_UINT(rgba[i][RCOMP]); | ||
2128 | dst[i*2+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); | ||
2129 | } | ||
2130 | break; | ||
2069 | default: | 2131 | default: |
2070 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 2132 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
2071 | } | 2133 | } |
@@ -2139,6 +2201,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
2139 | dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]); | 2201 | dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]); |
2140 | } | 2202 | } |
2141 | break; | 2203 | break; |
2204 | case GL_DUDV_ATI: | ||
2205 | case GL_DU8DV8_ATI: | ||
2206 | for (i=0;i<n;i++) { | ||
2207 | dst[i*2+0] = FLOAT_TO_INT(rgba[i][RCOMP]); | ||
2208 | dst[i*2+1] = FLOAT_TO_INT(rgba[i][GCOMP]); | ||
2209 | } | ||
2210 | break; | ||
2142 | default: | 2211 | default: |
2143 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 2212 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
2144 | } | 2213 | } |
@@ -2212,6 +2281,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
2212 | dst[i*4+3] = rgba[i][RCOMP]; | 2281 | dst[i*4+3] = rgba[i][RCOMP]; |
2213 | } | 2282 | } |
2214 | break; | 2283 | break; |
2284 | case GL_DUDV_ATI: | ||
2285 | case GL_DU8DV8_ATI: | ||
2286 | for (i=0;i<n;i++) { | ||
2287 | dst[i*2+0] = rgba[i][RCOMP]; | ||
2288 | dst[i*2+1] = rgba[i][GCOMP]; | ||
2289 | } | ||
2290 | break; | ||
2215 | default: | 2291 | default: |
2216 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 2292 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
2217 | } | 2293 | } |
@@ -2285,6 +2361,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], | |||
2285 | dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]); | 2361 | dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]); |
2286 | } | 2362 | } |
2287 | break; | 2363 | break; |
2364 | case GL_DUDV_ATI: | ||
2365 | case GL_DU8DV8_ATI: | ||
2366 | for (i=0;i<n;i++) { | ||
2367 | dst[i*2+0] = _mesa_float_to_half(rgba[i][RCOMP]); | ||
2368 | dst[i*2+1] = _mesa_float_to_half(rgba[i][GCOMP]); | ||
2369 | } | ||
2370 | break; | ||
2288 | default: | 2371 | default: |
2289 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); | 2372 | _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); |
2290 | } | 2373 | } |
@@ -2834,7 +2917,8 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], | |||
2834 | srcFormat == GL_BGR || | 2917 | srcFormat == GL_BGR || |
2835 | srcFormat == GL_RGBA || | 2918 | srcFormat == GL_RGBA || |
2836 | srcFormat == GL_BGRA || | 2919 | srcFormat == GL_BGRA || |
2837 | srcFormat == GL_ABGR_EXT); | 2920 | srcFormat == GL_ABGR_EXT || |
2921 | srcFormat == GL_DUDV_ATI); | ||
2838 | 2922 | ||
2839 | ASSERT(srcType == GL_UNSIGNED_BYTE || | 2923 | ASSERT(srcType == GL_UNSIGNED_BYTE || |
2840 | srcType == GL_BYTE || | 2924 | srcType == GL_BYTE || |
@@ -2949,6 +3033,13 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], | |||
2949 | aComp = 0; | 3033 | aComp = 0; |
2950 | stride = 4; | 3034 | stride = 4; |
2951 | break; | 3035 | break; |
3036 | case GL_DUDV_ATI: | ||
3037 | redIndex = 0; | ||
3038 | greenIndex = 1; | ||
3039 | blueIndex = -1; | ||
3040 | alphaIndex = -1; | ||
3041 | stride = 2; | ||
3042 | break; | ||
2952 | default: | 3043 | default: |
2953 | _mesa_problem(NULL, "bad srcFormat in extract float data"); | 3044 | _mesa_problem(NULL, "bad srcFormat in extract float data"); |
2954 | return; | 3045 | return; |
@@ -3877,6 +3968,62 @@ _mesa_unpack_color_span_float( GLcontext *ctx, | |||
3877 | } | 3968 | } |
3878 | } | 3969 | } |
3879 | 3970 | ||
3971 | /** | ||
3972 | * Similar to _mesa_unpack_color_span_float(), but for dudv data instead of rgba, | ||
3973 | * directly return GLbyte data, no transfer ops apply. | ||
3974 | */ | ||
3975 | void | ||
3976 | _mesa_unpack_dudv_span_byte( GLcontext *ctx, | ||
3977 | GLuint n, GLenum dstFormat, GLbyte dest[], | ||
3978 | GLenum srcFormat, GLenum srcType, | ||
3979 | const GLvoid *source, | ||
3980 | const struct gl_pixelstore_attrib *srcPacking, | ||
3981 | GLbitfield transferOps ) | ||
3982 | { | ||
3983 | ASSERT(dstFormat == GL_DUDV_ATI); | ||
3984 | ASSERT(srcFormat == GL_DUDV_ATI); | ||
3985 | |||
3986 | ASSERT(srcType == GL_UNSIGNED_BYTE || | ||
3987 | srcType == GL_BYTE || | ||
3988 | srcType == GL_UNSIGNED_SHORT || | ||
3989 | srcType == GL_SHORT || | ||
3990 | srcType == GL_UNSIGNED_INT || | ||
3991 | srcType == GL_INT || | ||
3992 | srcType == GL_HALF_FLOAT_ARB || | ||
3993 | srcType == GL_FLOAT); | ||
3994 | |||
3995 | /* general solution */ | ||
3996 | { | ||
3997 | GLint dstComponents; | ||
3998 | GLfloat rgba[MAX_WIDTH][4]; | ||
3999 | |||
4000 | dstComponents = _mesa_components_in_format( dstFormat ); | ||
4001 | /* source & dest image formats should have been error checked by now */ | ||
4002 | assert(dstComponents > 0); | ||
4003 | |||
4004 | /* | ||
4005 | * Extract image data and convert to RGBA floats | ||
4006 | */ | ||
4007 | assert(n <= MAX_WIDTH); | ||
4008 | extract_float_rgba(n, rgba, srcFormat, srcType, source, | ||
4009 | srcPacking->SwapBytes); | ||
4010 | |||
4011 | |||
4012 | /* Now determine which color channels we need to produce. | ||
4013 | * And determine the dest index (offset) within each color tuple. | ||
4014 | */ | ||
4015 | |||
4016 | /* Now pack results in the requested dstFormat */ | ||
4017 | GLbyte *dst = dest; | ||
4018 | GLuint i; | ||
4019 | for (i = 0; i < n; i++) { | ||
4020 | /* not sure - need clamp[-1,1] here? */ | ||
4021 | dst[0] = FLOAT_TO_BYTE(rgba[i][RCOMP]); | ||
4022 | dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]); | ||
4023 | dst += dstComponents; | ||
4024 | } | ||
4025 | } | ||
4026 | } | ||
3880 | 4027 | ||
3881 | /* | 4028 | /* |
3882 | * Unpack a row of color index data from a client buffer according to | 4029 | * Unpack a row of color index data from a client buffer according to |
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h index 0e0bbd96d85..b26c27e5a8a 100644 --- a/src/mesa/main/image.h +++ b/src/mesa/main/image.h | |||
@@ -198,6 +198,13 @@ _mesa_unpack_color_span_float( GLcontext *ctx, | |||
198 | const struct gl_pixelstore_attrib *srcPacking, | 198 | const struct gl_pixelstore_attrib *srcPacking, |
199 | GLbitfield transferOps ); | 199 | GLbitfield transferOps ); |
200 | 200 | ||
201 | extern void | ||
202 | _mesa_unpack_dudv_span_byte( GLcontext *ctx, | ||
203 | GLuint n, GLenum dstFormat, GLbyte dest[], | ||
204 | GLenum srcFormat, GLenum srcType, | ||
205 | const GLvoid *source, | ||
206 | const struct gl_pixelstore_attrib *srcPacking, | ||
207 | GLbitfield transferOps ); | ||
201 | 208 | ||
202 | extern void | 209 | extern void |
203 | _mesa_unpack_index_span( const GLcontext *ctx, GLuint n, | 210 | _mesa_unpack_index_span( const GLcontext *ctx, GLuint n, |
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index 2630855a0ea..bfd740870ec 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h | |||
@@ -54,13 +54,16 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; | |||
54 | #define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 ) | 54 | #define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 ) |
55 | 55 | ||
56 | 56 | ||
57 | /** Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */ | 57 | /** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */ |
58 | #define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) | 58 | #define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) |
59 | 59 | ||
60 | /** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */ | ||
61 | #define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0)) | ||
62 | |||
60 | /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ | 63 | /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ |
61 | #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) | 64 | #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) |
62 | 65 | ||
63 | /** Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */ | 66 | /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */ |
64 | #define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) | 67 | #define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) |
65 | 68 | ||
66 | 69 | ||
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 3dd4b3391b9..af2bf8fe228 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c | |||
@@ -85,7 +85,7 @@ bytes_per_pixel(GLenum datatype, GLuint comps) | |||
85 | rowC[j][e], rowC[k][e], \ | 85 | rowC[j][e], rowC[k][e], \ |
86 | rowD[j][e], rowD[k][e]); \ | 86 | rowD[j][e], rowD[k][e]); \ |
87 | } while(0) | 87 | } while(0) |
88 | 88 | ||
89 | #define FILTER_F_3D(e) \ | 89 | #define FILTER_F_3D(e) \ |
90 | do { \ | 90 | do { \ |
91 | dst[i][e] = (rowA[j][e] + rowA[k][e] \ | 91 | dst[i][e] = (rowA[j][e] + rowA[k][e] \ |
@@ -226,7 +226,6 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, | |||
226 | dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; | 226 | dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; |
227 | } | 227 | } |
228 | } | 228 | } |
229 | |||
230 | else if (datatype == GL_FLOAT && comps == 4) { | 229 | else if (datatype == GL_FLOAT && comps == 4) { |
231 | GLuint i, j, k; | 230 | GLuint i, j, k; |
232 | const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA; | 231 | const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA; |
@@ -471,6 +470,17 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, | |||
471 | dst[i] = (blue << 5) | (green << 2) | red; | 470 | dst[i] = (blue << 5) | (green << 2) | red; |
472 | } | 471 | } |
473 | } | 472 | } |
473 | else if (datatype == GL_BYTE && comps == 2) { | ||
474 | GLuint i, j, k; | ||
475 | const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA; | ||
476 | const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB; | ||
477 | GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow; | ||
478 | for (i = j = 0, k = k0; i < (GLuint) dstWidth; | ||
479 | i++, j += colStride, k += colStride) { | ||
480 | dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; | ||
481 | dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; | ||
482 | } | ||
483 | } | ||
474 | else { | 484 | else { |
475 | _mesa_problem(NULL, "bad format in do_row()"); | 485 | _mesa_problem(NULL, "bad format in do_row()"); |
476 | } | 486 | } |
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 9080c83da4e..169f1af057d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h | |||
@@ -1390,6 +1390,8 @@ struct gl_texture_unit | |||
1390 | GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */ | 1390 | GLbitfield _GenFlags; /**< Bitwise-OR of Gen[STRQ]._ModeBit */ |
1391 | 1391 | ||
1392 | GLfloat LodBias; /**< for biasing mipmap levels */ | 1392 | GLfloat LodBias; /**< for biasing mipmap levels */ |
1393 | GLenum BumpTarget; | ||
1394 | GLfloat RotMatrix[4]; /* 2x2 matrix */ | ||
1393 | 1395 | ||
1394 | /** | 1396 | /** |
1395 | * \name GL_EXT_texture_env_combine | 1397 | * \name GL_EXT_texture_env_combine |
@@ -2388,6 +2390,8 @@ struct gl_constants | |||
2388 | GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ | 2390 | GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ |
2389 | 2391 | ||
2390 | GLuint MaxVarying; /**< Number of float[4] varying parameters */ | 2392 | GLuint MaxVarying; /**< Number of float[4] varying parameters */ |
2393 | |||
2394 | GLbitfield SupportedBumpUnits; /**> units supporting GL_ATI_envmap_bumpmap as targets */ | ||
2391 | }; | 2395 | }; |
2392 | 2396 | ||
2393 | 2397 | ||
@@ -2484,6 +2488,7 @@ struct gl_extensions | |||
2484 | GLboolean APPLE_client_storage; | 2488 | GLboolean APPLE_client_storage; |
2485 | GLboolean APPLE_packed_pixels; | 2489 | GLboolean APPLE_packed_pixels; |
2486 | GLboolean APPLE_vertex_array_object; | 2490 | GLboolean APPLE_vertex_array_object; |
2491 | GLboolean ATI_envmap_bumpmap; | ||
2487 | GLboolean ATI_texture_mirror_once; | 2492 | GLboolean ATI_texture_mirror_once; |
2488 | GLboolean ATI_texture_env_combine3; | 2493 | GLboolean ATI_texture_env_combine3; |
2489 | GLboolean ATI_fragment_shader; | 2494 | GLboolean ATI_fragment_shader; |
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c index 95547a500ee..c2960fc8208 100644 --- a/src/mesa/main/texenv.c +++ b/src/mesa/main/texenv.c | |||
@@ -142,7 +142,11 @@ set_combiner_mode(GLcontext *ctx, | |||
142 | case GL_MODULATE_ADD_ATI: | 142 | case GL_MODULATE_ADD_ATI: |
143 | case GL_MODULATE_SIGNED_ADD_ATI: | 143 | case GL_MODULATE_SIGNED_ADD_ATI: |
144 | case GL_MODULATE_SUBTRACT_ATI: | 144 | case GL_MODULATE_SUBTRACT_ATI: |
145 | legal =ctx->Extensions.ATI_texture_env_combine3; | 145 | legal = ctx->Extensions.ATI_texture_env_combine3; |
146 | break; | ||
147 | case GL_BUMP_ENVMAP_ATI: | ||
148 | legal = (ctx->Extensions.ATI_envmap_bumpmap && | ||
149 | pname == GL_COMBINE_RGB); | ||
146 | break; | 150 | break; |
147 | default: | 151 | default: |
148 | legal = GL_FALSE; | 152 | legal = GL_FALSE; |
@@ -500,6 +504,26 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) | |||
500 | case GL_ALPHA_SCALE: | 504 | case GL_ALPHA_SCALE: |
501 | set_combiner_scale(ctx, texUnit, pname, param[0]); | 505 | set_combiner_scale(ctx, texUnit, pname, param[0]); |
502 | break; | 506 | break; |
507 | case GL_BUMP_TARGET_ATI: | ||
508 | if (!ctx->Extensions.ATI_envmap_bumpmap) { | ||
509 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname ); | ||
510 | return; | ||
511 | } | ||
512 | if (((GLenum) (GLint) param[0] < GL_TEXTURE0) || | ||
513 | ((GLenum) (GLint) param[0] > GL_TEXTURE31)) { | ||
514 | /* spec doesn't say this but it seems logical */ | ||
515 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]); | ||
516 | return; | ||
517 | } | ||
518 | if (!((1 << ((GLenum) (GLint) param[0] - GL_TEXTURE0)) & ctx->Const.SupportedBumpUnits)) { | ||
519 | _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", (GLenum) (GLint) param[0]); | ||
520 | return; | ||
521 | } | ||
522 | else { | ||
523 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); | ||
524 | texUnit->BumpTarget = (GLenum) (GLint) param[0]; | ||
525 | } | ||
526 | break; | ||
503 | default: | 527 | default: |
504 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); | 528 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); |
505 | return; | 529 | return; |
@@ -735,6 +759,16 @@ get_texenvi(GLcontext *ctx, const struct gl_texture_unit *texUnit, | |||
735 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); | 759 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); |
736 | } | 760 | } |
737 | break; | 761 | break; |
762 | case GL_BUMP_TARGET_ATI: | ||
763 | /* spec doesn't say so, but I think this should be queryable */ | ||
764 | if (ctx->Extensions.ATI_envmap_bumpmap) { | ||
765 | return texUnit->BumpTarget; | ||
766 | } | ||
767 | else { | ||
768 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); | ||
769 | } | ||
770 | break; | ||
771 | |||
738 | default: | 772 | default: |
739 | ; | 773 | ; |
740 | } | 774 | } |
@@ -874,4 +908,142 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) | |||
874 | } | 908 | } |
875 | } | 909 | } |
876 | 910 | ||
911 | /* why does ATI_envmap_bumpmap require new entrypoints? Should just | ||
912 | reuse TexEnv ones... */ | ||
913 | void GLAPIENTRY | ||
914 | _mesa_TexBumpParameterivATI( GLenum pname, const GLint *param ) | ||
915 | { | ||
916 | GLfloat p[4]; | ||
917 | if (pname == GL_BUMP_ROT_MATRIX_ATI) { | ||
918 | /* hope that conversion is correct here */ | ||
919 | p[0] = INT_TO_FLOAT( param[0] ); | ||
920 | p[1] = INT_TO_FLOAT( param[1] ); | ||
921 | p[2] = INT_TO_FLOAT( param[2] ); | ||
922 | p[3] = INT_TO_FLOAT( param[3] ); | ||
923 | } | ||
924 | else { | ||
925 | p[0] = (GLfloat) param[0]; | ||
926 | p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */ | ||
927 | } | ||
928 | _mesa_TexBumpParameterfvATI( pname, p ); | ||
929 | } | ||
930 | |||
931 | void GLAPIENTRY | ||
932 | _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param ) | ||
933 | { | ||
934 | struct gl_texture_unit *texUnit; | ||
935 | GET_CURRENT_CONTEXT(ctx); | ||
936 | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||
937 | |||
938 | /* should return error if extension not supported? */ | ||
939 | texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; | ||
940 | |||
941 | if (pname == GL_BUMP_ROT_MATRIX_ATI) { | ||
942 | if (TEST_EQ_4V(param, texUnit->RotMatrix)) | ||
943 | return; | ||
944 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); | ||
945 | COPY_4FV(texUnit->RotMatrix, param); | ||
946 | } | ||
947 | else { | ||
948 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexBumpParameter(pname)" ); | ||
949 | return; | ||
950 | } | ||
951 | /* Drivers might want to know about this, instead of dedicated function | ||
952 | just shove it into TexEnv where it really belongs anyway */ | ||
953 | if (ctx->Driver.TexEnv) { | ||
954 | (*ctx->Driver.TexEnv)( ctx, 0, pname, param ); | ||
955 | } | ||
956 | } | ||
957 | |||
958 | void GLAPIENTRY | ||
959 | _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param ) | ||
960 | { | ||
961 | const struct gl_texture_unit *texUnit; | ||
962 | GLint i; | ||
963 | GLint temp = 0; | ||
964 | GET_CURRENT_CONTEXT(ctx); | ||
965 | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||
966 | |||
967 | /* should return error if extension not supported? */ | ||
968 | texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; | ||
969 | |||
970 | if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) { | ||
971 | /* spec leaves open to support larger matrices. | ||
972 | Don't think anyone would ever want to use it | ||
973 | (and apps almost certainly would not understand it and | ||
974 | thus fail to submit matrices correctly) so hardcode this. */ | ||
975 | *param = 4; | ||
976 | } | ||
977 | else if (pname == GL_BUMP_ROT_MATRIX_ATI) { | ||
978 | /* hope that conversion is correct here */ | ||
979 | param[0] = FLOAT_TO_INT(texUnit->RotMatrix[0]); | ||
980 | param[1] = FLOAT_TO_INT(texUnit->RotMatrix[1]); | ||
981 | param[2] = FLOAT_TO_INT(texUnit->RotMatrix[2]); | ||
982 | param[3] = FLOAT_TO_INT(texUnit->RotMatrix[3]); | ||
983 | } | ||
984 | else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) { | ||
985 | for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { | ||
986 | if (ctx->Const.SupportedBumpUnits & (1 << i)) { | ||
987 | temp++; | ||
988 | } | ||
989 | } | ||
990 | *param = temp; | ||
991 | } | ||
992 | else if (pname == GL_BUMP_TEX_UNITS_ATI) { | ||
993 | for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { | ||
994 | if (ctx->Const.SupportedBumpUnits & (1 << i)) { | ||
995 | *param++ = i + GL_TEXTURE0; | ||
996 | } | ||
997 | } | ||
998 | } | ||
999 | else { | ||
1000 | _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexBumpParameter(pname)" ); | ||
1001 | return; | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | void GLAPIENTRY | ||
1006 | _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param ) | ||
1007 | { | ||
1008 | const struct gl_texture_unit *texUnit; | ||
1009 | GLint i; | ||
1010 | GLint temp = 0; | ||
1011 | GET_CURRENT_CONTEXT(ctx); | ||
1012 | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||
1013 | |||
1014 | /* should return error if extension not supported? */ | ||
1015 | texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; | ||
1016 | |||
1017 | if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) { | ||
1018 | /* spec leaves open to support larger matrices. | ||
1019 | Don't think anyone would ever want to use it | ||
1020 | (and apps might not understand it) so hardcode this. */ | ||
1021 | *param = (GLfloat) 4; | ||
1022 | } | ||
1023 | else if (pname == GL_BUMP_ROT_MATRIX_ATI) { | ||
1024 | param[0] = texUnit->RotMatrix[0]; | ||
1025 | param[1] = texUnit->RotMatrix[1]; | ||
1026 | param[2] = texUnit->RotMatrix[2]; | ||
1027 | param[3] = texUnit->RotMatrix[3]; | ||
1028 | } | ||
1029 | else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) { | ||
1030 | for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { | ||
1031 | if (ctx->Const.SupportedBumpUnits & (1 << i)) { | ||
1032 | temp++; | ||
1033 | } | ||
1034 | } | ||
1035 | *param = (GLfloat) temp; | ||
1036 | } | ||
1037 | else if (pname == GL_BUMP_TEX_UNITS_ATI) { | ||
1038 | for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { | ||
1039 | if (ctx->Const.SupportedBumpUnits & (1 << i)) { | ||
1040 | *param++ = (GLfloat) (i + GL_TEXTURE0); | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | else { | ||
1045 | _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexBumpParameter(pname)" ); | ||
1046 | return; | ||
1047 | } | ||
1048 | } | ||
877 | 1049 | ||
diff --git a/src/mesa/main/texenv.h b/src/mesa/main/texenv.h index bdff7fdb82b..1e9c5faed79 100644 --- a/src/mesa/main/texenv.h +++ b/src/mesa/main/texenv.h | |||
@@ -48,5 +48,16 @@ _mesa_TexEnvi( GLenum target, GLenum pname, GLint param ); | |||
48 | extern void GLAPIENTRY | 48 | extern void GLAPIENTRY |
49 | _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ); | 49 | _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ); |
50 | 50 | ||
51 | extern void GLAPIENTRY | ||
52 | _mesa_TexBumpParameterivATI( GLenum pname, const GLint *param ); | ||
53 | |||
54 | extern void GLAPIENTRY | ||
55 | _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param ); | ||
56 | |||
57 | extern void GLAPIENTRY | ||
58 | _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param ); | ||
59 | |||
60 | extern void GLAPIENTRY | ||
61 | _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param ); | ||
51 | 62 | ||
52 | #endif /* TEXENV_H */ | 63 | #endif /* TEXENV_H */ |
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 51c13a563d6..3fbd119b347 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c | |||
@@ -94,11 +94,11 @@ struct state_key { | |||
94 | GLuint ScaleShiftA:2; | 94 | GLuint ScaleShiftA:2; |
95 | 95 | ||
96 | GLuint NumArgsRGB:3; | 96 | GLuint NumArgsRGB:3; |
97 | GLuint ModeRGB:4; | 97 | GLuint ModeRGB:5; |
98 | struct mode_opt OptRGB[MAX_TERMS]; | 98 | struct mode_opt OptRGB[MAX_TERMS]; |
99 | 99 | ||
100 | GLuint NumArgsA:3; | 100 | GLuint NumArgsA:3; |
101 | GLuint ModeA:4; | 101 | GLuint ModeA:5; |
102 | struct mode_opt OptA[MAX_TERMS]; | 102 | struct mode_opt OptA[MAX_TERMS]; |
103 | } unit[8]; | 103 | } unit[8]; |
104 | }; | 104 | }; |
@@ -194,7 +194,8 @@ static GLuint translate_source( GLenum src ) | |||
194 | #define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */ | 194 | #define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */ |
195 | #define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */ | 195 | #define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */ |
196 | #define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */ | 196 | #define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */ |
197 | #define MODE_UNKNOWN 15 | 197 | #define MODE_BUMP_ENVMAP_ATI 15 /* special */ |
198 | #define MODE_UNKNOWN 16 | ||
198 | 199 | ||
199 | /** | 200 | /** |
200 | * Translate GL combiner state into a MODE_x value | 201 | * Translate GL combiner state into a MODE_x value |
@@ -223,6 +224,7 @@ static GLuint translate_mode( GLenum envMode, GLenum mode ) | |||
223 | case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; | 224 | case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; |
224 | case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; | 225 | case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; |
225 | case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; | 226 | case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; |
227 | case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI; | ||
226 | default: | 228 | default: |
227 | assert(0); | 229 | assert(0); |
228 | return MODE_UNKNOWN; | 230 | return MODE_UNKNOWN; |
@@ -383,7 +385,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) | |||
383 | translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeRGB); | 385 | translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeRGB); |
384 | key->unit[i].ModeA = | 386 | key->unit[i].ModeA = |
385 | translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeA); | 387 | translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeA); |
386 | 388 | ||
387 | key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB; | 389 | key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB; |
388 | key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA; | 390 | key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA; |
389 | 391 | ||
@@ -397,8 +399,18 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) | |||
397 | key->unit[i].OptA[j].Source = | 399 | key->unit[i].OptA[j].Source = |
398 | translate_source(texUnit->_CurrentCombine->SourceA[j]); | 400 | translate_source(texUnit->_CurrentCombine->SourceA[j]); |
399 | } | 401 | } |
402 | |||
403 | if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) { | ||
404 | /* requires some special translation */ | ||
405 | key->unit[i].NumArgsRGB = 2; | ||
406 | key->unit[i].ScaleShiftRGB = 0; | ||
407 | key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR; | ||
408 | key->unit[i].OptRGB[0].Source = SRC_TEXTURE; | ||
409 | key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; | ||
410 | key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; | ||
411 | } | ||
400 | } | 412 | } |
401 | 413 | ||
402 | if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { | 414 | if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { |
403 | key->separate_specular = 1; | 415 | key->separate_specular = 1; |
404 | inputs_referenced |= FRAG_BIT_COL1; | 416 | inputs_referenced |= FRAG_BIT_COL1; |
@@ -464,6 +476,11 @@ struct texenv_fragment_program { | |||
464 | * else undef. | 476 | * else undef. |
465 | */ | 477 | */ |
466 | 478 | ||
479 | struct ureg texcoord_tex[MAX_TEXTURE_COORD_UNITS]; | ||
480 | /* Reg containing texcoord for a texture unit, | ||
481 | * needed for bump mapping, else undef. | ||
482 | */ | ||
483 | |||
467 | struct ureg src_previous; /**< Reg containing color from previous | 484 | struct ureg src_previous; /**< Reg containing color from previous |
468 | * stage. May need to be decl'd. | 485 | * stage. May need to be decl'd. |
469 | */ | 486 | */ |
@@ -756,6 +773,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, | |||
756 | */ | 773 | */ |
757 | reserve_temp(p, dest); | 774 | reserve_temp(p, dest); |
758 | 775 | ||
776 | #if 0 | ||
759 | /* Is this a texture indirection? | 777 | /* Is this a texture indirection? |
760 | */ | 778 | */ |
761 | if ((coord.file == PROGRAM_TEMPORARY && | 779 | if ((coord.file == PROGRAM_TEMPORARY && |
@@ -767,6 +785,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, | |||
767 | p->alu_temps = 0; | 785 | p->alu_temps = 0; |
768 | assert(0); /* KW: texture env crossbar */ | 786 | assert(0); /* KW: texture env crossbar */ |
769 | } | 787 | } |
788 | #endif | ||
770 | 789 | ||
771 | return dest; | 790 | return dest; |
772 | } | 791 | } |
@@ -1052,6 +1071,10 @@ static struct ureg emit_combine( struct texenv_fragment_program *p, | |||
1052 | emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); | 1071 | emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); |
1053 | } | 1072 | } |
1054 | return dest; | 1073 | return dest; |
1074 | case MODE_BUMP_ENVMAP_ATI: | ||
1075 | /* special - not handled here */ | ||
1076 | assert(0); | ||
1077 | return src[0]; | ||
1055 | default: | 1078 | default: |
1056 | assert(0); | 1079 | assert(0); |
1057 | return src[0]; | 1080 | return src[0]; |
@@ -1074,6 +1097,10 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) | |||
1074 | if (!key->unit[unit].enabled) { | 1097 | if (!key->unit[unit].enabled) { |
1075 | return get_source(p, SRC_PREVIOUS, 0); | 1098 | return get_source(p, SRC_PREVIOUS, 0); |
1076 | } | 1099 | } |
1100 | if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { | ||
1101 | /* this isn't really a env stage delivering a color and handled elsewhere */ | ||
1102 | return get_source(p, SRC_PREVIOUS, 0); | ||
1103 | } | ||
1077 | 1104 | ||
1078 | switch (key->unit[unit].ModeRGB) { | 1105 | switch (key->unit[unit].ModeRGB) { |
1079 | case MODE_DOT3_RGB_EXT: | 1106 | case MODE_DOT3_RGB_EXT: |
@@ -1163,9 +1190,17 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) | |||
1163 | { | 1190 | { |
1164 | if (is_undef(p->src_texture[unit])) { | 1191 | if (is_undef(p->src_texture[unit])) { |
1165 | GLuint texTarget = p->state->unit[unit].source_index; | 1192 | GLuint texTarget = p->state->unit[unit].source_index; |
1166 | struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); | 1193 | struct ureg texcoord; |
1167 | struct ureg tmp = get_tex_temp( p ); | 1194 | struct ureg tmp = get_tex_temp( p ); |
1168 | 1195 | ||
1196 | if (is_undef(p->texcoord_tex[unit])) { | ||
1197 | texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); | ||
1198 | } | ||
1199 | else { | ||
1200 | /* might want to reuse this reg for tex output actually */ | ||
1201 | texcoord = p->texcoord_tex[unit]; | ||
1202 | } | ||
1203 | |||
1169 | if (texTarget == TEXTURE_UNKNOWN_INDEX) | 1204 | if (texTarget == TEXTURE_UNKNOWN_INDEX) |
1170 | program_error(p, "TexSrcBit"); | 1205 | program_error(p, "TexSrcBit"); |
1171 | 1206 | ||
@@ -1233,7 +1268,7 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit ) | |||
1233 | GLuint i; | 1268 | GLuint i; |
1234 | 1269 | ||
1235 | for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { | 1270 | for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { |
1236 | load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit); | 1271 | load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit ); |
1237 | } | 1272 | } |
1238 | 1273 | ||
1239 | for (i = 0; i < key->unit[unit].NumArgsA; i++) { | 1274 | for (i = 0; i < key->unit[unit].NumArgsA; i++) { |
@@ -1243,6 +1278,40 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit ) | |||
1243 | return GL_TRUE; | 1278 | return GL_TRUE; |
1244 | } | 1279 | } |
1245 | 1280 | ||
1281 | /** | ||
1282 | * Generate instructions for loading bump map textures. | ||
1283 | */ | ||
1284 | static GLboolean | ||
1285 | load_texunit_bumpmap( struct texenv_fragment_program *p, int unit ) | ||
1286 | { | ||
1287 | struct state_key *key = p->state; | ||
1288 | GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0; | ||
1289 | struct ureg texcDst, bumpMapRes; | ||
1290 | struct ureg constdudvcolor = register_const4f(p, 0.0, 0.0, 0.0, 1.0); | ||
1291 | struct ureg texcSrc = register_input(p, FRAG_ATTRIB_TEX0 + bumpedUnitNr); | ||
1292 | struct ureg rotMat0 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_0, unit ); | ||
1293 | struct ureg rotMat1 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_1, unit ); | ||
1294 | |||
1295 | load_texenv_source( p, unit + SRC_TEXTURE0, unit ); | ||
1296 | |||
1297 | bumpMapRes = get_source(p, key->unit[unit].OptRGB[0].Source, unit); | ||
1298 | texcDst = get_tex_temp( p ); | ||
1299 | p->texcoord_tex[bumpedUnitNr] = texcDst; | ||
1300 | |||
1301 | /* apply rot matrix and add coords to be available in next phase */ | ||
1302 | /* dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1) */ | ||
1303 | /* note only 2 coords are affected the rest are left unchanged (mul by 0) */ | ||
1304 | emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, | ||
1305 | swizzle1(bumpMapRes, SWIZZLE_X), rotMat0, texcSrc ); | ||
1306 | emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, | ||
1307 | swizzle1(bumpMapRes, SWIZZLE_Y), rotMat1, texcDst ); | ||
1308 | |||
1309 | /* move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish | ||
1310 | enough to access this later, should optimize away */ | ||
1311 | emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0, constdudvcolor, undef, undef ); | ||
1312 | |||
1313 | return GL_TRUE; | ||
1314 | } | ||
1246 | 1315 | ||
1247 | /** | 1316 | /** |
1248 | * Generate a new fragment program which implements the context's | 1317 | * Generate a new fragment program which implements the context's |
@@ -1267,7 +1336,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, | |||
1267 | */ | 1336 | */ |
1268 | p.program->Base.Instructions = instBuffer; | 1337 | p.program->Base.Instructions = instBuffer; |
1269 | p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; | 1338 | p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; |
1270 | p.program->Base.NumTexIndirections = 1; /* correct? */ | 1339 | p.program->Base.NumTexIndirections = 1; |
1271 | p.program->Base.NumTexInstructions = 0; | 1340 | p.program->Base.NumTexInstructions = 0; |
1272 | p.program->Base.NumAluInstructions = 0; | 1341 | p.program->Base.NumAluInstructions = 0; |
1273 | p.program->Base.String = NULL; | 1342 | p.program->Base.String = NULL; |
@@ -1280,8 +1349,10 @@ create_new_program(GLcontext *ctx, struct state_key *key, | |||
1280 | p.program->Base.InputsRead = 0; | 1349 | p.program->Base.InputsRead = 0; |
1281 | p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; | 1350 | p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; |
1282 | 1351 | ||
1283 | for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) | 1352 | for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { |
1284 | p.src_texture[unit] = undef; | 1353 | p.src_texture[unit] = undef; |
1354 | p.texcoord_tex[unit] = undef; | ||
1355 | } | ||
1285 | 1356 | ||
1286 | p.src_previous = undef; | 1357 | p.src_previous = undef; |
1287 | p.half = undef; | 1358 | p.half = undef; |
@@ -1292,6 +1363,16 @@ create_new_program(GLcontext *ctx, struct state_key *key, | |||
1292 | release_temps(ctx, &p); | 1363 | release_temps(ctx, &p); |
1293 | 1364 | ||
1294 | if (key->enabled_units) { | 1365 | if (key->enabled_units) { |
1366 | GLboolean needbumpstage = GL_FALSE; | ||
1367 | /* Zeroth pass - bump map textures first */ | ||
1368 | for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) | ||
1369 | if (key->unit[unit].enabled && key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { | ||
1370 | needbumpstage = GL_TRUE; | ||
1371 | load_texunit_bumpmap( &p, unit ); | ||
1372 | } | ||
1373 | if (needbumpstage) | ||
1374 | p.program->Base.NumTexIndirections++; | ||
1375 | |||
1295 | /* First pass - to support texture_env_crossbar, first identify | 1376 | /* First pass - to support texture_env_crossbar, first identify |
1296 | * all referenced texture sources and emit texld instructions | 1377 | * all referenced texture sources and emit texld instructions |
1297 | * for each: | 1378 | * for each: |
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 16d05cc7d07..61a12493a6b 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c | |||
@@ -696,6 +696,33 @@ const struct gl_texture_format _mesa_texformat_intensity_float16 = { | |||
696 | store_texel_intensity_f16 /* StoreTexel */ | 696 | store_texel_intensity_f16 /* StoreTexel */ |
697 | }; | 697 | }; |
698 | 698 | ||
699 | const struct gl_texture_format _mesa_texformat_dudv8 = { | ||
700 | MESA_FORMAT_DUDV8, /* MesaFormat */ | ||
701 | GL_DUDV_ATI, /* BaseFormat */ | ||
702 | /* FIXME: spec doesn't say since that parameter didn't exist then, | ||
703 | but this should be something like SIGNED_NORMALIZED */ | ||
704 | GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ | ||
705 | /* maybe should add dudvBits field, but spec seems to be | ||
706 | lacking the ability to query with GetTexLevelParameter anyway */ | ||
707 | 0, /* RedBits */ | ||
708 | 0, /* GreenBits */ | ||
709 | 0, /* BlueBits */ | ||
710 | 0, /* AlphaBits */ | ||
711 | 0, /* LuminanceBits */ | ||
712 | 0, /* IntensityBits */ | ||
713 | 0, /* IndexBits */ | ||
714 | 0, /* DepthBits */ | ||
715 | 0, /* StencilBits */ | ||
716 | 2, /* TexelBytes */ | ||
717 | _mesa_texstore_dudv8, /* StoreTexImageFunc */ | ||
718 | NULL, /* FetchTexel1D */ | ||
719 | NULL, /* FetchTexel2D */ | ||
720 | NULL, /* FetchTexel3D */ | ||
721 | NULL, /* FetchTexel1Df */ | ||
722 | fetch_texel_2d_dudv8, /* FetchTexel2Df */ | ||
723 | NULL, /* FetchTexel3Df */ | ||
724 | NULL /* StoreTexel */ | ||
725 | }; | ||
699 | 726 | ||
700 | /*@}*/ | 727 | /*@}*/ |
701 | 728 | ||
@@ -1634,6 +1661,16 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, | |||
1634 | } | 1661 | } |
1635 | } | 1662 | } |
1636 | 1663 | ||
1664 | if (ctx->Extensions.ATI_envmap_bumpmap) { | ||
1665 | switch (internalFormat) { | ||
1666 | case GL_DUDV_ATI: | ||
1667 | case GL_DU8DV8_ATI: | ||
1668 | return &_mesa_texformat_dudv8; | ||
1669 | default: | ||
1670 | ; /* fallthrough */ | ||
1671 | } | ||
1672 | } | ||
1673 | |||
1637 | #if FEATURE_EXT_texture_sRGB | 1674 | #if FEATURE_EXT_texture_sRGB |
1638 | if (ctx->Extensions.EXT_texture_sRGB) { | 1675 | if (ctx->Extensions.EXT_texture_sRGB) { |
1639 | switch (internalFormat) { | 1676 | switch (internalFormat) { |
@@ -1778,6 +1815,11 @@ _mesa_format_to_type_and_comps(const struct gl_texture_format *format, | |||
1778 | *comps = 1; | 1815 | *comps = 1; |
1779 | return; | 1816 | return; |
1780 | 1817 | ||
1818 | case MESA_FORMAT_DUDV8: | ||
1819 | *datatype = GL_BYTE; | ||
1820 | *comps = 2; | ||
1821 | return; | ||
1822 | |||
1781 | #if FEATURE_EXT_texture_sRGB | 1823 | #if FEATURE_EXT_texture_sRGB |
1782 | case MESA_FORMAT_SRGB8: | 1824 | case MESA_FORMAT_SRGB8: |
1783 | *datatype = GL_UNSIGNED_BYTE; | 1825 | *datatype = GL_UNSIGNED_BYTE; |
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 31364c36b1a..7fa70ad4fee 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h | |||
@@ -161,7 +161,14 @@ enum _format { | |||
161 | MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, | 161 | MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, |
162 | MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, | 162 | MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, |
163 | MESA_FORMAT_INTENSITY_FLOAT32, | 163 | MESA_FORMAT_INTENSITY_FLOAT32, |
164 | MESA_FORMAT_INTENSITY_FLOAT16 | 164 | MESA_FORMAT_INTENSITY_FLOAT16, |
165 | /*@}*/ | ||
166 | |||
167 | /** | ||
168 | * \name Signed fixed point texture formats. | ||
169 | */ | ||
170 | /*@{*/ | ||
171 | MESA_FORMAT_DUDV8 | ||
165 | /*@}*/ | 172 | /*@}*/ |
166 | }; | 173 | }; |
167 | 174 | ||
@@ -209,6 +216,11 @@ extern const struct gl_texture_format _mesa_texformat_intensity_float32; | |||
209 | extern const struct gl_texture_format _mesa_texformat_intensity_float16; | 216 | extern const struct gl_texture_format _mesa_texformat_intensity_float16; |
210 | /*@}*/ | 217 | /*@}*/ |
211 | 218 | ||
219 | /** Signed fixed point texture formats */ | ||
220 | /*@{*/ | ||
221 | extern const struct gl_texture_format _mesa_texformat_dudv8; | ||
222 | /*@}*/ | ||
223 | |||
212 | /** \name Assorted hardware-friendly formats */ | 224 | /** \name Assorted hardware-friendly formats */ |
213 | /*@{*/ | 225 | /*@{*/ |
214 | extern const struct gl_texture_format _mesa_texformat_rgba8888; | 226 | extern const struct gl_texture_format _mesa_texformat_rgba8888; |
diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index 275340cabd3..f9f9d5b1f8e 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h | |||
@@ -1269,7 +1269,7 @@ static void FETCH(sl8)(const struct gl_texture_image *texImage, | |||
1269 | texel[RCOMP] = | 1269 | texel[RCOMP] = |
1270 | texel[GCOMP] = | 1270 | texel[GCOMP] = |
1271 | texel[BCOMP] = nonlinear_to_linear(src[0]); | 1271 | texel[BCOMP] = nonlinear_to_linear(src[0]); |
1272 | texel[ACOMP] = CHAN_MAX; | 1272 | texel[ACOMP] = 1.0F; |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | #if DIM == 3 | 1275 | #if DIM == 3 |
@@ -1308,7 +1308,22 @@ static void store_texel_sla8(struct gl_texture_image *texImage, | |||
1308 | 1308 | ||
1309 | #endif /* FEATURE_EXT_texture_sRGB */ | 1309 | #endif /* FEATURE_EXT_texture_sRGB */ |
1310 | 1310 | ||
1311 | #if DIM == 2 | ||
1312 | /* MESA_FORMAT_DUDV8 ********************************************************/ | ||
1313 | |||
1314 | /* this format by definition produces 0,0,0,1 as rgba values, | ||
1315 | however we'll return the dudv values as rg and fix up elsewhere */ | ||
1316 | static void FETCH(dudv8)(const struct gl_texture_image *texImage, | ||
1317 | GLint i, GLint j, GLint k, GLfloat *texel ) | ||
1318 | { | ||
1319 | const GLbyte *src = TEXEL_ADDR(GLbyte, texImage, i, j, k, 2); | ||
1320 | texel[RCOMP] = BYTE_TO_FLOAT(src[0]); | ||
1321 | texel[GCOMP] = BYTE_TO_FLOAT(src[1]); | ||
1322 | texel[BCOMP] = 0; | ||
1323 | texel[ACOMP] = 0; | ||
1311 | 1324 | ||
1325 | } | ||
1326 | #endif | ||
1312 | 1327 | ||
1313 | /* MESA_FORMAT_YCBCR *********************************************************/ | 1328 | /* MESA_FORMAT_YCBCR *********************************************************/ |
1314 | 1329 | ||
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index e3d44047598..2ed72280ec9 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c | |||
@@ -339,6 +339,17 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) | |||
339 | } | 339 | } |
340 | } | 340 | } |
341 | 341 | ||
342 | if (ctx->Extensions.ATI_envmap_bumpmap) { | ||
343 | switch (internalFormat) { | ||
344 | case GL_DUDV_ATI: | ||
345 | case GL_DU8DV8_ATI: | ||
346 | return GL_DUDV_ATI; | ||
347 | default: | ||
348 | ; /* fallthrough */ | ||
349 | } | ||
350 | } | ||
351 | |||
352 | |||
342 | if (ctx->Extensions.EXT_packed_depth_stencil) { | 353 | if (ctx->Extensions.EXT_packed_depth_stencil) { |
343 | switch (internalFormat) { | 354 | switch (internalFormat) { |
344 | case GL_DEPTH_STENCIL_EXT: | 355 | case GL_DEPTH_STENCIL_EXT: |
@@ -568,6 +579,20 @@ is_depthstencil_format(GLenum format) | |||
568 | } | 579 | } |
569 | } | 580 | } |
570 | 581 | ||
582 | /** | ||
583 | * Test if the given image format is a dudv format. | ||
584 | */ | ||
585 | static GLboolean | ||
586 | is_dudv_format(GLenum format) | ||
587 | { | ||
588 | switch (format) { | ||
589 | case GL_DUDV_ATI: | ||
590 | case GL_DU8DV8_ATI: | ||
591 | return GL_TRUE; | ||
592 | default: | ||
593 | return GL_FALSE; | ||
594 | } | ||
595 | } | ||
571 | 596 | ||
572 | 597 | ||
573 | /** | 598 | /** |
@@ -1539,7 +1564,8 @@ texture_error_check( GLcontext *ctx, GLenum target, | |||
1539 | (is_index_format(internalFormat) && !indexFormat) || | 1564 | (is_index_format(internalFormat) && !indexFormat) || |
1540 | (is_depth_format(internalFormat) != is_depth_format(format)) || | 1565 | (is_depth_format(internalFormat) != is_depth_format(format)) || |
1541 | (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || | 1566 | (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || |
1542 | (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) { | 1567 | (is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) || |
1568 | (is_dudv_format(internalFormat) != is_dudv_format(format))) { | ||
1543 | if (!isProxy) | 1569 | if (!isProxy) |
1544 | _mesa_error(ctx, GL_INVALID_OPERATION, | 1570 | _mesa_error(ctx, GL_INVALID_OPERATION, |
1545 | "glTexImage(internalFormat/format)"); | 1571 | "glTexImage(internalFormat/format)"); |
@@ -2273,6 +2299,12 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, | |||
2273 | return; | 2299 | return; |
2274 | } | 2300 | } |
2275 | 2301 | ||
2302 | if (!ctx->Extensions.ATI_envmap_bumpmap | ||
2303 | && is_dudv_format(format)) { | ||
2304 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); | ||
2305 | return; | ||
2306 | } | ||
2307 | |||
2276 | _mesa_lock_texture(ctx, texObj); | 2308 | _mesa_lock_texture(ctx, texObj); |
2277 | { | 2309 | { |
2278 | texImage = _mesa_select_tex_image(ctx, texObj, target, level); | 2310 | texImage = _mesa_select_tex_image(ctx, texObj, target, level); |
@@ -2313,6 +2345,11 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, | |||
2313 | _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); | 2345 | _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); |
2314 | goto out; | 2346 | goto out; |
2315 | } | 2347 | } |
2348 | else if (is_dudv_format(format) | ||
2349 | && !is_dudv_format(texImage->TexFormat->BaseFormat)) { | ||
2350 | _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); | ||
2351 | goto out; | ||
2352 | } | ||
2316 | 2353 | ||
2317 | if (ctx->Pack.BufferObj->Name) { | 2354 | if (ctx->Pack.BufferObj->Name) { |
2318 | /* packing texture image into a PBO */ | 2355 | /* packing texture image into a PBO */ |
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index d71f9530cb3..a5af6229104 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c | |||
@@ -95,6 +95,11 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) | |||
95 | /* GL_EXT_texture_env_combine */ | 95 | /* GL_EXT_texture_env_combine */ |
96 | dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine; | 96 | dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine; |
97 | 97 | ||
98 | /* GL_ATI_envmap_bumpmap - need this? */ | ||
99 | dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget; | ||
100 | COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix); | ||
101 | |||
102 | |||
98 | /* copy texture object bindings, not contents of texture objects */ | 103 | /* copy texture object bindings, not contents of texture objects */ |
99 | _mesa_lock_context_textures(dst); | 104 | _mesa_lock_context_textures(dst); |
100 | 105 | ||
@@ -411,6 +416,10 @@ update_tex_combine(GLcontext *ctx, struct gl_texture_unit *texUnit) | |||
411 | case GL_MODULATE_SUBTRACT_ATI: | 416 | case GL_MODULATE_SUBTRACT_ATI: |
412 | combine->_NumArgsRGB = 3; | 417 | combine->_NumArgsRGB = 3; |
413 | break; | 418 | break; |
419 | case GL_BUMP_ENVMAP_ATI: | ||
420 | /* no real arguments for this case */ | ||
421 | combine->_NumArgsRGB = 0; | ||
422 | break; | ||
414 | default: | 423 | default: |
415 | combine->_NumArgsRGB = 0; | 424 | combine->_NumArgsRGB = 0; |
416 | _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); | 425 | _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); |
@@ -682,6 +691,7 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) | |||
682 | texUnit->Combine = default_combine_state; | 691 | texUnit->Combine = default_combine_state; |
683 | texUnit->_EnvMode = default_combine_state; | 692 | texUnit->_EnvMode = default_combine_state; |
684 | texUnit->_CurrentCombine = & texUnit->_EnvMode; | 693 | texUnit->_CurrentCombine = & texUnit->_EnvMode; |
694 | texUnit->BumpTarget = GL_TEXTURE0; | ||
685 | 695 | ||
686 | texUnit->TexGenEnabled = 0x0; | 696 | texUnit->TexGenEnabled = 0x0; |
687 | texUnit->GenS.Mode = GL_EYE_LINEAR; | 697 | texUnit->GenS.Mode = GL_EYE_LINEAR; |
@@ -702,6 +712,16 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) | |||
702 | ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 ); | 712 | ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 ); |
703 | ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 ); | 713 | ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 ); |
704 | ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 ); | 714 | ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 ); |
715 | ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 ); | ||
716 | ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 ); | ||
717 | ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 ); | ||
718 | ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 ); | ||
719 | ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 ); | ||
720 | ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 ); | ||
721 | ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 ); | ||
722 | ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 ); | ||
723 | /* no mention of this in spec, but maybe id matrix expected? */ | ||
724 | ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 ); | ||
705 | 725 | ||
706 | /* initialize current texture object ptrs to the shared default objects */ | 726 | /* initialize current texture object ptrs to the shared default objects */ |
707 | for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { | 727 | for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { |
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 6360ca15f81..cc3c6958c7d 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c | |||
@@ -2471,6 +2471,95 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS) | |||
2471 | return GL_TRUE; | 2471 | return GL_TRUE; |
2472 | } | 2472 | } |
2473 | 2473 | ||
2474 | GLboolean | ||
2475 | _mesa_texstore_dudv8(TEXSTORE_PARAMS) | ||
2476 | { | ||
2477 | const GLboolean littleEndian = _mesa_little_endian(); | ||
2478 | |||
2479 | ASSERT(dstFormat == &_mesa_texformat_dudv8); | ||
2480 | ASSERT(dstFormat->TexelBytes == 2); | ||
2481 | ASSERT(ctx->Extensions.ATI_envmap_bumpmap); | ||
2482 | ASSERT((srcFormat == GL_DU8DV8_ATI) || | ||
2483 | (srcFormat == GL_DUDV_ATI)); | ||
2484 | ASSERT(baseInternalFormat == GL_DUDV_ATI); | ||
2485 | |||
2486 | if (!srcPacking->SwapBytes && srcType == GL_BYTE && | ||
2487 | littleEndian) { | ||
2488 | /* simple memcpy path */ | ||
2489 | memcpy_texture(ctx, dims, | ||
2490 | dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, | ||
2491 | dstRowStride, | ||
2492 | dstImageOffsets, | ||
2493 | srcWidth, srcHeight, srcDepth, srcFormat, srcType, | ||
2494 | srcAddr, srcPacking); | ||
2495 | } | ||
2496 | else if (srcType == GL_BYTE) { | ||
2497 | |||
2498 | GLubyte dstmap[4]; | ||
2499 | |||
2500 | /* dstmap - how to swizzle from RGBA to dst format: | ||
2501 | */ | ||
2502 | if (littleEndian) { | ||
2503 | dstmap[0] = 0; | ||
2504 | dstmap[1] = 3; | ||
2505 | } | ||
2506 | else { | ||
2507 | dstmap[0] = 3; | ||
2508 | dstmap[1] = 0; | ||
2509 | } | ||
2510 | dstmap[2] = ZERO; /* ? */ | ||
2511 | dstmap[3] = ONE; /* ? */ | ||
2512 | |||
2513 | _mesa_swizzle_ubyte_image(ctx, dims, | ||
2514 | GL_LUMINANCE_ALPHA, /* hack */ | ||
2515 | GL_UNSIGNED_BYTE, /* hack */ | ||
2516 | GL_LUMINANCE_ALPHA, /* hack */ | ||
2517 | dstmap, 2, | ||
2518 | dstAddr, dstXoffset, dstYoffset, dstZoffset, | ||
2519 | dstRowStride, dstImageOffsets, | ||
2520 | srcWidth, srcHeight, srcDepth, srcAddr, | ||
2521 | srcPacking); | ||
2522 | } | ||
2523 | else { | ||
2524 | /* general path - note this is defined for 2d textures only */ | ||
2525 | const GLint components = _mesa_components_in_format(baseInternalFormat); | ||
2526 | const GLint srcStride = _mesa_image_row_stride(srcPacking, | ||
2527 | srcWidth, srcFormat, srcType); | ||
2528 | GLbyte *tempImage, *dst, *src; | ||
2529 | GLint row; | ||
2530 | |||
2531 | tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth | ||
2532 | * components * sizeof(GLbyte)); | ||
2533 | if (!tempImage) | ||
2534 | return GL_FALSE; | ||
2535 | |||
2536 | src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr, | ||
2537 | srcWidth, srcHeight, | ||
2538 | srcFormat, srcType, | ||
2539 | 0, 0, 0); | ||
2540 | |||
2541 | dst = tempImage; | ||
2542 | for (row = 0; row < srcHeight; row++) { | ||
2543 | _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat, | ||
2544 | dst, srcFormat, srcType, src, | ||
2545 | srcPacking, 0); | ||
2546 | dst += srcWidth * components; | ||
2547 | src += srcStride; | ||
2548 | } | ||
2549 | |||
2550 | src = tempImage; | ||
2551 | dst = (GLbyte *) dstAddr | ||
2552 | + dstYoffset * dstRowStride | ||
2553 | + dstXoffset * dstFormat->TexelBytes; | ||
2554 | for (row = 0; row < srcHeight; row++) { | ||
2555 | memcpy(dst, src, srcWidth * dstFormat->TexelBytes); | ||
2556 | dst += dstRowStride; | ||
2557 | src += srcWidth * dstFormat->TexelBytes; | ||
2558 | } | ||
2559 | _mesa_free((void *) tempImage); | ||
2560 | } | ||
2561 | return GL_TRUE; | ||
2562 | } | ||
2474 | 2563 | ||
2475 | 2564 | ||
2476 | /** | 2565 | /** |
@@ -3882,7 +3971,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, | |||
3882 | GLint col; | 3971 | GLint col; |
3883 | GLbitfield transferOps = 0x0; | 3972 | GLbitfield transferOps = 0x0; |
3884 | 3973 | ||
3885 | if (type == GL_FLOAT && | 3974 | if (type == GL_FLOAT && texImage->TexFormat->BaseFormat != GL_DUDV_ATI && |
3886 | ((ctx->Color.ClampReadColor == GL_TRUE) || | 3975 | ((ctx->Color.ClampReadColor == GL_TRUE) || |
3887 | (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB && | 3976 | (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB && |
3888 | texImage->TexFormat->DataType != GL_FLOAT))) | 3977 | texImage->TexFormat->DataType != GL_FLOAT))) |
diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index b03386b2acc..c9e639be4e0 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h | |||
@@ -78,7 +78,7 @@ extern GLboolean _mesa_texstore_sargb8(TEXSTORE_PARAMS); | |||
78 | extern GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS); | 78 | extern GLboolean _mesa_texstore_sl8(TEXSTORE_PARAMS); |
79 | extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS); | 79 | extern GLboolean _mesa_texstore_sla8(TEXSTORE_PARAMS); |
80 | #endif | 80 | #endif |
81 | 81 | extern GLboolean _mesa_texstore_dudv8(TEXSTORE_PARAMS); | |
82 | 82 | ||
83 | extern GLchan * | 83 | extern GLchan * |
84 | _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, | 84 | _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, |
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 1f7d87ccc94..f51d9e26512 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c | |||
@@ -506,6 +506,26 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], | |||
506 | } | 506 | } |
507 | } | 507 | } |
508 | return; | 508 | return; |
509 | case STATE_ROT_MATRIX_0: | ||
510 | { | ||
511 | const int unit = (int) state[2]; | ||
512 | GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; | ||
513 | value[0] = rotMat22[0]; | ||
514 | value[1] = rotMat22[2]; | ||
515 | value[2] = 0.0; | ||
516 | value[3] = 0.0; | ||
517 | } | ||
518 | break; | ||
519 | case STATE_ROT_MATRIX_1: | ||
520 | { | ||
521 | const int unit = (int) state[2]; | ||
522 | GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; | ||
523 | value[0] = rotMat22[1]; | ||
524 | value[1] = rotMat22[3]; | ||
525 | value[2] = 0.0; | ||
526 | value[3] = 0.0; | ||
527 | } | ||
528 | break; | ||
509 | 529 | ||
510 | /* XXX: make sure new tokens added here are also handled in the | 530 | /* XXX: make sure new tokens added here are also handled in the |
511 | * _mesa_program_state_flags() switch, below. | 531 | * _mesa_program_state_flags() switch, below. |
@@ -591,6 +611,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) | |||
591 | 611 | ||
592 | case STATE_TEXRECT_SCALE: | 612 | case STATE_TEXRECT_SCALE: |
593 | case STATE_SHADOW_AMBIENT: | 613 | case STATE_SHADOW_AMBIENT: |
614 | case STATE_ROT_MATRIX_0: | ||
615 | case STATE_ROT_MATRIX_1: | ||
594 | return _NEW_TEXTURE; | 616 | return _NEW_TEXTURE; |
595 | case STATE_FOG_PARAMS_OPTIMIZED: | 617 | case STATE_FOG_PARAMS_OPTIMIZED: |
596 | return _NEW_FOG; | 618 | return _NEW_FOG; |
@@ -806,6 +828,12 @@ append_token(char *dst, gl_state_index k) | |||
806 | case STATE_SHADOW_AMBIENT: | 828 | case STATE_SHADOW_AMBIENT: |
807 | append(dst, "CompareFailValue"); | 829 | append(dst, "CompareFailValue"); |
808 | break; | 830 | break; |
831 | case STATE_ROT_MATRIX_0: | ||
832 | append(dst, "rotMatrixRow0"); | ||
833 | break; | ||
834 | case STATE_ROT_MATRIX_1: | ||
835 | append(dst, "rotMatrixRow1"); | ||
836 | break; | ||
809 | default: | 837 | default: |
810 | /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ | 838 | /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ |
811 | append(dst, "driverState"); | 839 | append(dst, "driverState"); |
diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index d5358a1d042..d563080db1c 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h | |||
@@ -117,6 +117,8 @@ typedef enum gl_state_index_ { | |||
117 | STATE_PCM_SCALE, /**< Post color matrix RGBA scale */ | 117 | STATE_PCM_SCALE, /**< Post color matrix RGBA scale */ |
118 | STATE_PCM_BIAS, /**< Post color matrix RGBA bias */ | 118 | STATE_PCM_BIAS, /**< Post color matrix RGBA bias */ |
119 | STATE_SHADOW_AMBIENT, /**< ARB_shadow_ambient fail value; token[2] is texture unit index */ | 119 | STATE_SHADOW_AMBIENT, /**< ARB_shadow_ambient fail value; token[2] is texture unit index */ |
120 | STATE_ROT_MATRIX_0, /**< ATI_envmap_bumpmap, rot matrix row 0 */ | ||
121 | STATE_ROT_MATRIX_1, /**< ATI_envmap_bumpmap, rot matrix row 1 */ | ||
120 | STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ | 122 | STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ |
121 | } gl_state_index; | 123 | } gl_state_index; |
122 | 124 | ||
diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 38b5633887f..aa28311672d 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c | |||
@@ -591,6 +591,25 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, | |||
591 | } | 591 | } |
592 | } | 592 | } |
593 | break; | 593 | break; |
594 | case GL_BUMP_ENVMAP_ATI: | ||
595 | { | ||
596 | /* this produces a fixed rgba color, and the coord calc is done elsewhere */ | ||
597 | for (i = 0; i < n; i++) { | ||
598 | /* rgba result is 0,0,0,1 */ | ||
599 | #if CHAN_TYPE == GL_FLOAT | ||
600 | rgba[i][RCOMP] = 0.0; | ||
601 | rgba[i][GCOMP] = 0.0; | ||
602 | rgba[i][BCOMP] = 0.0; | ||
603 | rgba[i][ACOMP] = 1.0; | ||
604 | #else | ||
605 | rgba[i][RCOMP] = 0; | ||
606 | rgba[i][GCOMP] = 0; | ||
607 | rgba[i][BCOMP] = 0; | ||
608 | rgba[i][ACOMP] = CHAN_MAX; | ||
609 | #endif | ||
610 | } | ||
611 | } | ||
612 | return; /* no alpha processing */ | ||
594 | default: | 613 | default: |
595 | _mesa_problem(ctx, "invalid combine mode"); | 614 | _mesa_problem(ctx, "invalid combine mode"); |
596 | } | 615 | } |
@@ -1218,12 +1237,86 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) | |||
1218 | if (swrast->_AnyTextureCombine) | 1237 | if (swrast->_AnyTextureCombine) |
1219 | MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); | 1238 | MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); |
1220 | 1239 | ||
1240 | /* First must sample all bump maps */ | ||
1241 | for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { | ||
1242 | if (ctx->Texture.Unit[unit]._ReallyEnabled && | ||
1243 | ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) { | ||
1244 | const GLfloat (*texcoords)[4] | ||
1245 | = (const GLfloat (*)[4]) | ||
1246 | span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; | ||
1247 | GLfloat (*targetcoords)[4] | ||
1248 | = (GLfloat (*)[4]) | ||
1249 | span->array->attribs[FRAG_ATTRIB_TEX0 + | ||
1250 | ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0]; | ||
1251 | |||
1252 | const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | ||
1253 | const struct gl_texture_object *curObj = texUnit->_Current; | ||
1254 | GLfloat *lambda = span->array->lambda[unit]; | ||
1255 | GLchan (*texels)[4] = (GLchan (*)[4]) | ||
1256 | (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan))); | ||
1257 | GLuint i; | ||
1258 | GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0]; | ||
1259 | GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1]; | ||
1260 | GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2]; | ||
1261 | GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3]; | ||
1262 | |||
1263 | /* adjust texture lod (lambda) */ | ||
1264 | if (span->arrayMask & SPAN_LAMBDA) { | ||
1265 | if (texUnit->LodBias + curObj->LodBias != 0.0F) { | ||
1266 | /* apply LOD bias, but don't clamp yet */ | ||
1267 | const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias, | ||
1268 | -ctx->Const.MaxTextureLodBias, | ||
1269 | ctx->Const.MaxTextureLodBias); | ||
1270 | GLuint i; | ||
1271 | for (i = 0; i < span->end; i++) { | ||
1272 | lambda[i] += bias; | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) { | ||
1277 | /* apply LOD clamping to lambda */ | ||
1278 | const GLfloat min = curObj->MinLod; | ||
1279 | const GLfloat max = curObj->MaxLod; | ||
1280 | GLuint i; | ||
1281 | for (i = 0; i < span->end; i++) { | ||
1282 | GLfloat l = lambda[i]; | ||
1283 | lambda[i] = CLAMP(l, min, max); | ||
1284 | } | ||
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | /* Sample the texture (span->end = number of fragments) */ | ||
1289 | swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, | ||
1290 | texcoords, lambda, texels ); | ||
1291 | |||
1292 | /* manipulate the span values of the bump target | ||
1293 | not sure this can work correctly even ignoring | ||
1294 | the problem that channel is unsigned */ | ||
1295 | for (i = 0; i < span->end; i++) { | ||
1296 | #if CHAN_TYPE == GL_FLOAT | ||
1297 | targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] * | ||
1298 | rotMatrix01) / targetcoords[i][3]; | ||
1299 | targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] * | ||
1300 | rotMatrix11) / targetcoords[i][3]; | ||
1301 | #else | ||
1302 | targetcoords[i][0] += (CHAN_TO_FLOAT(texels[i][1]) * rotMatrix00 + | ||
1303 | CHAN_TO_FLOAT(texels[i][1]) * rotMatrix01) / | ||
1304 | targetcoords[i][3]; | ||
1305 | targetcoords[i][1] += (CHAN_TO_FLOAT(texels[i][0]) * rotMatrix10 + | ||
1306 | CHAN_TO_FLOAT(texels[i][1]) * rotMatrix11) / | ||
1307 | targetcoords[i][3]; | ||
1308 | #endif | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1221 | /* | 1313 | /* |
1222 | * Must do all texture sampling before combining in order to | 1314 | * Must do all texture sampling before combining in order to |
1223 | * accomodate GL_ARB_texture_env_crossbar. | 1315 | * accomodate GL_ARB_texture_env_crossbar. |
1224 | */ | 1316 | */ |
1225 | for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { | 1317 | for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { |
1226 | if (ctx->Texture.Unit[unit]._ReallyEnabled) { | 1318 | if (ctx->Texture.Unit[unit]._ReallyEnabled && |
1319 | ctx->Texture.Unit[unit]._CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) { | ||
1227 | const GLfloat (*texcoords)[4] | 1320 | const GLfloat (*texcoords)[4] |
1228 | = (const GLfloat (*)[4]) | 1321 | = (const GLfloat (*)[4]) |
1229 | span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; | 1322 | span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; |