diff options
Diffstat (limited to 'src/mesa/drivers')
239 files changed, 19609 insertions, 17257 deletions
diff --git a/src/mesa/drivers/beos/GLView.cpp b/src/mesa/drivers/beos/GLView.cpp index 45473a8ef27..9e4a7ebe56e 100644 --- a/src/mesa/drivers/beos/GLView.cpp +++ b/src/mesa/drivers/beos/GLView.cpp @@ -43,7 +43,7 @@ extern "C" { #include "texobj.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -344,7 +344,7 @@ BGLView::BGLView(BRect rect, char *name, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); @@ -830,7 +830,7 @@ void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); if (ctx->Color.DrawBuffer[0] == GL_FRONT) { diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 3c8c6c256e6..88ac4bb31d5 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -1,18 +1,19 @@ /* - * Copyright (C) 2004-2006 Claudio Ciccani <[email protected]> + * Copyright (C) 2004-2007 Claudio Ciccani <[email protected]> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * Based on glfbdev.c, written by Brian Paul. @@ -45,7 +46,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -373,7 +374,7 @@ dfbUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -786,7 +787,7 @@ directfbgl_create_context( GLcontext *context, } _swrast_CreateContext( context ); - _ac_CreateContext( context ); + _vbo_CreateContext( context ); _tnl_CreateContext( context ); _swsetup_CreateContext( context ); _swsetup_Wakeup( context ); diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index ba251a81430..cc3dcf9d8db 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -482,8 +482,27 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) { __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + drm_clip_rect_t rect; + dPriv->swapBuffers(dPriv); - (void) dpy; + + /* Check that we actually have the new damage report method */ + if (api_ver < 20070105 || dri_interface->reportDamage == NULL) + return; + + /* Assume it's affecting the whole drawable for now */ + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = rect.x1 + dPriv->w; + rect.y2 = rect.y1 + dPriv->h; + + /* Report the damage. Currently, all our drivers draw directly to the + * front buffer, so we report the damage there rather than to the backing + * store (if any). + */ + (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw, + dPriv->x, dPriv->y, + &rect, 1, GL_TRUE); } /** diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index d6d51cdd165..c7984964255 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -2466,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] = ""; #endif -#if defined(need_GL_VERSION_2_0) -static const char GetVertexAttribPointervARB_names[] = - "iip\0" /* Parameter signature */ - "glGetVertexAttribPointerv\0" +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramLocalParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramLocalParameters4fvEXT\0" ""; #endif @@ -3152,13 +3152,6 @@ static const char VertexAttribPointerNV_names[] = ""; #endif -#if defined(need_GL_EXT_gpu_program_parameters) -static const char ProgramLocalParameters4fvEXT_names[] = - "iiip\0" /* Parameter signature */ - "glProgramLocalParameters4fvEXT\0" - ""; -#endif - #if defined(need_GL_EXT_framebuffer_object) static const char GetFramebufferAttachmentParameterivEXT_names[] = "iiip\0" /* Parameter signature */ @@ -3781,9 +3774,10 @@ static const char ReplacementCodeuiColor3fVertex3fSUN_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) static const char GetVertexAttribPointervNV_names[] = "iip\0" /* Parameter signature */ + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glGetVertexAttribPointervNV\0" ""; @@ -5343,8 +5337,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] #if defined(need_GL_EXT_gpu_program_parameters) static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = { - { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 }, + { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { NULL, 0, 0 } }; #endif @@ -6263,7 +6257,6 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, - { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 }, { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, @@ -6295,6 +6288,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, { DeleteProgram_names, DeleteProgram_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c index d6ba23bc6e6..08b52b4d8f7 100644 --- a/src/mesa/drivers/dri/fb/fb_dri.c +++ b/src/mesa/drivers/dri/fb/fb_dri.c @@ -50,7 +50,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -93,7 +93,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -365,7 +365,7 @@ fbCreateContext( const __GLcontextModes *glVisual, /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); @@ -399,7 +399,7 @@ fbDestroyContext( __DRIcontextPrivate *driContextPriv ) if ( fbmesa ) { _swsetup_DestroyContext( fbmesa->glCtx ); _tnl_DestroyContext( fbmesa->glCtx ); - _ac_DestroyContext( fbmesa->glCtx ); + _vbo_DestroyContext( fbmesa->glCtx ); _swrast_DestroyContext( fbmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c index 5c74b0b0f47..517e71f8880 100644 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ b/src/mesa/drivers/dri/fb/fb_egl.c @@ -17,7 +17,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -388,7 +388,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -491,7 +491,7 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index b81d94de252..eb13478166a 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1034,7 +1034,7 @@ static void ffbDDUpdateState(GLcontext *ctx, GLuint newstate) _swrast_InvalidateState( ctx, newstate ); _swsetup_InvalidateState( ctx, newstate ); - _ac_InvalidateState( ctx, newstate ); + _vbo_InvalidateState( ctx, newstate ); _tnl_InvalidateState( ctx, newstate ); if (newstate & _NEW_TEXTURE) diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 99256d76b6e..215aaf8ffba 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -38,7 +38,7 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "drivers/common/driverfuncs.h" #include "ffb_context.h" @@ -277,7 +277,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -313,7 +313,7 @@ ffbDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext( fmesa->glCtx ); _tnl_DestroyContext( fmesa->glCtx ); - _ac_DestroyContext( fmesa->glCtx ); + _vbo_DestroyContext( fmesa->glCtx ); _swrast_DestroyContext( fmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/gamma/gamma_context.c b/src/mesa/drivers/dri/gamma/gamma_context.c index ffaf45459bc..b1dcbfcdcfa 100644 --- a/src/mesa/drivers/dri/gamma/gamma_context.c +++ b/src/mesa/drivers/dri/gamma/gamma_context.c @@ -28,7 +28,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -147,7 +147,7 @@ GLboolean gammaCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c index 08749bf5d39..8dbe0a97caa 100644 --- a/src/mesa/drivers/dri/gamma/gamma_state.c +++ b/src/mesa/drivers/dri/gamma/gamma_state.c @@ -33,7 +33,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #define ENABLELIGHTING 0 @@ -1663,7 +1663,7 @@ static void gammaDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); GAMMA_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c index 00f6aa32aeb..e8922b15036 100644 --- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c +++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c @@ -34,7 +34,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" static GLboolean gammaInitDriver(__DRIscreenPrivate *sPriv) @@ -57,7 +57,7 @@ gammaDestroyContext(__DRIcontextPrivate *driContextPriv) if (gmesa) { _swsetup_DestroyContext( gmesa->glCtx ); _tnl_DestroyContext( gmesa->glCtx ); - _ac_DestroyContext( gmesa->glCtx ); + _vbo_DestroyContext( gmesa->glCtx ); _swrast_DestroyContext( gmesa->glCtx ); gammaFreeVB( gmesa->glCtx ); diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index c0f4efd7a31..db8f7a19a23 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -44,7 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -287,7 +287,7 @@ i810CreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -350,7 +350,7 @@ i810DestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); i810FreeVB( imesa->glCtx ); diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 6f9d4b5bd47..3ad25282d90 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -21,8 +21,8 @@ #include "i810ioctl.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" #include "tnl/tnl.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "tnl/t_pipeline.h" @@ -953,7 +953,7 @@ static void i810InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); I810_CONTEXT(ctx)->new_state |= new_state; } diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index b2e9ba31874..e58c9498ce0 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -36,7 +36,8 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" + #include "utils.h" #include "i915_reg.h" @@ -63,7 +64,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 3cec6a2ddfc..fd11e10652e 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -611,10 +611,12 @@ void i915_update_fog( GLcontext *ctx ) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog( ctx, (i915->vertex_fog == I915_FOG_VERTEX) ); - _tnl_allow_pixel_fog( ctx, (i915->vertex_fog != I915_FOG_VERTEX) ); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 0a2e33ffd53..7bb00d98339 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -37,7 +37,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -228,7 +228,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; @@ -304,7 +304,7 @@ GLboolean intelInitContext( intelContextPtr intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -423,7 +423,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 94879d209f7..3b3f3f5a3f7 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -20,6 +20,7 @@ DRIVER_SOURCES = \ intel_batchbuffer.c \ intel_mipmap_tree.c \ i915_tex_layout.c \ + intel_tex_layout.c \ intel_tex_image.c \ intel_tex_subimage.c \ intel_tex_copy.c \ @@ -59,8 +60,10 @@ C_SOURCES = \ ASM_SOURCES = - +DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_tex_layout.o: ../intel/intel_tex_layout.c + symlinks: diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c index 4cbe29d79d6..9b4d72eab3e 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.c +++ b/src/mesa/drivers/dri/i915tex/i915_context.c @@ -36,7 +36,6 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" #include "utils.h" #include "i915_reg.h" @@ -67,7 +66,7 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state) { _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _tnl_invalidate_vertex_state(ctx, new_state); intel_context(ctx)->NewGLState |= new_state; diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index 5ae76fcd185..d2713e88f96 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -243,7 +243,6 @@ struct i915_context GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; - struct i915_fragment_program tex_program; struct i915_fragment_program *current_program; struct i915_hw_state meta, initial, state, *current; diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 2f5a30787ee..78ae4bdb5fc 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -520,7 +520,6 @@ update_specular(GLcontext * ctx) /* A hack to trigger the rebuild of the fragment program. */ intel_context(ctx)->NewGLState |= _NEW_TEXTURE; - I915_CONTEXT(ctx)->tex_program.translated = 0; } static void @@ -646,10 +645,12 @@ i915_update_fog(GLcontext * ctx) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX)); - _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX)); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c index a53abe9a92f..59e148ca04e 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex.c @@ -52,27 +52,6 @@ i915TexEnv(GLcontext * ctx, GLenum target, struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { - case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - i915->tex_program.translated = 0; - break; - case GL_TEXTURE_LOD_BIAS:{ GLuint unit = ctx->Texture.CurrentUnit; GLint b = (int) ((*param) * 16.0); @@ -92,22 +71,8 @@ i915TexEnv(GLcontext * ctx, GLenum target, } -static void -i915BindTexture(GLcontext * ctx, GLenum target, - struct gl_texture_object *texobj) -{ - /* Need this if image format changes between bound textures. - * Could try and shortcircuit by checking for differences in - * state between incoming and outgoing textures: - */ - I915_CONTEXT(ctx)->tex_program.translated = 0; -} - - - void i915InitTextureFuncs(struct dd_function_table *functions) { - functions->BindTexture = i915BindTexture; functions->TexEnv = i915TexEnv; } diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index e9360ecea83..333fefef859 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -30,6 +30,7 @@ */ #include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" #include "macros.h" #include "intel_context.h" @@ -52,12 +53,6 @@ static GLint step_offsets[6][2] = { {0, 2}, {-1, 1} }; -static GLuint -minify(GLuint d) -{ - return MAX2(1, d >> 1); -} - GLboolean i915_miptree_layout(struct intel_mipmap_tree * mt) { @@ -217,7 +212,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt) y = mt->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4) { + else if (dim < 4 && (face > 0 || mt->first_level > 0)) { y = mt->total_height - 4; x = face * 8; } @@ -322,52 +317,9 @@ i945_miptree_layout(struct intel_mipmap_tree * mt) case GL_TEXTURE_1D: case GL_TEXTURE_2D: - case GL_TEXTURE_RECTANGLE_ARB:{ - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - GLint align_h = 2; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, - x, y, - width, - mt->compressed ? height/4 : height, 1); - - - if (mt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = MAX2(align_h, height); - - /* LPT change: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += mt->pitch / 2; - x = (x + 3) & ~3; - } - else { - y += img_height; - y += align_h - 1; - y &= ~(align_h - 1); - } - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y); - - width = minify(width); - height = minify(height); - } + case GL_TEXTURE_RECTANGLE_ARB: + i945_miptree_layout_2d(mt); break; - } default: _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); } diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index b4e0b74f161..c92b83bcb3a 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -252,6 +252,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; if (used == 0) return batch->last_fence; @@ -278,17 +279,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ - if (!intel->locked) { - assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS)); - + if (!was_locked) LOCK_HARDWARE(intel); - do_flush_locked(batch, used, GL_FALSE, GL_TRUE); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) UNLOCK_HARDWARE(intel); - } - else { - GLboolean ignore_cliprects = !(batch->flags & INTEL_BATCH_CLIPRECTS); - do_flush_locked(batch, used, ignore_cliprects, GL_FALSE); - } /* Reset the buffer: */ @@ -313,7 +311,7 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, struct _DriBufferObject *buffer, GLuint flags, GLuint mask, GLuint delta) { - assert(batch->nr_relocs <= MAX_RELOCS); + assert(batch->nr_relocs < MAX_RELOCS); driBOAddListItem(&batch->list, buffer, flags, mask); diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index a83dbf423df..59261f72741 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -9,7 +9,7 @@ struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 100 +#define MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 31c41d86857..ba3c7f0c1f7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -50,7 +50,10 @@ intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) _mesa_initialize_buffer_object(&obj->Base, name, target); driGenBuffers(intel->intelScreen->regionPool, - "bufferobj", 1, &obj->buffer, 64, 0, 0); + "bufferobj", 1, &obj->buffer, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0); return &obj->Base; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index c77d365360d..a5ce08b1701 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -37,7 +37,6 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -241,7 +240,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) { _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _tnl_invalidate_vertex_state(ctx, new_state); intel_context(ctx)->NewGLState |= new_state; @@ -357,6 +356,10 @@ intelInitContext(struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + intel->width = intelScreen->width; + intel->height = intelScreen->height; + intel->current_rotation = intelScreen->current_rotation; + if (!lockMutexInit) { lockMutexInit = GL_TRUE; _glthread_INIT_MUTEX(lockMutex); @@ -390,7 +393,7 @@ intelInitContext(struct intel_context *intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -500,7 +503,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext(&intel->ctx); _tnl_DestroyContext(&intel->ctx); - _ac_DestroyContext(&intel->ctx); + _vbo_DestroyContext(&intel->ctx); _swrast_DestroyContext(&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ @@ -635,14 +638,35 @@ intelContendedLock(struct intel_context *intel, GLuint flags) sarea->rotation != intelScreen->current_rotation) { intelUpdateScreenRotation(sPriv, sarea); + } - /* + if (sarea->width != intel->width || + sarea->height != intel->height || + sarea->rotation != intel->current_rotation) { + + void *batchMap = intel->batch->map; + + /* + * FIXME: Really only need to do this when drawing to a + * common back- or front buffer. + */ + + /* * This will drop the outstanding batchbuffer on the floor - * FIXME: This should be done for all contexts? */ + if (batchMap != NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + intel_batchbuffer_reset(intel->batch); + if (batchMap == NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + /* lose all primitives */ intel->prim.primitive = ~0; intel->prim.start_ptr = 0; @@ -653,6 +677,10 @@ intelContendedLock(struct intel_context *intel, GLuint flags) /* force window update */ intel->lastStamp = 0; + + intel->width = sarea->width; + intel->height = sarea->height; + intel->current_rotation = sarea->rotation; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 7654e4ecd51..96b911501f3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -286,6 +286,15 @@ struct intel_context GLuint swap_missed_count; GLuint swap_scheduled; + + /* Rotation. Need to match that of the + * current screen. + */ + + int width; + int height; + int current_rotation; + }; /* These are functions now: diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 9bbfabbb8c3..efa1b014a61 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -737,6 +737,9 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, */ stencil_bits_array[0] = 0; stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_layout.c b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c new file mode 120000 index 00000000000..fe61b441945 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c index 25a2dca6857..3935787806b 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c @@ -50,7 +50,6 @@ intelTexSubimage(GLcontext * ctx, { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); - GLuint dstImageStride; GLuint dstRowStride; DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, @@ -79,7 +78,7 @@ intelTexSubimage(GLcontext * ctx, intelImage->face, intelImage->level, &dstRowStride, - &dstImageStride); + texImage->ImageOffsets); assert(dstRowStride); diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index 5f82dfa19e6..79d587a1744 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -2,6 +2,7 @@ #include "macros.h" #include "intel_context.h" +#include "intel_batchbuffer.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" @@ -109,6 +110,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) GLuint nr_faces = 0; struct intel_texture_image *firstImage; + GLboolean need_flush = GL_FALSE; + /* We know/require this is true by now: */ assert(intelObj->base.Complete); @@ -155,9 +158,15 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) * leaving the tree alone. */ if (intelObj->mt && - ((intelObj->mt->first_level > intelObj->firstLevel) || - (intelObj->mt->last_level < intelObj->lastLevel) || - (intelObj->mt->internal_format != firstImage->base.InternalFormat))) { + (intelObj->mt->target != intelObj->base.Target || + intelObj->mt->internal_format != firstImage->base.InternalFormat || + intelObj->mt->first_level != intelObj->firstLevel || + intelObj->mt->last_level != intelObj->lastLevel || + intelObj->mt->width0 != firstImage->base.Width || + intelObj->mt->height0 != firstImage->base.Height || + intelObj->mt->depth0 != firstImage->base.Depth || + intelObj->mt->cpp != firstImage->base.TexFormat->TexelBytes || + intelObj->mt->compressed != firstImage->base.IsCompressed)) { intel_miptree_release(intel, &intelObj->mt); } @@ -194,10 +203,14 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (intelObj->mt != intelImage->mt) { copy_image_data_to_tree(intel, intelObj, intelImage); + need_flush = GL_TRUE; } } } + if (need_flush) + intel_batchbuffer_flush(intel->batch); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 213eac895cb..9e4ff112dc3 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -20,6 +20,7 @@ DRIVER_SOURCES = \ intel_pixel_bitmap.c \ intel_state.c \ intel_tex.c \ + intel_tex_layout.c \ intel_tex_validate.c \ brw_aub.c \ brw_aub_playback.c \ @@ -34,17 +35,11 @@ DRIVER_SOURCES = \ brw_context.c \ brw_curbe.c \ brw_draw.c \ - brw_draw_current.c \ brw_draw_upload.c \ brw_eu.c \ brw_eu_debug.c \ brw_eu_emit.c \ brw_eu_util.c \ - brw_exec.c \ - brw_exec_api.c \ - brw_exec_array.c \ - brw_exec_draw.c \ - brw_exec_eval.c \ brw_fallback.c \ brw_gs.c \ brw_gs_emit.c \ @@ -53,9 +48,6 @@ DRIVER_SOURCES = \ brw_metaops.c \ brw_misc_state.c \ brw_program.c \ - brw_save.c \ - brw_save_api.c \ - brw_save_draw.c \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ @@ -92,8 +84,10 @@ C_SOURCES = \ ASM_SOURCES = - +DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_tex_layout.o: ../intel/intel_tex_layout.c + symlinks: diff --git a/src/mesa/drivers/dri/i965/brw_attrib.h b/src/mesa/drivers/dri/i965/brw_attrib.h deleted file mode 100644 index 12659bd1cf0..00000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef BRW_ATTRIB_H -#define BRW_ATTRIB_H - - -/* - * Note: The first attributes match the VERT_ATTRIB_* definitions - * in mtypes.h. However, the tnl module has additional attributes - * for materials, color indexes, edge flags, etc. - */ -/* Although it's nice to use these as bit indexes in a DWORD flag, we - * could manage without if necessary. Another limit currently is the - * number of bits allocated for these numbers in places like vertex - * program instruction formats and register layouts. - */ -enum { - BRW_ATTRIB_POS = 0, - BRW_ATTRIB_WEIGHT = 1, - BRW_ATTRIB_NORMAL = 2, - BRW_ATTRIB_COLOR0 = 3, - BRW_ATTRIB_COLOR1 = 4, - BRW_ATTRIB_FOG = 5, - BRW_ATTRIB_INDEX = 6, - BRW_ATTRIB_EDGEFLAG = 7, - BRW_ATTRIB_TEX0 = 8, - BRW_ATTRIB_TEX1 = 9, - BRW_ATTRIB_TEX2 = 10, - BRW_ATTRIB_TEX3 = 11, - BRW_ATTRIB_TEX4 = 12, - BRW_ATTRIB_TEX5 = 13, - BRW_ATTRIB_TEX6 = 14, - BRW_ATTRIB_TEX7 = 15, - - BRW_ATTRIB_GENERIC0 = 16, /* Not used? */ - BRW_ATTRIB_GENERIC1 = 17, - BRW_ATTRIB_GENERIC2 = 18, - BRW_ATTRIB_GENERIC3 = 19, - BRW_ATTRIB_GENERIC4 = 20, - BRW_ATTRIB_GENERIC5 = 21, - BRW_ATTRIB_GENERIC6 = 22, - BRW_ATTRIB_GENERIC7 = 23, - BRW_ATTRIB_GENERIC8 = 24, - BRW_ATTRIB_GENERIC9 = 25, - BRW_ATTRIB_GENERIC10 = 26, - BRW_ATTRIB_GENERIC11 = 27, - BRW_ATTRIB_GENERIC12 = 28, - BRW_ATTRIB_GENERIC13 = 29, - BRW_ATTRIB_GENERIC14 = 30, - BRW_ATTRIB_GENERIC15 = 31, - - BRW_ATTRIB_MAT_FRONT_AMBIENT = 32, - BRW_ATTRIB_MAT_BACK_AMBIENT = 33, - BRW_ATTRIB_MAT_FRONT_DIFFUSE = 34, - BRW_ATTRIB_MAT_BACK_DIFFUSE = 35, - BRW_ATTRIB_MAT_FRONT_SPECULAR = 36, - BRW_ATTRIB_MAT_BACK_SPECULAR = 37, - BRW_ATTRIB_MAT_FRONT_EMISSION = 38, - BRW_ATTRIB_MAT_BACK_EMISSION = 39, - BRW_ATTRIB_MAT_FRONT_SHININESS = 40, - BRW_ATTRIB_MAT_BACK_SHININESS = 41, - BRW_ATTRIB_MAT_FRONT_INDEXES = 42, - BRW_ATTRIB_MAT_BACK_INDEXES = 43, - - BRW_ATTRIB_MAX = 44 -} ; - -#define BRW_ATTRIB_FIRST_MATERIAL BRW_ATTRIB_MAT_FRONT_AMBIENT -#define BRW_ATTRIB_LAST_MATERIAL BRW_ATTRIB_MAT_BACK_INDEXES - -#define BRW_MAX_COPIED_VERTS 3 - - -static inline GLuint64EXT brw_translate_inputs( GLboolean vp_enabled, - GLuint mesa_inputs ) -{ - GLuint64EXT inputs = mesa_inputs; - if (vp_enabled) - return inputs; - else - return (inputs & 0xffff) | ((inputs & 0xffff0000) << 16); -} - - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h b/src/mesa/drivers/dri/i965/brw_attrib_tmp.h deleted file mode 100644 index 3089bd6cac2..00000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h +++ /dev/null @@ -1,485 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 ) -#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) -#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) -#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) - -#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 ) -#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) -#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) -#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) - -#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] ) - -static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(TexCoord1f)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY TAG(Color3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(Color4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR1, v ); -} - - -static void GLAPIENTRY TAG(EdgeFlag)( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - -static void GLAPIENTRY TAG(Indexf)( GLfloat f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_INDEX, f ); -} - -static void GLAPIENTRY TAG(Indexfv)( const GLfloat *f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_INDEX, f ); -} - - -static void GLAPIENTRY TAG(MultiTexCoord1f)( GLenum target, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1F( attr, x ); -} - -static void GLAPIENTRY TAG(MultiTexCoord1fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2f)( GLenum target, GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3F( attr, x, y, z ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4F( attr, x, y, z, w ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4FV( attr, v ); -} - - -static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1F(0, x); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1F(BRW_ATTRIB_GENERIC0 + index, x); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2F(0, x, y); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2F(BRW_ATTRIB_GENERIC0 + index, x, y); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3F(0, x, y, z); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3F(BRW_ATTRIB_GENERIC0 + index, x, y, z); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4F(0, x, y, z, w); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4F(BRW_ATTRIB_GENERIC0 + index, x, y, z, w); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - - -/* Although we don't export NV_vertex_program, these entrypoints are - * used by the display list and other code specifically because of - * their property of aliasing with other attributes. - */ -static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1F(index, x); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2F(index, x, y); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3F(index, x, y, z); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4F(index, x, y, z, w); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4FV(index, v); -} - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* Colormaterial conflicts are dealt with later. - */ -static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - switch (pname) { - case GL_EMISSION: - MAT( BRW_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( BRW_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( BRW_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( BRW_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - ERROR(); - return; - } -} - - -#undef ATTR1FV -#undef ATTR2FV -#undef ATTR3FV -#undef ATTR4FV - -#undef ATTR1F -#undef ATTR2F -#undef ATTR3F -#undef ATTR4F - -#undef MAT -#undef MAT_ATTR diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 0e8591aaa8d..3bec153075a 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -62,6 +62,8 @@ static void compile_clip_prog( struct brw_context *brw, */ brw_init_compile(&c.func); + c.func.single_program_flow = 1; + c.key = *key; diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index c3967c8c614..49b2770a514 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -116,7 +116,7 @@ struct brw_clip_compile { GLuint last_mrf; GLuint header_position_offset; - GLuint offset[BRW_ATTRIB_MAX]; + GLuint offset[VERT_ATTRIB_MAX]; }; #define ATTR_SIZE (4*4) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index bc422c1a50b..6faee65542b 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -34,8 +34,6 @@ #include "brw_aub.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_vs.h" #include "imports.h" #include "intel_tex.h" @@ -158,12 +156,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw_FrameBufferTexInit( brw ); - /* Hook our functions into exec and compile dispatch tables. Only - * fallback on out-of-memory situations. - */ - brw_exec_init( ctx ); - brw_save_init( ctx ); - { const char *filename = getenv("INTEL_REPLAY"); if (filename) { diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index cac4d86d3ab..08fdc545205 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -36,7 +36,6 @@ #include "intel_context.h" #include "brw_structs.h" #include "imports.h" -#include "brw_attrib.h" /* Glossary: @@ -215,7 +214,7 @@ struct brw_vs_prog_data { GLuint total_grf; GLuint outputs_written; - GLuint64EXT inputs_read; + GLuint inputs_read; /* Used for calculating urb partitions: */ @@ -382,10 +381,10 @@ struct brw_cached_batch_item { -/* Protect against a future where BRW_ATTRIB_MAX > 32. Wouldn't life +/* Protect against a future where VERT_ATTRIB_MAX > 32. Wouldn't life * be easier if C allowed arrays of packed elements? */ -#define ATTRIB_BIT_DWORDS ((BRW_ATTRIB_MAX+31)/32) +#define ATTRIB_BIT_DWORDS ((VERT_ATTRIB_MAX+31)/32) struct brw_vertex_element { const struct gl_client_array *glarray; @@ -401,8 +400,8 @@ struct brw_vertex_element { struct brw_vertex_info { - GLuint64EXT varying; /* varying:1[BRW_ATTRIB_MAX] */ - GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[BRW_ATTRIB_MAX] */ + GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */ + GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */ }; @@ -449,14 +448,13 @@ struct brw_context struct brw_cached_batch_item *cached_batch_items; struct { - /* Fallback values for inputs not supplied: - */ - struct gl_client_array current_values[BRW_ATTRIB_MAX]; /* Arrays with buffer objects to copy non-bufferobj arrays into * for upload: */ - struct gl_client_array vbo_array[BRW_ATTRIB_MAX]; + struct gl_client_array vbo_array[VERT_ATTRIB_MAX]; + + struct brw_vertex_element inputs[VERT_ATTRIB_MAX]; #define BRW_NR_UPLOAD_BUFS 17 #define BRW_UPLOAD_INIT_SIZE (128*1024) @@ -469,11 +467,6 @@ struct brw_context GLuint wrap; } upload; - /* Currenly bound arrays, including fallbacks to current_values - * above: - */ - struct brw_vertex_element inputs[BRW_ATTRIB_MAX]; - /* Summary of size and varying of active arrays, so we can check * for changes to this state: */ @@ -505,8 +498,8 @@ struct brw_context /* Active vertex program: */ - struct gl_vertex_program *vertex_program; - struct gl_fragment_program *fragment_program; + const struct gl_vertex_program *vertex_program; + const struct gl_fragment_program *fragment_program; /* For populating the gtt: diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 471fda9f7ef..092c6bafc2d 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -45,7 +44,8 @@ #include "intel_batchbuffer.h" #include "intel_buffer_objects.h" - +#include "tnl/tnl.h" +#include "vbo/vbo_context.h" @@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw, static void brw_emit_prim( struct brw_context *brw, - const struct brw_draw_prim *prim ) + const struct _mesa_prim *prim ) { struct brw_3d_primitive prim_packet; @@ -170,34 +170,9 @@ static void brw_emit_prim( struct brw_context *brw, } } - - -static void update_current_size( struct gl_client_array *array) -{ - const GLfloat *ptr = (const GLfloat *)array->Ptr; - - assert(array->StrideB == 0); - assert(array->Type == GL_FLOAT || array->Type == GL_UNSIGNED_BYTE); - - if (ptr[3] != 1.0) - array->Size = 4; - else if (ptr[2] != 0.0) - array->Size = 3; - else if (ptr[1] != 0.0) - array->Size = 2; - else - array->Size = 1; -} - - - -/* Fill in any gaps in passed arrays with pointers to current - * attributes: - */ static void brw_merge_inputs( struct brw_context *brw, const struct gl_client_array *arrays[]) { - struct gl_client_array *current_values = brw->vb.current_values; struct brw_vertex_element *inputs = brw->vb.inputs; struct brw_vertex_info old = brw->vb.info; GLuint i; @@ -205,19 +180,16 @@ static void brw_merge_inputs( struct brw_context *brw, memset(inputs, 0, sizeof(*inputs)); memset(&brw->vb.info, 0, sizeof(brw->vb.info)); - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - if (arrays[i] && arrays[i]->Enabled) - { - brw->vb.inputs[i].glarray = arrays[i]; - brw->vb.info.varying |= (GLuint64EXT) 1 << i; - } - else - { - brw->vb.inputs[i].glarray = ¤t_values[i]; - update_current_size(¤t_values[i]); - } + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + brw->vb.inputs[i].glarray = arrays[i]; + + /* XXX: metaops passes null arrays */ + if (arrays[i]) { + if (arrays[i]->StrideB != 0) + brw->vb.info.varying |= 1 << i; - brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + } } /* Raise statechanges if input sizes and varying have changed: @@ -229,8 +201,11 @@ static void brw_merge_inputs( struct brw_context *brw, brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } +/* XXX: could split the primitive list to fallback only on the + * non-conformant primitives. + */ static GLboolean check_fallbacks( struct brw_context *brw, - const struct brw_draw_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims ) { GLuint i; @@ -281,15 +256,16 @@ static GLboolean check_fallbacks( struct brw_context *brw, return GL_FALSE; } - +/* May fail if out of video memory for texture or vbo upload, or on + * fallback conditions. + */ static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims, - const struct brw_draw_index_buffer *ib, + const struct _mesa_index_buffer *ib, GLuint min_index, - GLuint max_index, - GLuint flags ) + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); struct brw_context *brw = brw_context(ctx); @@ -298,11 +274,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, if (ctx->NewState) _mesa_update_state( ctx ); - + /* Bind all inputs, derive varying and size information: */ brw_merge_inputs( brw, arrays ); - + /* Have to validate state quite late. Will rebuild tnl_program, * which depends on varying information. * @@ -319,10 +295,6 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, } { - assert(intel->locked); - - - /* Set the first primitive early, ahead of validate_state: */ brw_set_prim(brw, prim[0].mode); @@ -411,44 +383,88 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, return retval; } +static GLboolean brw_need_rebase( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_index_buffer *ib, + GLuint min_index ) +{ + if (min_index == 0) + return GL_FALSE; -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, - GLuint nr_prims, - const struct brw_draw_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint flags ) + if (ib) { + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } + else { + /* Hmm. This isn't quite what I wanted. BRW can actually + * handle the mixed case well enough that we shouldn't need to + * rebase. However, it's probably not very common, nor hugely + * expensive to do it this way: + */ + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } +} + + +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); GLboolean retval; - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + /* Decide if we want to rebase. If so we end up recursing once + * only into this function. + */ + if (brw_need_rebase( ctx, arrays, ib, min_index )) { + vbo_rebase_prims( ctx, arrays, + prim, nr_prims, + ib, min_index, max_index, + brw_draw_prims ); + + return; + } - - if (!retval && bmError(intel)) { - DBG("retrying\n"); - /* This looks like out-of-memory but potentially we have - * situation where there is enough memory but it has become - * fragmented. Clear out all heaps and start from scratch by - * faking a contended lock event: (done elsewhere) - */ + /* Make a first attempt at drawing: + */ + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + + /* This looks like out-of-memory but potentially we have + * situation where there is enough memory but it has become + * fragmented. Clear out all heaps and start from scratch by + * faking a contended lock event: (done elsewhere) + */ + if (!retval && !intel->Fallback && bmError(intel)) { + DBG("retrying\n"); /* Then try a second time only to upload textures and draw the * primitives: */ - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + } + + /* Otherwise, we really are out of memory. Pass the drawing + * command to the software tnl module and which will in turn call + * swrast to do the drawing. + */ + if (!retval) { + _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { intelFinish( &intel->ctx ); intel->aub_wrap = 1; } - - - return retval; } @@ -461,21 +477,25 @@ static void brw_invalidate_vbo_cb( struct intel_context *intel, void *ptr ) void brw_draw_init( struct brw_context *brw ) { GLcontext *ctx = &brw->intel.ctx; + struct vbo_context *vbo = vbo_context(ctx); GLuint i; + /* Register our drawing function: + */ + vbo->draw_prims = brw_draw_prims; + brw->vb.upload.size = BRW_UPLOAD_INIT_SIZE; for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) { brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - /* XXX: Set these to no-backing-store + /* NOTE: These are set to no-backing-store. */ bmBufferSetInvalidateCB(&brw->intel, intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])), brw_invalidate_vbo_cb, &brw->intel, GL_TRUE); - } ctx->Driver.BufferData( ctx, @@ -484,9 +504,6 @@ void brw_draw_init( struct brw_context *brw ) NULL, GL_DYNAMIC_DRAW_ARB, brw->vb.upload.vbo[0] ); - - - brw_init_current_values(ctx, brw->vb.current_values); } void brw_draw_destroy( struct brw_context *brw ) diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index 92640bf725b..0f7b7383102 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -29,44 +29,18 @@ #define BRW_DRAW_H #include "mtypes.h" /* for GLcontext... */ -#include "brw_attrib.h" +#include "vbo/vbo.h" struct brw_context; -struct brw_draw_prim { - GLuint mode:8; - GLuint indexed:1; - GLuint begin:1; - GLuint end:1; - GLuint weak:1; - GLuint pad:20; - GLuint start; - GLuint count; -}; - -struct brw_draw_index_buffer { - GLuint count; - GLenum type; - struct gl_buffer_object *obj; - const void *ptr; - GLuint rebase; -}; - - -#define BRW_DRAW_SORTED 0x1 -#define BRW_DRAW_ALL_INTERLEAVED 0x2 -#define BRW_DRAW_NON_INTERLEAVED 0x4 -#define BRW_DRAW_LOCKED 0x8 - -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct brw_draw_prim *prims, - GLuint nr_prims, - const struct brw_draw_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint flags ); +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); @@ -80,25 +54,12 @@ void brw_init_current_values(GLcontext *ctx, /* brw_draw_upload.c */ void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer); + const struct _mesa_index_buffer *index_buffer); GLboolean brw_upload_vertices( struct brw_context *brw, GLuint min_index, GLuint max_index ); -/* Helpers for save, exec. Should probably have their own file: - */ -struct brw_exec_context; -struct brw_save_context; - -struct brw_exec_save { - struct brw_exec_context *exec; - struct brw_save_context *save; -}; - -/* Doesn't really belong here: - */ -#define IMM_CONTEXT(ctx) ((struct brw_exec_save *)((ctx)->swtnl_im)) #endif diff --git a/src/mesa/drivers/dri/i965/brw_draw_current.c b/src/mesa/drivers/dri/i965/brw_draw_current.c deleted file mode 100644 index 98d930738e5..00000000000 --- a/src/mesa/drivers/dri/i965/brw_draw_current.c +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include <stdlib.h> - -#include "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "enums.h" - -#include "brw_context.h" -#include "brw_draw.h" - -#include "bufmgr.h" -#include "intel_buffer_objects.h" - - -void brw_init_current_values(GLcontext *ctx, - struct gl_client_array *arrays) -{ - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - /* Set up a constant (StrideB == 0) array for each current - * attribute: - */ - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - struct gl_client_array *cl = &arrays[i]; - - switch (i) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - case BRW_ATTRIB_MAT_BACK_SHININESS: - case BRW_ATTRIB_INDEX: - case BRW_ATTRIB_EDGEFLAG: - cl->Size = 1; - break; - case BRW_ATTRIB_MAT_FRONT_INDEXES: - case BRW_ATTRIB_MAT_BACK_INDEXES: - cl->Size = 3; - break; - default: - /* This is fixed for the material attributes, for others will - * be determined at runtime: - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - cl->Size = 4; - else - cl->Size = 1; - break; - } - - switch (i) { - case BRW_ATTRIB_EDGEFLAG: - cl->Type = GL_UNSIGNED_BYTE; - cl->Ptr = (const void *)&ctx->Current.EdgeFlag; - break; - case BRW_ATTRIB_INDEX: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)&ctx->Current.Index; - break; - default: - cl->Type = GL_FLOAT; - if (i < BRW_ATTRIB_FIRST_MATERIAL) - cl->Ptr = (const void *)ctx->Current.Attrib[i]; - else - cl->Ptr = (const void *)ctx->Light.Material.Attrib[i - BRW_ATTRIB_FIRST_MATERIAL]; - break; - } - - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->Flags = 0; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 57ee294f0cf..6150cac4aa3 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -310,7 +309,6 @@ copy_array_to_vbo_array( struct brw_context *brw, GLuint i, const struct gl_client_array *array, GLuint element_size, - GLuint min_index, GLuint count) { GLcontext *ctx = &brw->intel.ctx; @@ -337,7 +335,6 @@ copy_array_to_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; /* ? */ - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = vbo; { @@ -349,7 +346,7 @@ copy_array_to_vbo_array( struct brw_context *brw, map += offset; copy_strided_array( map, - array->Ptr + min_index * array->StrideB, + array->Ptr, element_size, array->StrideB, count); @@ -380,7 +377,6 @@ interleaved_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = uploaded_array->BufferObj; return vbo_array; @@ -393,17 +389,17 @@ GLboolean brw_upload_vertices( struct brw_context *brw, { GLcontext *ctx = &brw->intel.ctx; struct intel_context *intel = intel_context(ctx); - GLuint64EXT tmp = brw->vs.prog_data->inputs_read; + GLuint tmp = brw->vs.prog_data->inputs_read; struct brw_vertex_element_packet vep; struct brw_array_state vbp; GLuint i; const void *ptr = NULL; GLuint interleave = 0; - struct brw_vertex_element *enabled[BRW_ATTRIB_MAX]; + struct brw_vertex_element *enabled[VERT_ATTRIB_MAX]; GLuint nr_enabled = 0; - struct brw_vertex_element *upload[BRW_ATTRIB_MAX]; + struct brw_vertex_element *upload[VERT_ATTRIB_MAX]; GLuint nr_uploads = 0; @@ -412,17 +408,19 @@ GLboolean brw_upload_vertices( struct brw_context *brw, /* First build an array of pointers to ve's in vb.inputs_read */ + if (0) + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); while (tmp) { - GLuint i = ffsll(tmp)-1; + GLuint i = _mesa_ffsll(tmp)-1; struct brw_vertex_element *input = &brw->vb.inputs[i]; - tmp &= ~((GLuint64EXT)1<<i); + tmp &= ~(1<<i); enabled[nr_enabled++] = input; input->index = i; input->element_size = get_size(input->glarray->Type) * input->glarray->Size; - input->count = input->glarray->StrideB ? max_index - min_index : 1; + input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1; if (!input->glarray->BufferObj->Name) { if (i == 0) { @@ -441,10 +439,16 @@ GLboolean brw_upload_vertices( struct brw_context *brw, } upload[nr_uploads++] = input; - input->vbo_rebase_offset = 0; + + /* We rebase drawing to start at element zero only when + * varyings are not in vbos, which means we can end up + * uploading non-varying arrays (stride != 0) when min_index + * is zero. This doesn't matter as the amount to upload is + * the same for these arrays whether the draw call is rebased + * or not - we just have to upload the one element. + */ + assert(min_index == 0 || input->glarray->StrideB == 0); } - else - input->vbo_rebase_offset = min_index * input->glarray->StrideB; } /* Upload interleaved arrays if all uploads are interleaved @@ -457,7 +461,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input0->glarray = copy_array_to_vbo_array(brw, 0, input0->glarray, interleave, - min_index, input0->count); for (i = 1; i < nr_uploads; i++) { @@ -475,7 +478,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input->glarray = copy_array_to_vbo_array(brw, i, input->glarray, input->element_size, - min_index, input->count); } @@ -523,9 +525,9 @@ GLboolean brw_upload_vertices( struct brw_context *brw, vbp.vb[i].vb0.bits.pad = 0; vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA; vbp.vb[i].vb0.bits.vb_index = i; - vbp.vb[i].offset = (GLuint)input->glarray->Ptr + input->vbo_rebase_offset; + vbp.vb[i].offset = (GLuint)input->glarray->Ptr; vbp.vb[i].buffer = array_buffer(input->glarray); - vbp.vb[i].max_index = max_index - min_index; + vbp.vb[i].max_index = max_index; } @@ -566,94 +568,32 @@ static GLuint element_size( GLenum type ) - -static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer, - struct gl_buffer_object **vbo_return, - GLuint *offset_return ) +void brw_upload_indices( struct brw_context *brw, + const struct _mesa_index_buffer *index_buffer ) { GLcontext *ctx = &brw->intel.ctx; - GLuint min_index = index_buffer->rebase; - const void *indices = index_buffer->ptr; - GLsizei count = index_buffer->count; - GLenum type = index_buffer->type; - GLuint size = element_size(type) * count; - struct gl_buffer_object *bufferobj; - GLuint offset; - GLuint i; - - get_space(brw, size, &bufferobj, &offset); + struct intel_context *intel = &brw->intel; + GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; + struct gl_buffer_object *bufferobj = index_buffer->obj; + GLuint offset = (GLuint)index_buffer->ptr; - *vbo_return = bufferobj; - *offset_return = offset; + /* Turn into a proper VBO: + */ + if (!bufferobj->Name) { + + /* Get new bufferobj, offset: + */ + get_space(brw, ib_size, &bufferobj, &offset); - if (min_index == 0) { /* Straight upload */ ctx->Driver.BufferSubData( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, offset, - size, - indices, + ib_size, + index_buffer->ptr, bufferobj); } - else { - void *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_DRAW_ARB, - bufferobj); - - map += offset; - - switch (type) { - case GL_UNSIGNED_INT: { - GLuint *ui_map = (GLuint *)map; - const GLuint *ui_indices = (const GLuint *)indices; - - for (i = 0; i < count; i++) - ui_map[i] = ui_indices[i] - min_index; - break; - } - case GL_UNSIGNED_SHORT: { - GLushort *us_map = (GLushort *)map; - const GLushort *us_indices = (const GLushort *)indices; - - for (i = 0; i < count; i++) - us_map[i] = us_indices[i] - min_index; - break; - } - case GL_UNSIGNED_BYTE: { - GLubyte *ub_map = (GLubyte *)map; - const GLubyte *ub_indices = (const GLubyte *)indices; - - for (i = 0; i < count; i++) - ub_map[i] = ub_indices[i] - min_index; - break; - } - } - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - bufferobj); - - } -} - - - -void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer) -{ - struct intel_context *intel = &brw->intel; - GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; - struct gl_buffer_object *bufferobj = index_buffer->obj; - GLuint offset = (GLuint)index_buffer->ptr; - - /* Already turned into a proper VBO: - */ - if (!index_buffer->obj->Name) { - rebase_indices_to_vbo_indices(brw, index_buffer, &bufferobj, &offset ); - } /* Emit the indexbuffer packet: */ diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 1afa0f816b8..d4dbcf38a7a 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -104,6 +104,7 @@ struct brw_compile { struct brw_instruction *current; GLuint flag_value; + GLboolean single_program_flow; }; diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 6425c91450c..9992b47d8ae 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -464,7 +464,6 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p, return insn; } - /* EU takes the value from the flag register and pushes it onto some * sort of a stack (presumably merging with any flag value already on * the stack). Within an if block, the flags at the top of the stack @@ -482,7 +481,16 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p, */ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_IF); + struct brw_instruction *insn; + + if (p->single_program_flow) { + assert(execute_size == BRW_EXECUTE_1); + + insn = next_insn(p, BRW_OPCODE_ADD); + insn->header.predicate_inverse = 1; + } else { + insn = next_insn(p, BRW_OPCODE_IF); + } /* Override the defaults for this instruction: */ @@ -504,7 +512,13 @@ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size) struct brw_instruction *brw_ELSE(struct brw_compile *p, struct brw_instruction *if_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ELSE); + struct brw_instruction *insn; + + if (p->single_program_flow) { + insn = next_insn(p, BRW_OPCODE_ADD); + } else { + insn = next_insn(p, BRW_OPCODE_ELSE); + } brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); @@ -516,11 +530,17 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, /* Patch the if instruction to point at this instruction. */ - assert(if_insn->header.opcode == BRW_OPCODE_IF); + if (p->single_program_flow) { + assert(if_insn->header.opcode == BRW_OPCODE_ADD); - if_insn->bits3.if_else.jump_count = insn - if_insn; - if_insn->bits3.if_else.pop_count = 1; - if_insn->bits3.if_else.pad0 = 0; + if_insn->bits3.ud = (insn - if_insn + 1) * 16; + } else { + assert(if_insn->header.opcode == BRW_OPCODE_IF); + + if_insn->bits3.if_else.jump_count = insn - if_insn; + if_insn->bits3.if_else.pop_count = 1; + if_insn->bits3.if_else.pad0 = 0; + } return insn; } @@ -528,63 +548,76 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, void brw_ENDIF(struct brw_compile *p, struct brw_instruction *patch_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); + if (p->single_program_flow) { + /* In single program flow mode, there's no need to execute an ENDIF, + * since we don't need to do any stack operations, and if we're executing + * currently, we want to just continue executing. + */ + struct brw_instruction *next = &p->store[p->nr_insn]; - brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src1(insn, brw_imm_d(0x0)); + assert(patch_insn->header.opcode == BRW_OPCODE_ADD); - insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = patch_insn->header.execution_size; - insn->header.mask_control = BRW_MASK_ENABLE; + patch_insn->bits3.ud = (next - patch_insn) * 16; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); - assert(patch_insn->bits3.if_else.jump_count == 0); - - /* Patch the if or else instructions to point at this or the next - * instruction respectively. - */ - if (patch_insn->header.opcode == BRW_OPCODE_IF) { - /* Automagically turn it into an IFF: + brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = patch_insn->header.execution_size; + insn->header.mask_control = BRW_MASK_ENABLE; + + assert(patch_insn->bits3.if_else.jump_count == 0); + + /* Patch the if or else instructions to point at this or the next + * instruction respectively. */ - patch_insn->header.opcode = BRW_OPCODE_IFF; - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; - patch_insn->bits3.if_else.pop_count = 0; - patch_insn->bits3.if_else.pad0 = 0; + if (patch_insn->header.opcode == BRW_OPCODE_IF) { + /* Automagically turn it into an IFF: + */ + patch_insn->header.opcode = BRW_OPCODE_IFF; + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 0; + patch_insn->bits3.if_else.pad0 = 0; + } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 1; + patch_insn->bits3.if_else.pad0 = 0; + } else { + assert(0); + } + /* Also pop item off the stack in the endif instruction: + */ + insn->bits3.if_else.jump_count = 0; + insn->bits3.if_else.pop_count = 1; + insn->bits3.if_else.pad0 = 0; } - else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; - patch_insn->bits3.if_else.pop_count = 1; - patch_insn->bits3.if_else.pad0 = 0; - } - else { - assert(0); - } - - /* Also pop item off the stack in the endif instruction: - */ - insn->bits3.if_else.jump_count = 0; - insn->bits3.if_else.pop_count = 1; - insn->bits3.if_else.pad0 = 0; } /* DO/WHILE loop: */ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); + if (p->single_program_flow) { + return &p->store[p->nr_insn]; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); - /* Override the defaults for this instruction: - */ - brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + /* Override the defaults for this instruction: + */ + brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = execute_size; -/* insn->header.mask_control = BRW_MASK_ENABLE; */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = execute_size; + /* insn->header.mask_control = BRW_MASK_ENABLE; */ - return insn; + return insn; + } } @@ -592,19 +625,31 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) void brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_WHILE); + struct brw_instruction *insn; + + if (p->single_program_flow) + insn = next_insn(p, BRW_OPCODE_ADD); + else + insn = next_insn(p, BRW_OPCODE_WHILE); brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = do_insn->header.execution_size; - assert(do_insn->header.opcode == BRW_OPCODE_DO); - insn->bits3.if_else.jump_count = do_insn - insn; - insn->bits3.if_else.pop_count = 0; - insn->bits3.if_else.pad0 = 0; + if (p->single_program_flow) { + insn->header.execution_size = BRW_EXECUTE_1; + + insn->bits3.d = (do_insn - insn) * 16; + } else { + insn->header.execution_size = do_insn->header.execution_size; + + assert(do_insn->header.opcode == BRW_OPCODE_DO); + insn->bits3.if_else.jump_count = do_insn - insn; + insn->bits3.if_else.pop_count = 0; + insn->bits3.if_else.pad0 = 0; + } /* insn->header.mask_control = BRW_MASK_ENABLE; */ diff --git a/src/mesa/drivers/dri/i965/brw_exec.c b/src/mesa/drivers/dri/i965/brw_exec.c deleted file mode 100644 index fc06c3c3617..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <[email protected]> - */ - - -#include "api_arrayelt.h" -#include "glheader.h" -#include "imports.h" -#include "context.h" -#include "macros.h" -#include "mtypes.h" -#include "dlist.h" -#include "vtxfmt.h" - -#include "brw_exec.h" - - -void brw_exec_init( GLcontext *ctx ) -{ - struct brw_exec_context *exec = CALLOC_STRUCT(brw_exec_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - exec->ctx = ctx; - IMM_CONTEXT(ctx)->exec = exec; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_exec_vtx_init( exec ); - brw_exec_array_init( exec ); - - ctx->Driver.NeedFlush = 0; - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - - exec->eval.recalculate_maps = 1; -} - - -void brw_exec_destroy( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - brw_exec_vtx_destroy( exec ); - brw_exec_array_destroy( exec ); - - if (exec) { - FREE(exec); - IMM_CONTEXT(ctx)->exec = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - -/* Really want to install these callbacks to a central facility to be - * invoked according to the state flags. That will have to wait for a - * mesa rework: - */ -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) - exec->eval.recalculate_maps = 1; - - _ae_invalidate_state(ctx, new_state); -} - - -void brw_exec_wakeup( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); - - /* Assume we haven't been getting state updates either: - */ - brw_exec_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_exec.h b/src/mesa/drivers/dri/i965/brw_exec.h deleted file mode 100644 index f07b4485874..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - * - */ - -#ifndef __BRW_EXEC_H__ -#define __BRW_EXEC_H__ - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -#define BRW_MAX_PRIM 64 - -/* Wierd implementation stuff: - */ -#define BRW_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */ -#define BRW_MAX_ATTR_CODEGEN 16 -#define ERROR_ATTRIB 16 - - - - -struct brw_exec_eval1_map { - struct gl_1d_map *map; - GLuint sz; -}; - -struct brw_exec_eval2_map { - struct gl_2d_map *map; - GLuint sz; -}; - - - -struct brw_exec_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -typedef void (*brw_attrfv_func)( const GLfloat * ); - - -struct brw_exec_context -{ - GLcontext *ctx; - GLvertexformat vtxfmt; - - struct { - struct gl_buffer_object *bufferobj; - GLubyte *buffer_map; - - GLuint vertex_size; - - struct brw_draw_prim prim[BRW_MAX_PRIM]; - GLuint prim_count; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current vertex */ - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ - GLfloat CurrentFloatEdgeFlag; - - GLuint vert_count; - GLuint max_vert; - struct brw_exec_copied_vtx copied; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - - GLfloat *attrptr[BRW_ATTRIB_MAX]; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - } vtx; - - - struct { - GLboolean recalculate_maps; - struct brw_exec_eval1_map map1[BRW_ATTRIB_MAX]; - struct brw_exec_eval2_map map2[BRW_ATTRIB_MAX]; - } eval; - - struct { - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - struct gl_buffer_object *index_obj; - } array; -}; - - - -/* External API: - */ -void brw_exec_init( GLcontext *ctx ); -void brw_exec_destroy( GLcontext *ctx ); -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ); -void brw_exec_wakeup( GLcontext *ctx ); - - -/* Internal functions: - */ -void brw_exec_array_init( struct brw_exec_context *exec ); -void brw_exec_array_destroy( struct brw_exec_context *exec ); - - -void brw_exec_vtx_init( struct brw_exec_context *exec ); -void brw_exec_vtx_destroy( struct brw_exec_context *exec ); -void brw_exec_vtx_flush( struct brw_exec_context *exec ); -void brw_exec_vtx_wrap( struct brw_exec_context *exec ); - -void brw_exec_eval_update( struct brw_exec_context *exec ); - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ); - -void brw_exec_do_EvalCoord1f( struct brw_exec_context *exec, - GLfloat u); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c deleted file mode 100644 index 470fa6f4177..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ /dev/null @@ -1,716 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "vtxfmt.h" -#include "dlist.h" -#include "state.h" -#include "light.h" -#include "api_arrayelt.h" -#include "api_noop.h" -#include "dispatch.h" - -#include "brw_exec.h" - -static void reset_attrfv( struct brw_exec_context *exec ); - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void brw_exec_wrap_buffers( struct brw_exec_context *exec ) -{ - if (exec->vtx.prim_count == 0) { - exec->vtx.copied.nr = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - } - else { - GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; - GLuint last_count; - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - GLint i = exec->vtx.prim_count - 1; - assert(i >= 0); - exec->vtx.prim[i].count = (exec->vtx.vert_count - - exec->vtx.prim[i].start); - } - - last_count = exec->vtx.prim[exec->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (exec->vtx.vert_count) - brw_exec_vtx_flush( exec ); - else { - exec->vtx.prim_count = 0; - exec->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(exec->vtx.prim_count == 0); - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive; - exec->vtx.prim[0].start = 0; - exec->vtx.prim[0].count = 0; - exec->vtx.prim_count++; - - if (exec->vtx.copied.nr == last_count) - exec->vtx.prim[0].begin = last_begin; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - */ -void brw_exec_vtx_wrap( struct brw_exec_context *exec ) -{ - GLfloat *data = exec->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - /* Copy stored stored vertices to start of new list. - */ - assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - _mesa_memcpy( exec->vtx.vbptr, data, - exec->vtx.vertex_size * sizeof(GLfloat)); - exec->vtx.vbptr += exec->vtx.vertex_size; - data += exec->vtx.vertex_size; - exec->vtx.vert_count++; - } - - exec->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void brw_exec_copy_to_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - /* Note: the exec->vtx.current[i] pointers point into the - * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. - */ - COPY_CLEAN_4V(exec->vtx.current[i], - exec->vtx.attrsz[i], - exec->vtx.attrptr[i]); - - /* This triggers rather too much recalculation of Mesa state - * that doesn't get used (eg light positions). - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - } - } - - /* color index is special (it's not a float[4] so COPY_CLEAN_4V above - * will trash adjacent memory!) - */ - if (exec->vtx.attrsz[BRW_ATTRIB_INDEX]) { - ctx->Current.Index = exec->vtx.attrptr[BRW_ATTRIB_INDEX][0]; - } - - /* Edgeflag requires additional treatment: - */ - if (exec->vtx.attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled && - exec->vtx.attrsz[BRW_ATTRIB_COLOR0]) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void brw_exec_copy_from_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* Edgeflag requires additional treatment: - */ - exec->vtx.CurrentFloatEdgeFlag = - (GLfloat)ctx->Current.EdgeFlag; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) - switch (exec->vtx.attrsz[i]) { - case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; - case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; - case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; - case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void brw_exec_wrap_upgrade_vertex( struct brw_exec_context *exec, - GLuint attr, - GLuint newsz ) -{ - GLcontext *ctx = exec->ctx; - GLint lastcount = exec->vtx.vert_count; - GLfloat *tmp; - GLuint oldsz; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - brw_exec_copy_to_current( exec ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - exec->vtx.attrsz[attr] == 0 && - lastcount > 8 && - exec->vtx.vertex_size) { - reset_attrfv( exec ); - } - - /* Fix up sizes: - */ - oldsz = exec->vtx.attrsz[attr]; - exec->vtx.attrsz[attr] = newsz; - - exec->vtx.vertex_size += newsz - oldsz; - exec->vtx.max_vert = BRW_VERT_BUFFER_SIZE / exec->vtx.vertex_size; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = exec->vtx.vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - exec->vtx.attrptr[i] = tmp; - tmp += exec->vtx.attrsz[i]; - } - else - exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - brw_exec_copy_from_current( exec ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (exec->vtx.copied.nr) - { - GLfloat *data = exec->vtx.copied.buffer; - GLfloat *dest = exec->vtx.vbptr; - GLuint j; - - assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (exec->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = exec->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - exec->vtx.vbptr = dest; - exec->vtx.vert_count += exec->vtx.copied.nr; - exec->vtx.copied.nr = 0; - } -} - - -static void brw_exec_fixup_vertex( GLcontext *ctx, - GLuint attr, GLuint sz ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - if (sz > exec->vtx.attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - brw_exec_wrap_upgrade_vertex( exec, attr, sz ); - } - else if (sz < exec->vtx.active_sz[attr]) { - static const GLfloat id[4] = { 0, 0, 0, 1 }; - - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++) - exec->vtx.attrptr[attr][i-1] = id[i-1]; - } - - exec->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - - - -/* - */ -#define ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \ - \ - if (exec->vtx.active_sz[A] != N) \ - brw_exec_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = exec->vtx.attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < exec->vtx.vertex_size; i++) \ - exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ - \ - exec->vtx.vbptr += exec->vtx.vertex_size; \ - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ - \ - if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ - brw_exec_vtx_wrap( exec ); \ - } \ -} while (0) - - -#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) -#define TAG(x) brw_##x - -#include "brw_attrib_tmp.h" - - - - - -/* Eval - */ -static void GLAPIENTRY brw_exec_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map1[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); - } - } - - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord1f( exec, u ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map2[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (exec->vtx.active_sz[BRW_ATTRIB_NORMAL] != 3) - brw_exec_fixup_vertex( ctx, BRW_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord2f( exec, u, v ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord1fv( const GLfloat *u ) -{ - brw_exec_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY brw_exec_EvalCoord2fv( const GLfloat *u ) -{ - brw_exec_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY brw_exec_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - brw_exec_EvalCoord1f( u ); -} - - -static void GLAPIENTRY brw_exec_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - brw_exec_EvalCoord2f( u, v ); -} - - -/* Build a list of primitives on the fly. Keep - * ctx->Driver.CurrentExecPrimitive uptodate as well. - */ -static void GLAPIENTRY brw_exec_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - if (ctx->NewState) { - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) - brw_exec_FlushVertices( ctx, ~0 ); - - i = exec->vtx.prim_count++; - exec->vtx.prim[i].mode = mode; - exec->vtx.prim[i].begin = 1; - exec->vtx.prim[i].end = 0; - exec->vtx.prim[i].indexed = 0; - exec->vtx.prim[i].weak = 0; - exec->vtx.prim[i].pad = 0; - exec->vtx.prim[i].start = exec->vtx.vert_count; - exec->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - -} - -static void GLAPIENTRY brw_exec_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int idx = exec->vtx.vert_count; - int i = exec->vtx.prim_count - 1; - - exec->vtx.prim[i].end = 1; - exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - - if (exec->vtx.prim_count == BRW_MAX_PRIM) - brw_exec_vtx_flush( exec ); - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); -} - - -static void brw_exec_vtxfmt_init( struct brw_exec_context *exec ) -{ - GLvertexformat *vfmt = &exec->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = brw_exec_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->End = brw_exec_End; - vfmt->EvalCoord1f = brw_exec_EvalCoord1f; - vfmt->EvalCoord1fv = brw_exec_EvalCoord1fv; - vfmt->EvalCoord2f = brw_exec_EvalCoord2f; - vfmt->EvalCoord2fv = brw_exec_EvalCoord2fv; - vfmt->EvalPoint1 = brw_exec_EvalPoint1; - vfmt->EvalPoint2 = brw_exec_EvalPoint2; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; - - - /* from attrib_tmp.h: - */ - vfmt->Color3f = brw_Color3f; - vfmt->Color3fv = brw_Color3fv; - vfmt->Color4f = brw_Color4f; - vfmt->Color4fv = brw_Color4fv; - vfmt->FogCoordfEXT = brw_FogCoordfEXT; - vfmt->FogCoordfvEXT = brw_FogCoordfvEXT; - vfmt->MultiTexCoord1fARB = brw_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = brw_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = brw_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = brw_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = brw_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = brw_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = brw_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = brw_MultiTexCoord4fv; - vfmt->Normal3f = brw_Normal3f; - vfmt->Normal3fv = brw_Normal3fv; - vfmt->SecondaryColor3fEXT = brw_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = brw_SecondaryColor3fvEXT; - vfmt->TexCoord1f = brw_TexCoord1f; - vfmt->TexCoord1fv = brw_TexCoord1fv; - vfmt->TexCoord2f = brw_TexCoord2f; - vfmt->TexCoord2fv = brw_TexCoord2fv; - vfmt->TexCoord3f = brw_TexCoord3f; - vfmt->TexCoord3fv = brw_TexCoord3fv; - vfmt->TexCoord4f = brw_TexCoord4f; - vfmt->TexCoord4fv = brw_TexCoord4fv; - vfmt->Vertex2f = brw_Vertex2f; - vfmt->Vertex2fv = brw_Vertex2fv; - vfmt->Vertex3f = brw_Vertex3f; - vfmt->Vertex3fv = brw_Vertex3fv; - vfmt->Vertex4f = brw_Vertex4f; - vfmt->Vertex4fv = brw_Vertex4fv; - - vfmt->VertexAttrib1fARB = brw_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = brw_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = brw_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = brw_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = brw_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = brw_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = brw_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = brw_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = brw_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = brw_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = brw_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = brw_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = brw_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = brw_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = brw_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = brw_VertexAttrib4fvNV; - - vfmt->Materialfv = brw_Materialfv; - - vfmt->EdgeFlag = brw_EdgeFlag; - vfmt->Indexf = brw_Indexf; - vfmt->Indexfv = brw_Indexfv; - -} - - -static void brw_exec_current_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* setup the pointers for the typical 16 vertex attributes */ - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) - exec->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - exec->vtx.current[BRW_ATTRIB_FIRST_MATERIAL + i] = - ctx->Light.Material.Attrib[i]; - - exec->vtx.current[BRW_ATTRIB_INDEX] = &ctx->Current.Index; - exec->vtx.current[BRW_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; -} - -void brw_exec_vtx_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - /* Allocate a buffer object. Will just reuse this object - * continuously. - */ - exec->vtx.bufferobj = ctx->Array.NullBufferObj; - exec->vtx.buffer_map = ALIGN_MALLOC(BRW_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); - - brw_exec_current_init( exec ); - brw_exec_vtxfmt_init( exec ); - - /* Hook our functions into the dispatch table. - */ - _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - exec->vtx.inputs[i] = &exec->vtx.arrays[i]; - } - - exec->vtx.vertex_size = 0; -} - - -void brw_exec_vtx_destroy( struct brw_exec_context *exec ) -{ - if (exec->vtx.buffer_map) { - ALIGN_FREE(exec->vtx.buffer_map); - exec->vtx.buffer_map = NULL; - } -} - - -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) - return; - - if (exec->vtx.vert_count) { - brw_exec_vtx_flush( exec ); - } - - if (exec->vtx.vertex_size) { - brw_exec_copy_to_current( exec ); - reset_attrfv( exec ); - } - - exec->ctx->Driver.NeedFlush = 0; -} - - -static void reset_attrfv( struct brw_exec_context *exec ) -{ - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - } - - exec->vtx.vertex_size = 0; -} - diff --git a/src/mesa/drivers/dri/i965/brw_exec_array.c b/src/mesa/drivers/dri/i965/brw_exec_array.c deleted file mode 100644 index ca19a198374..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_array.c +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "api_noop.h" -#include "dispatch.h" - -#include "brw_attrib.h" -#include "brw_draw.h" -#include "brw_exec.h" -#include "brw_fallback.h" - -static GLuint get_max_index( GLuint count, GLuint type, - const GLvoid *indices ) -{ - GLint i; - - /* Compute max element. This is only needed for upload of non-VBO, - * non-constant data elements. - * - * XXX: Postpone this calculation until it is known that it is - * needed. Otherwise could scan this pointlessly in the all-vbo - * case. - */ - switch(type) { - case GL_UNSIGNED_INT: { - const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - for (i = 0; i < count; i++) - if (ui_indices[i] > max_ui) - max_ui = ui_indices[i]; - return max_ui; - } - case GL_UNSIGNED_SHORT: { - const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - for (i = 0; i < count; i++) - if (us_indices[i] > max_us) - max_us = us_indices[i]; - return max_us; - } - case GL_UNSIGNED_BYTE: { - const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - for (i = 0; i < count; i++) - if (ub_indices[i] > max_ub) - max_ub = ub_indices[i]; - return max_ub; - } - default: - return 0; - } -} - - - - -/*********************************************************************** - * API functions. - */ - -static void GLAPIENTRY -brw_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_prim prim[1]; - GLboolean ok; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - - if (exec->array.inputs[0]->BufferObj->Name) { - /* Use vertex attribute as a hint to tell us if we expect all - * arrays to be in VBO's and if so, don't worry about avoiding - * the upload of elements < start. - */ - prim[0].mode = mode; - prim[0].start = start; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count, 0 ); - } - else { - /* If not using VBO's, we don't want to upload any more elements - * than necessary from the arrays as they will not be valid next - * time the application tries to draw with them. - */ - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count, 0 ); - } - - if (!ok) { - brw_fallback(ctx); - CALL_DrawArrays(ctx->Exec, ( mode, start, count )); - brw_unfallback(ctx); - } -} - - - -static void GLAPIENTRY -brw_exec_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_index_buffer ib; - struct brw_draw_prim prim[1]; - - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - ib.count = count; - ib.type = type; - ib.obj = ctx->Array.ElementArrayBufferObj; - ib.ptr = indices; - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* Use the fact that indices are in a VBO as a hint that the - * program has put all the arrays in VBO's and we don't have to - * worry about performance implications of start > 0. - * - * XXX: consider passing start as min_index to draw_prims instead. - */ - ib.rebase = 0; - } - else { - ib.rebase = start; - } - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 1; - - if (!brw_draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1, 0 )) { - brw_fallback(ctx); - CALL_DrawRangeElements(ctx->Exec, (mode, start, end, count, type, indices)); - brw_unfallback(ctx); - } -} - - -static void GLAPIENTRY -brw_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint max_index; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - if (ctx->Array.ElementArrayBufferObj->Name) { - const GLvoid *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, - ctx->Array.ElementArrayBufferObj); - - max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - } - else { - max_index = get_max_index(count, type, indices); - } - - brw_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); -} - - -/*********************************************************************** - * Initialization - */ - - -static void init_arrays( GLcontext *ctx, - const struct gl_client_array *arrays[] ) -{ - struct gl_array_object *obj = ctx->Array.ArrayObj; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - arrays[BRW_ATTRIB_POS] = &obj->Vertex; - arrays[BRW_ATTRIB_NORMAL] = &obj->Normal; - arrays[BRW_ATTRIB_COLOR0] = &obj->Color; - arrays[BRW_ATTRIB_COLOR1] = &obj->SecondaryColor; - arrays[BRW_ATTRIB_FOG] = &obj->FogCoord; - - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) - arrays[BRW_ATTRIB_TEX0 + i] = &obj->TexCoord[i]; - - arrays[BRW_ATTRIB_INDEX] = &obj->Index; - arrays[BRW_ATTRIB_EDGEFLAG] = &obj->EdgeFlag; - - for (i = BRW_ATTRIB_GENERIC0; i <= BRW_ATTRIB_GENERIC15; i++) - arrays[i] = &obj->VertexAttrib[i - BRW_ATTRIB_GENERIC0]; -} - - - - -void brw_exec_array_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - init_arrays(ctx, exec->array.inputs); - -#if 1 - exec->vtxfmt.DrawArrays = brw_exec_DrawArrays; - exec->vtxfmt.DrawElements = brw_exec_DrawElements; - exec->vtxfmt.DrawRangeElements = brw_exec_DrawRangeElements; -#else - exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays; - exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; - exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; -#endif - - exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); -} - - -void brw_exec_array_destroy( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj); -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_draw.c b/src/mesa/drivers/dri/i965/brw_exec_draw.c deleted file mode 100644 index 62bda9845b9..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_draw.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "context.h" -#include "enums.h" -#include "state.h" -#include "macros.h" - -#include "brw_exec.h" -#include "brw_draw.h" -#include "brw_fallback.h" - - -static void brw_exec_debug_verts( struct brw_exec_context *exec ) -{ - GLuint count = exec->vtx.vert_count; - GLuint i; - - _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n", - __FUNCTION__, - count, - exec->vtx.prim_count, - exec->vtx.vertex_size); - - for (i = 0 ; i < exec->vtx.prim_count ; i++) { - struct brw_draw_prim *prim = &exec->vtx.prim[i]; - _mesa_printf(" prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - prim->begin ? "BEGIN" : "(wrap)", - prim->end ? "END" : "(wrap)"); - } -} - - -/* - * NOTE: Need to have calculated primitives by this point -- do it on the fly. - * NOTE: Old 'parity' issue is gone. - */ -static GLuint brw_copy_vertices( struct brw_exec_context *exec ) -{ - GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count; - GLuint ovf, i; - GLuint sz = exec->vtx.vertex_size; - GLfloat *dst = exec->vtx.copied.buffer; - GLfloat *src = ((GLfloat *)exec->vtx.buffer_map + - exec->vtx.prim[exec->vtx.prim_count-1].start * - exec->vtx.vertex_size); - - - switch( exec->ctx->Driver.CurrentExecPrimitive ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_POLYGON+1: - return 0; - default: - assert(0); - return 0; - } -} - - -/* TODO: populate these as the vertex is defined: - */ -static void brw_exec_bind_arrays( struct brw_exec_context *exec ) -{ - struct gl_client_array *arrays = exec->vtx.arrays; - GLuint count = exec->vtx.vert_count; - GLubyte *data = exec->vtx.buffer_map; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - /* Make all active attributes (including edgeflag) available as - * arrays of floats. - */ - for (attr = 0; attr < BRW_ATTRIB_MAX ; attr++) { - if (exec->vtx.attrsz[attr]) { - arrays[attr].Ptr = (void *)data; - arrays[attr].Size = exec->vtx.attrsz[attr]; - arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */ - arrays[attr]._MaxElement = count; /* ??? */ - - data += exec->vtx.attrsz[attr] * sizeof(GLfloat); - } - } -} - - -static -void brw_exec_loopback_vertex_list( GLcontext *ctx, - struct brw_exec_context *exec ) -{ - const GLfloat *buffer = (const GLfloat *)exec->vtx.buffer_map; - - brw_fallback(ctx); - - brw_loopback_vertex_list( ctx, - buffer, - exec->vtx.attrsz, - exec->vtx.prim, - exec->vtx.prim_count, - 0, /* XXX - copied.nr */ - exec->vtx.vertex_size); - - - brw_unfallback(ctx); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_exec_vtx_flush( struct brw_exec_context *exec ) -{ - if (0) - brw_exec_debug_verts( exec ); - - - if (exec->vtx.prim_count && - exec->vtx.vert_count) { - - exec->vtx.copied.nr = brw_copy_vertices( exec ); - - if (exec->vtx.copied.nr != exec->vtx.vert_count) { - GLcontext *ctx = exec->ctx; - - brw_exec_bind_arrays( exec ); - - - if (!brw_draw_prims( ctx, - exec->vtx.inputs, - exec->vtx.prim, - exec->vtx.prim_count, - NULL, - 0, - exec->vtx.vert_count, - 0 )) { - /* Fallback path: - */ - brw_exec_loopback_vertex_list(ctx, exec); - } - } - } - - exec->vtx.prim_count = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_eval.c b/src/mesa/drivers/dri/i965/brw_exec_eval.c deleted file mode 100644 index 9dbeb1b58e4..00000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_eval.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "api_eval.h" -#include "context.h" -#include "macros.h" -#include "math/m_eval.h" -#include "brw_exec.h" -#include "dispatch.h" - - -static void clear_active_eval1( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map1[attr].map = NULL; -} - -static void clear_active_eval2( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map2[attr].map = NULL; -} - -static void set_active_eval1( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_1d_map *map ) -{ - if (!exec->eval.map1[attr].map) { - exec->eval.map1[attr].map = map; - exec->eval.map1[attr].sz = dim; - } -} - -static void set_active_eval2( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_2d_map *map ) -{ - if (!exec->eval.map2[attr].map) { - exec->eval.map2[attr].map = map; - exec->eval.map2[attr].sz = dim; - } -} - -void brw_exec_eval_update( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint attr; - - /* Vertex program maps have priority over conventional attribs */ - - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - clear_active_eval1( exec, attr ); - clear_active_eval2( exec, attr ); - } - - /* _NEW_PROGRAM */ - if (ctx->VertexProgram._Enabled) { - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - /* _NEW_EVAL */ - if (ctx->Eval.Map1Attrib[attr]) - set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] ); - - if (ctx->Eval.Map2Attrib[attr]) - set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] ); - } - } - - if (ctx->Eval.Map1Color4) - set_active_eval1( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 ); - - if (ctx->Eval.Map2Color4) - set_active_eval2( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 ); - - if (ctx->Eval.Map1TextureCoord4) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 ); - else if (ctx->Eval.Map1TextureCoord3) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 ); - else if (ctx->Eval.Map1TextureCoord2) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 ); - else if (ctx->Eval.Map1TextureCoord1) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 ); - - if (ctx->Eval.Map2TextureCoord4) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 ); - else if (ctx->Eval.Map2TextureCoord3) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 ); - else if (ctx->Eval.Map2TextureCoord2) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 ); - else if (ctx->Eval.Map2TextureCoord1) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 ); - - if (ctx->Eval.Map1Normal) - set_active_eval1( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal ); - - if (ctx->Eval.Map2Normal) - set_active_eval2( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal ); - - if (ctx->Eval.Map1Vertex4) - set_active_eval1( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 ); - else if (ctx->Eval.Map1Vertex3) - set_active_eval1( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 ); - - if (ctx->Eval.Map2Vertex4) - set_active_eval2( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 ); - else if (ctx->Eval.Map2Vertex3) - set_active_eval2( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); - - exec->eval.recalculate_maps = 0; -} - - - -void brw_exec_do_EvalCoord1f(struct brw_exec_context *exec, GLfloat u) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_1d_map *map = exec->eval.map1[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, data, uu, - exec->eval.map1[attr].sz, - map->Order); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord1f is a noop if this map not enabled: - **/ - if (exec->eval.map1[0].map) { - struct gl_1d_map *map = exec->eval.map1[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, vertex, uu, - exec->eval.map1[0].sz, - map->Order); - - if (exec->eval.map1[0].sz == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_2d_map *map = exec->eval.map2[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_surf(map->Points, - data, - uu, vv, - exec->eval.map2[attr].sz, - map->Uorder, map->Vorder); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord2f is a noop if this map not enabled: - **/ - if (exec->eval.map2[0].map) { - struct gl_2d_map *map = exec->eval.map2[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - if (exec->ctx->Eval.AutoNormal) { - GLfloat normal[4]; - GLfloat du[4], dv[4]; - - _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - - if (exec->eval.map2[0].sz == 4) { - du[0] = du[0]*vertex[3] - du[3]*vertex[0]; - du[1] = du[1]*vertex[3] - du[3]*vertex[1]; - du[2] = du[2]*vertex[3] - du[3]*vertex[2]; - - dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0]; - dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1]; - dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2]; - } - - - CROSS3(normal, du, dv); - NORMALIZE_3FV(normal); - normal[3] = 1.0; - - COPY_SZ_4V( exec->vtx.attrptr[BRW_ATTRIB_NORMAL], - exec->vtx.attrsz[BRW_ATTRIB_NORMAL], - normal ); - - } - else { - _math_horner_bezier_surf(map->Points, vertex, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - } - - if (exec->vtx.attrsz[0] == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 56e21e339ef..86464b2ec5f 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -30,8 +30,6 @@ #include "tnl/tnl.h" #include "context.h" #include "brw_context.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_fallback.h" #include "glheader.h" @@ -40,297 +38,6 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" -#include "dispatch.h" - - -typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); - - -/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */ -static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvNV(ctx->Exec, (target, v)); -} - -static attr_func vert_attrfunc[4] = { - VertexAttrib1fvNV, - VertexAttrib2fvNV, - VertexAttrib3fvNV, - VertexAttrib4fvNV -}; - -#if 0 -static void VertexAttrib1fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvARB(ctx->Exec, (target, v)); -} - - -static attr_func vert_attrfunc_arb[4] = { - VertexAttrib1fvARB, - VertexAttrib2fvARB, - VertexAttrib3fvARB, - VertexAttrib4fvARB -}; -#endif - - - - - - -static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); - break; - case BRW_ATTRIB_MAT_BACK_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SHININESS, v )); - break; - } -} - - -static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); - break; - case BRW_ATTRIB_MAT_BACK_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_COLOR_INDEXES, v )); - break; - } -} - - -static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_BACK_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_FRONT_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_BACK_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_FRONT_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_BACK_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_FRONT_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); - break; - case BRW_ATTRIB_MAT_BACK_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SPECULAR, v )); - break; - } -} - - -static attr_func mat_attrfunc[4] = { - mat_attr1fv, - NULL, - mat_attr3fv, - mat_attr4fv -}; - - -static void index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_Indexf(ctx->Exec, (v[0])); -} - -static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_EdgeFlag(ctx->Exec, ((GLboolean)(v[0] == 1.0))); -} - -struct loopback_attr { - GLint target; - GLint sz; - attr_func func; -}; - -/* Don't emit ends and begins on wrapped primitives. Don't replay - * wrapped vertices. If we get here, it's probably because the the - * precalculated wrapping is wrong. - */ -static void loopback_prim( GLcontext *ctx, - const GLfloat *buffer, - const struct brw_draw_prim *prim, - GLuint wrap_count, - GLuint vertex_size, - const struct loopback_attr *la, GLuint nr ) -{ - GLint start = prim->start; - GLint end = start + prim->count; - const GLfloat *data; - GLint j; - GLuint k; - - if (0) - _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n", - _mesa_lookup_enum_by_nr(prim->mode), - prim->begin ? "begin" : "..", - prim->end ? "end" : "..", - start, - end); - - if (prim->begin) { - CALL_Begin(GET_DISPATCH(), ( prim->mode )); - } - else { - assert(start == 0); - start += wrap_count; - } - - data = buffer + start * vertex_size; - - for (j = start ; j < end ; j++) { - const GLfloat *tmp = data + la[0].sz; - - for (k = 1 ; k < nr ; k++) { - la[k].func( ctx, la[k].target, tmp ); - tmp += la[k].sz; - } - - /* Fire the vertex - */ - la[0].func( ctx, BRW_ATTRIB_POS, data ); - data = tmp; - } - - if (prim->end) { - CALL_End(GET_DISPATCH(), ()); - } -} - -/* Primitives generated by DrawArrays/DrawElements/Rectf may be - * caught here. If there is no primitive in progress, execute them - * normally, otherwise need to track and discard the generated - * primitives. - */ -static void loopback_weak_prim( GLcontext *ctx, - const struct brw_draw_prim *prim ) -{ - /* Use the prim_weak flag to ensure that if this primitive - * wraps, we don't mistake future vertex_lists for part of the - * surrounding primitive. - * - * While this flag is set, we are simply disposing of data - * generated by an operation now known to be a noop. - */ - if (prim->begin) - ctx->Driver.CurrentExecPrimitive |= BRW_SAVE_PRIM_WEAK; - if (prim->end) - ctx->Driver.CurrentExecPrimitive &= ~BRW_SAVE_PRIM_WEAK; -} - - -void brw_loopback_vertex_list( GLcontext *ctx, - const GLfloat *buffer, - const GLubyte *attrsz, - const struct brw_draw_prim *prim, - GLuint prim_count, - GLuint wrap_count, - GLuint vertex_size) -{ - struct loopback_attr la[BRW_ATTRIB_MAX]; - GLuint i, nr = 0; - - for (i = 0 ; i <= BRW_ATTRIB_TEX7 ; i++) { - if (i == BRW_ATTRIB_INDEX || i == BRW_ATTRIB_EDGEFLAG) - continue; - - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = vert_attrfunc[attrsz[i]-1]; - nr++; - } - } - - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; - i <= BRW_ATTRIB_MAT_BACK_INDEXES ; - i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = mat_attrfunc[attrsz[i]-1]; - nr++; - } - } - - if (attrsz[BRW_ATTRIB_EDGEFLAG]) { - la[nr].target = BRW_ATTRIB_EDGEFLAG; - la[nr].sz = attrsz[BRW_ATTRIB_EDGEFLAG]; - la[nr].func = edgeflag_attr1fv; - nr++; - } - - if (attrsz[BRW_ATTRIB_INDEX]) { - la[nr].target = BRW_ATTRIB_INDEX; - la[nr].sz = attrsz[BRW_ATTRIB_INDEX]; - la[nr].func = index_attr1fv; - nr++; - } - - /* XXX ARB vertex attribs */ - - for (i = 0 ; i < prim_count ; i++) { - if ((prim[i].mode & BRW_SAVE_PRIM_WEAK) && - (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) - { - loopback_weak_prim( ctx, &prim[i] ); - } - else - { - loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr ); - } - } -} - @@ -405,62 +112,6 @@ const struct brw_tracked_state brw_check_fallback = { -/* If there is a fallback, fallback to software rasterization and - * transformation together. There is never a requirement to have - * software t&l but hardware rasterization. - * - * Further, all fallbacks are based on GL state, not on eg. primitive - * or vertex data. - */ - -static void do_fallback( struct brw_context *brw, - GLboolean fallback ) -{ - GLcontext *ctx = &brw->intel.ctx; - - /* flush: - */ - ctx->Driver.Flush( ctx ); - - if (fallback) { - _swsetup_Wakeup( ctx ); - _tnl_wakeup_exec( ctx ); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_TRUE); - } - else { - /* Flush vertices and copy-to-current: - */ - FLUSH_CURRENT(ctx, 0); - - _swrast_flush( ctx ); - - brw_exec_wakeup(ctx); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_FALSE); - } -} - - -void brw_fallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 1); -} - - -void brw_unfallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 0); -} - /* Not used: */ void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode ) diff --git a/src/mesa/drivers/dri/i965/brw_fallback.h b/src/mesa/drivers/dri/i965/brw_fallback.h index 81a2d344b81..684a46cd170 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.h +++ b/src/mesa/drivers/dri/i965/brw_fallback.h @@ -31,7 +31,7 @@ #include "mtypes.h" /* for GLcontext... */ struct brw_context; -struct brw_draw_prim; +struct vbo_prim; void brw_fallback( GLcontext *ctx ); void brw_unfallback( GLcontext *ctx ); @@ -39,7 +39,7 @@ void brw_unfallback( GLcontext *ctx ); void brw_loopback_vertex_list( GLcontext *ctx, const GLfloat *buffer, const GLubyte *attrsz, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint prim_count, GLuint wrap_count, GLuint vertex_size); diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 7d3f9dd5e3b..73263a5fff4 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -66,7 +66,9 @@ static void compile_gs_prog( struct brw_context *brw, /* Begin the compilation: */ brw_init_compile(&c.func); - + + c.func.single_program_flow = 1; + /* For some reason the thread is spawned with only 4 channels * unmasked. */ @@ -80,6 +82,9 @@ static void compile_gs_prog( struct brw_context *brw, case GL_QUADS: brw_gs_quads( &c ); break; + case GL_QUAD_STRIP: + brw_gs_quad_strip( &c ); + break; case GL_LINE_LOOP: brw_gs_lines( &c ); break; @@ -143,7 +148,7 @@ static const GLenum gs_prim[GL_POLYGON+1] = { GL_TRIANGLES, GL_TRIANGLES, GL_QUADS, - GL_QUADS, + GL_QUAD_STRIP, GL_TRIANGLES }; diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index f9aa71d9199..29a4e80ce1b 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -67,6 +67,7 @@ struct brw_gs_compile { #define ATTR_SIZE (4*4) void brw_gs_quads( struct brw_gs_compile *c ); +void brw_gs_quad_strip( struct brw_gs_compile *c ); void brw_gs_tris( struct brw_gs_compile *c ); void brw_gs_lines( struct brw_gs_compile *c ); void brw_gs_points( struct brw_gs_compile *c ); diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index e4eed36a464..9abb94d82ed 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -116,6 +116,16 @@ void brw_gs_quads( struct brw_gs_compile *c ) brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); } +void brw_gs_quad_strip( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 4); + + brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); +} + void brw_gs_tris( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 3); diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 2deec5eae3d..1579762b6d1 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -47,7 +47,6 @@ #include "brw_context.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_attrib.h" #include "brw_fallback.h" #define INIT(brw, STRUCT, ATTRIB) \ @@ -388,8 +387,8 @@ static void meta_draw_quad(struct intel_context *intel, struct brw_context *brw = brw_context(&intel->ctx); struct gl_client_array pos_array; struct gl_client_array color_array; - struct gl_client_array *attribs[BRW_ATTRIB_MAX]; - struct brw_draw_prim prim[1]; + struct gl_client_array *attribs[VERT_ATTRIB_MAX]; + struct _mesa_prim prim[1]; GLfloat pos[4][3]; GLubyte color[4]; @@ -439,29 +438,29 @@ static void meta_draw_quad(struct intel_context *intel, /* Ignoring texture coords. */ - memset(attribs, 0, BRW_ATTRIB_MAX * sizeof(*attribs)); - - attribs[BRW_ATTRIB_POS] = &pos_array; - attribs[BRW_ATTRIB_POS]->Ptr = 0; - attribs[BRW_ATTRIB_POS]->Type = GL_FLOAT; - attribs[BRW_ATTRIB_POS]->Enabled = 1; - attribs[BRW_ATTRIB_POS]->Size = 3; - attribs[BRW_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->_MaxElement = 4; - attribs[BRW_ATTRIB_POS]->Normalized = 0; - attribs[BRW_ATTRIB_POS]->BufferObj = brw->metaops.vbo; - - attribs[BRW_ATTRIB_COLOR0] = &color_array; - attribs[BRW_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); - attribs[BRW_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; - attribs[BRW_ATTRIB_COLOR0]->Enabled = 1; - attribs[BRW_ATTRIB_COLOR0]->Size = 4; - attribs[BRW_ATTRIB_COLOR0]->StrideB = 0; - attribs[BRW_ATTRIB_COLOR0]->Stride = 0; - attribs[BRW_ATTRIB_COLOR0]->_MaxElement = 1; - attribs[BRW_ATTRIB_COLOR0]->Normalized = 1; - attribs[BRW_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; + memset(attribs, 0, VERT_ATTRIB_MAX * sizeof(*attribs)); + + attribs[VERT_ATTRIB_POS] = &pos_array; + attribs[VERT_ATTRIB_POS]->Ptr = 0; + attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT; + attribs[VERT_ATTRIB_POS]->Enabled = 1; + attribs[VERT_ATTRIB_POS]->Size = 3; + attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->_MaxElement = 4; + attribs[VERT_ATTRIB_POS]->Normalized = 0; + attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo; + + attribs[VERT_ATTRIB_COLOR0] = &color_array; + attribs[VERT_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); + attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; + attribs[VERT_ATTRIB_COLOR0]->Enabled = 1; + attribs[VERT_ATTRIB_COLOR0]->Size = 4; + attribs[VERT_ATTRIB_COLOR0]->StrideB = 0; + attribs[VERT_ATTRIB_COLOR0]->Stride = 0; + attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1; + attribs[VERT_ATTRIB_COLOR0]->Normalized = 1; + attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; /* Just ignoring texture coordinates for now. */ @@ -476,24 +475,16 @@ static void meta_draw_quad(struct intel_context *intel, prim[0].start = 0; prim[0].count = 4; - if (!brw_draw_prims(&brw->intel.ctx, - (const struct gl_client_array **)attribs, - prim, 1, - NULL, - 0, - 4, - BRW_DRAW_LOCKED )) - { - /* This should not be possible: - */ - _mesa_printf("brw_draw_prims failed in metaops!\n"); - assert(0); - } + brw_draw_prims(&brw->intel.ctx, + (const struct gl_client_array **)attribs, + prim, 1, + NULL, + 0, + 3 ); } -static void install_meta_state( struct intel_context *intel, - GLenum state ) +static void install_meta_state( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; struct brw_context *brw = brw_context(ctx); diff --git a/src/mesa/drivers/dri/i965/brw_save.c b/src/mesa/drivers/dri/i965/brw_save.c deleted file mode 100644 index 1af7791c4d4..00000000000 --- a/src/mesa/drivers/dri/i965/brw_save.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <[email protected]> - */ - - -#include "mtypes.h" -#include "api_arrayelt.h" -#include "dlist.h" -#include "vtxfmt.h" -#include "imports.h" - -#include "brw_save.h" - - - -void brw_save_init( GLcontext *ctx ) -{ - struct brw_save_context *save = CALLOC_STRUCT(brw_save_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - save->ctx = ctx; - IMM_CONTEXT(ctx)->save = save; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_save_api_init( save ); - brw_save_wakeup(ctx); - - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; -} - - -void brw_save_destroy( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - if (save) { - FREE(save); - IMM_CONTEXT(ctx)->save = NULL; - } - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - - -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - _ae_invalidate_state(ctx, new_state); -} - - -/* Note that this can occur during the playback of a display list: - */ -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (fallback) - save->replay_flags |= BRW_SAVE_FALLBACK; - else - save->replay_flags &= ~BRW_SAVE_FALLBACK; -} - - -/* I don't see any reason to swap this code out on fallbacks. It - * wouldn't really mean anything to do so anyway as the old lists are - * still around from pre-fallback. Instead, the above code ensures - * that vertices are routed back through immediate mode dispatch on - * fallback. - * - * The below can be moved into init or removed: - */ -void brw_save_wakeup( GLcontext *ctx ) -{ - ctx->Driver.NewList = brw_save_NewList; - ctx->Driver.EndList = brw_save_EndList; - ctx->Driver.SaveFlushVertices = brw_save_SaveFlushVertices; - ctx->Driver.BeginCallList = brw_save_BeginCallList; - ctx->Driver.EndCallList = brw_save_EndCallList; - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - /* Assume we haven't been getting state updates either: - */ - brw_save_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_save.h b/src/mesa/drivers/dri/i965/brw_save.h deleted file mode 100644 index 41cabe65084..00000000000 --- a/src/mesa/drivers/dri/i965/brw_save.h +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - * - */ - -#ifndef BRW_SAVE_H -#define BRW_SAVE_H - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -struct brw_save_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -/* For display lists, this structure holds a run of vertices of the - * same format, and a strictly well-formed set of begin/end pairs, - * starting on the first vertex and ending at the last. Vertex - * copying on buffer breaks is precomputed according to these - * primitives, though there are situations where the copying will need - * correction at execute-time, perhaps by replaying the list as - * immediate mode commands. - * - * On executing this list, the 'current' values may be updated with - * the values of the final vertex, and often no fixup of the start of - * the vertex list is required. - * - * Eval and other commands that don't fit into these vertex lists are - * compiled using the fallback opcode mechanism provided by dlist.c. - */ -struct brw_save_vertex_list { - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLuint buffer_offset; - GLuint count; - GLuint wrap_count; /* number of copied vertices at start */ - GLboolean dangling_attr_ref; /* current attr implicitly referenced - outside the list */ - - struct brw_draw_prim *prim; - GLuint prim_count; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; -}; - -/* These buffers should be a reasonable size to support upload to - * hardware. Current brw implementation will re-upload on any - * changes, so don't make too big or apps which dynamically create - * dlists and use only a few times will suffer. - * - * Consider stategy of uploading regions from the VBO on demand in the - * case of dynamic vbos. Then make the dlist code signal that - * likelyhood as it occurs. No reason we couldn't change usage - * internally even though this probably isn't allowed for client VBOs? - */ -#define BRW_SAVE_BUFFER_SIZE (8*1024) /* dwords */ -#define BRW_SAVE_PRIM_SIZE 128 -#define BRW_SAVE_PRIM_WEAK 0x40 - -#define BRW_SAVE_FALLBACK 0x10000000 - -/* Storage to be shared among several vertex_lists. - */ -struct brw_save_vertex_store { - struct gl_buffer_object *bufferobj; - GLfloat *buffer; - GLuint used; - GLuint refcount; -}; - -struct brw_save_primitive_store { - struct brw_draw_prim buffer[BRW_SAVE_PRIM_SIZE]; - GLuint used; - GLuint refcount; -}; - - -struct brw_save_context { - GLcontext *ctx; - GLvertexformat vtxfmt; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLfloat *buffer; - GLuint count; - GLuint wrap_count; - GLuint replay_flags; - - struct brw_draw_prim *prim; - GLuint prim_count, prim_max; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current values */ - GLfloat *attrptr[BRW_ATTRIB_MAX]; - GLuint vert_count; - GLuint max_vert; - GLboolean dangling_attr_ref; - GLboolean have_materials; - - GLuint opcode_vertex_list; - - struct brw_save_copied_vtx copied; - - GLfloat CurrentFloatEdgeFlag; - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->ListState */ - GLubyte *currentsz[BRW_ATTRIB_MAX]; -}; - - -void brw_save_init( GLcontext *ctx ); -void brw_save_destroy( GLcontext *ctx ); -void brw_save_wakeup( GLcontext *ctx ); -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ); - -/* Callbacks: - */ -void brw_save_EndList( GLcontext *ctx ); -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ); -void brw_save_EndCallList( GLcontext *ctx ); -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *list ); -void brw_save_SaveFlushVertices( GLcontext *ctx ); -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ); - -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ); - -void brw_save_api_init( struct brw_save_context *save ); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c deleted file mode 100644 index 06ed1d23aa2..00000000000 --- a/src/mesa/drivers/dri/i965/brw_save_api.c +++ /dev/null @@ -1,1170 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - - - -/* Display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "dispatch.h" - -#include "brw_save.h" -#include "brw_fallback.h" - - - - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct brw_save_vertex_list *node, - const GLfloat *src_buffer) -{ - struct brw_save_context *save = IMM_CONTEXT( ctx )->save; - const struct brw_draw_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = save->vertex_size; - const GLfloat *src = src_buffer + prim->start * sz; - GLfloat *dst = save->copied.buffer; - GLuint ovf, i; - - if (prim->end) - return 0; - - switch( prim->mode ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - default: - assert(0); - return 0; - } -} - - -static struct brw_save_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct brw_save_vertex_store *vertex_store = CALLOC_STRUCT(brw_save_vertex_store); - - /* obj->Name needs to be non-zero, but won't ever be examined more - * closely than that. In particular these buffers won't be entered - * into the hash and can never be confused with ones visible to the - * user. Perhaps there could be a special number for internal - * buffers: - */ - vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - - ctx->Driver.BufferData( ctx, - GL_ARRAY_BUFFER_ARB, - BRW_SAVE_BUFFER_SIZE * sizeof(GLfloat), - NULL, - GL_STATIC_DRAW_ARB, - vertex_store->bufferobj); - - vertex_store->buffer = NULL; - vertex_store->used = 0; - vertex_store->refcount = 1; - - return vertex_store; -} - -static void free_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(!vertex_store->buffer); - - if (vertex_store->bufferobj) - ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj ); - - FREE( vertex_store ); -} - -static GLfloat *map_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(vertex_store->bufferobj); - assert(!vertex_store->buffer); - vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, /* not used */ - GL_STATIC_DRAW_ARB, /* not used */ - vertex_store->bufferobj); - - assert(vertex_store->buffer); - return vertex_store->buffer + vertex_store->used; -} - -static void unmap_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj ); - vertex_store->buffer = NULL; -} - - -static struct brw_save_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct brw_save_primitive_store *store = CALLOC_STRUCT(brw_save_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - save->prim = save->prim_store->buffer + save->prim_store->used; - save->buffer = (save->vertex_store->buffer + - save->vertex_store->used); - - assert(save->buffer == save->vbptr); - - if (save->vertex_size) - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - else - save->max_vert = 0; - - save->vert_count = 0; - save->prim_count = 0; - save->prim_max = BRW_SAVE_PRIM_SIZE - save->prim_store->used; - save->dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - struct brw_save_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct brw_save_vertex_list *) - _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); - node->vertex_size = save->vertex_size; - node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); - node->count = save->vert_count; - node->wrap_count = save->copied.nr; - node->dangling_attr_ref = save->dangling_attr_ref; - node->prim = save->prim; - node->prim_count = save->prim_count; - node->vertex_store = save->vertex_store; - node->prim_store = save->prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[BRW_ATTRIB_POS] != 0 || - node->count == 0); - - if (save->dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - save->vertex_store->used += save->vertex_size * node->count; - save->prim_store->used += node->prim_count; - - - /* Copy duplicated vertices - */ - save->copied.nr = _save_copy_vertices( ctx, node, save->buffer ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - struct _glapi_table *dispatch = GET_DISPATCH(); - - _glapi_set_dispatch(ctx->Exec); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)((const char *)save->vertex_store->buffer + - node->buffer_offset), - node->attrsz, - node->prim, - node->prim_count, - node->wrap_count, - node->vertex_size); - - _glapi_set_dispatch(dispatch); - } - - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (save->vertex_store->used > - BRW_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { - - /* Unmap old store: - */ - unmap_vertex_store( ctx, save->vertex_store ); - - /* Release old reference: - */ - save->vertex_store->refcount--; - assert(save->vertex_store->refcount != 0); - save->vertex_store = NULL; - - /* Allocate and map new store: - */ - save->vertex_store = alloc_vertex_store( ctx ); - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - } - - if (save->prim_store->used > BRW_SAVE_PRIM_SIZE - 6) { - save->prim_store->refcount--; - assert(save->prim_store->refcount != 0); - save->prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - GLenum mode; - GLboolean weak; - - assert(i < (GLint) save->prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - save->prim[i].count = (save->vert_count - - save->prim[i].start); - mode = save->prim[i].mode; - weak = save->prim[i].weak; - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - save->prim[0].mode = mode; - save->prim[0].weak = weak; - save->prim[0].begin = 0; - save->prim[0].end = 0; - save->prim[0].pad = 0; - save->prim[0].start = 0; - save->prim[0].count = 0; - save->prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat *data = save->copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(save->max_vert - save->vert_count > save->copied.nr); - - for (i = 0 ; i < save->copied.nr ; i++) { - _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); - data += save->vertex_size; - save->vbptr += save->vertex_size; - save->vert_count++; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) { - if (save->attrsz[i]) { - save->currentsz[i][0] = save->attrsz[i]; - COPY_CLEAN_4V(save->current[i], - save->attrsz[i], - save->attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - save->CurrentFloatEdgeFlag = - save->attrptr[BRW_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (save->CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) - switch (save->attrsz[i]) { - case 4: save->attrptr[i][3] = save->current[i][3]; - case 3: save->attrptr[i][2] = save->current[i][2]; - case 2: save->attrptr[i][1] = save->current[i][1]; - case 1: save->attrptr[i][0] = save->current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - save->attrptr[BRW_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (save->vert_count) - _save_wrap_buffers( ctx ); - else - assert( save->copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = save->attrsz[attr]; - save->attrsz[attr] = newsz; - - save->vertex_size += newsz - oldsz; - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - save->vert_count = 0; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = save->vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (save->attrsz[i]) { - save->attrptr[i] = tmp; - tmp += save->attrsz[i]; - } - else - save->attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (save->copied.nr) - { - GLfloat *data = save->copied.buffer; - GLfloat *dest = save->buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (attr != BRW_ATTRIB_POS && save->currentsz[attr][0] == 0) { - assert(oldsz == 0); - save->dangling_attr_ref = GL_TRUE; - } - - for (i = 0 ; i < save->copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (save->attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, save->current[attr] ); - dest += newsz; - } - } - else { - GLint sz = save->attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - save->vbptr = dest; - save->vert_count += save->copied.nr; - } -} - -static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (sz > save->attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < save->active_sz[attr]) { - static GLfloat id[4] = { 0, 0, 0, 1 }; - GLuint i; - - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= save->attrsz[attr] ; i++) - save->attrptr[attr][i-1] = id[i-1]; - } - - save->active_sz[attr] = sz; -} - -static void _save_reset_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - save->attrsz[i] = 0; - save->active_sz[i] = 0; - } - - save->vertex_size = 0; -} - - - -#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ); - - -/* Only one size for each attribute may be active at once. Eg. if - * Color3f is installed/active, then Color4f may not be, even if the - * vertex actually contains 4 color coordinates. This is because the - * 3f version won't otherwise set color[3] to 1.0 -- this is the job - * of the chooser function when switching between Color4f and Color3f. - */ -#define ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->active_sz[A] != N) \ - save_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = save->attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < save->vertex_size; i++) \ - save->vbptr[i] = save->vertex[i]; \ - \ - save->vbptr += save->vertex_size; \ - \ - if (++save->vert_count >= save->max_vert) \ - _save_wrap_filled_vertex( ctx ); \ - } \ -} while (0) - -#define TAG(x) _save_##x - -#include "brw_attrib_tmp.h" - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define DO_FALLBACK(ctx) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->vert_count || save->prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _save_reset_counters( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1f( u ); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1fv( v ); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2f( u, v ); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2fv( v ); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint1( i ); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint2( i, j ); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallList( l ); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallLists( n, type, v ); -} - - - - -/* This begin is hooked into ... Updating of - * ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - GLuint i = save->prim_count++; - - assert(i < save->prim_max); - save->prim[i].mode = mode & ~BRW_SAVE_PRIM_WEAK; - save->prim[i].begin = 1; - save->prim[i].end = 0; - save->prim[i].weak = (mode & BRW_SAVE_PRIM_WEAK) ? 1 : 0; - save->prim[i].pad = 0; - save->prim[i].start = save->vert_count; - save->prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &save->vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - save->prim[i].end = 1; - save->prim[i].count = (save->vert_count - - save->prim[i].start); - - if (i == (GLint) save->prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(save->copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" ); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - brw_save_NotifyBegin( ctx, GL_QUADS | BRW_SAVE_PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - _ae_map_vbos( ctx ); - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); - - _ae_unmap_vbos( ctx ); -} - -/* Could do better by copying the arrays and element list intact and - * then emitting an indexed prim at runtime. - */ -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - _ae_map_vbos( ctx ); - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); - - _ae_unmap_vbos( ctx ); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLvertexformat *vfmt = &save->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void brw_save_SaveFlushVertices( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (save->vert_count || - save->prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - (void) list; (void) mode; - - if (!save->prim_store) - save->prim_store = alloc_prim_store( ctx ); - - if (!save->vertex_store) - save->vertex_store = alloc_vertex_store( ctx ); - - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_EndList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - unmap_vertex_store( ctx, save->vertex_store ); - - assert(save->vertex_size == 0); -} - -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - save->replay_flags |= dlist->flags; -} - -void brw_save_EndCallList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (ctx->ListState.CallDepth == 1) { - /* This is correct: want to keep only the BRW_SAVE_FALLBACK - * flag, if it is set: - */ - save->replay_flags &= BRW_SAVE_FALLBACK; - } -} - - -static void brw_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - free_vertex_store( ctx, node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); -} - - -static void brw_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "BRW-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct brw_draw_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - (prim->begin) ? "BEGIN" : "(wrap)", - (prim->end) ? "END" : "(wrap)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) { - save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - save->current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = BRW_ATTRIB_FIRST_MATERIAL; i <= BRW_ATTRIB_LAST_MATERIAL; i++) { - const GLuint j = i - BRW_ATTRIB_FIRST_MATERIAL; - ASSERT(j < MAT_ATTRIB_MAX); - save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - save->current[i] = ctx->ListState.CurrentMaterial[j]; - } - - save->currentsz[BRW_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex; - save->current[BRW_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex; - - save->currentsz[BRW_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - save->current[BRW_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void brw_save_api_init( struct brw_save_context *save ) -{ - GLcontext *ctx = save->ctx; - GLuint i; - - save->opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct brw_save_vertex_list), - brw_save_playback_vertex_list, - brw_destroy_vertex_list, - brw_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - for (i = 0; i < BRW_ATTRIB_MAX; i++) - save->inputs[i] = &save->arrays[i]; - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - diff --git a/src/mesa/drivers/dri/i965/brw_save_draw.c b/src/mesa/drivers/dri/i965/brw_save_draw.c deleted file mode 100644 index cebdd8d0607..00000000000 --- a/src/mesa/drivers/dri/i965/brw_save_draw.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Author: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "context.h" -#include "imports.h" -#include "mtypes.h" -#include "macros.h" -#include "light.h" -#include "state.h" - -#include "brw_save.h" -#include "brw_draw.h" -#include "brw_fallback.h" - -/* - * After playback, copy everything but the position from the - * last vertex to the saved state - */ -static void _playback_copy_to_current( GLcontext *ctx, - const struct brw_save_vertex_list *node ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat vertex[BRW_ATTRIB_MAX * 4], *data = vertex; - GLuint i, offset; - - if (node->count) - offset = (node->buffer_offset + - (node->count-1) * node->vertex_size * sizeof(GLfloat)); - else - offset = node->buffer_offset; - - ctx->Driver.GetBufferSubData( ctx, 0, offset, - node->vertex_size * sizeof(GLfloat), - data, node->vertex_store->bufferobj ); - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - if (node->attrsz[i]) { - if (i != BRW_ATTRIB_POS) - COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); - - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - - /* Edgeflag requires special treatment: - */ - if (i == BRW_ATTRIB_EDGEFLAG) - ctx->Current.EdgeFlag = (data[0] == 1.0); - - data += node->attrsz[i] * sizeof(GLfloat); - } - } - - /* Edgeflag requires special treatment: - */ - if (node->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (data[0] == 1.0); - } - - -#if 1 - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } -#endif - - /* CurrentExecPrimitive - */ - if (node->prim_count) { - const struct brw_draw_prim *prim = &node->prim[node->prim_count - 1]; - if (prim->end) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - else - ctx->Driver.CurrentExecPrimitive = prim->mode; - } -} - - - -/* Treat the vertex storage as a VBO, define vertex arrays pointing - * into it: - */ -static void brw_bind_vertex_list( struct brw_save_context *save, - const struct brw_save_vertex_list *node ) -{ - struct gl_client_array *arrays = save->arrays; - GLuint data = node->buffer_offset; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - for (attr = 0; attr < BRW_ATTRIB_MAX; attr++) { - if (node->attrsz[attr]) { - arrays[attr].Ptr = (const GLubyte *)data; - arrays[attr].Size = node->attrsz[attr]; - arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); - arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = node->vertex_store->bufferobj; - arrays[attr]._MaxElement = node->count; /* ??? */ - - assert(arrays[attr].BufferObj->Name); - - data += node->attrsz[attr] * sizeof(GLfloat); - } - } -} - -static void brw_save_loopback_vertex_list( GLcontext *ctx, - const struct brw_save_vertex_list *list ) -{ - const char *buffer = ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, /* ? */ - list->vertex_store->bufferobj); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)(buffer + list->buffer_offset), - list->attrsz, - list->prim, - list->prim_count, - list->wrap_count, - list->vertex_size); - - ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - list->vertex_store->bufferobj); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ) -{ - const struct brw_save_vertex_list *node = (const struct brw_save_vertex_list *) data; - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - FLUSH_CURRENT(ctx, 0); - - if (node->prim_count > 0 && node->count > 0) { - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && - node->prim[0].begin) { - - /* Degenerate case: list is called inside begin/end pair and - * includes operations such as glBegin or glDrawArrays. - */ - if (0) - _mesa_printf("displaylist recursive begin"); - - brw_save_loopback_vertex_list( ctx, node ); - return; - } - else if (save->replay_flags) { - /* Various degnerate cases: translate into immediate mode - * calls rather than trying to execute in place. - */ - brw_save_loopback_vertex_list( ctx, node ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - - brw_bind_vertex_list( save, node ); - - if (!brw_draw_prims( save->ctx, - save->inputs, - node->prim, - node->prim_count, - NULL, - 0, /* Node is a VBO, so this is ok */ - node->count, - 0 )) { - brw_fallback(ctx); - brw_save_loopback_vertex_list( ctx, node ); - brw_unfallback(ctx); - return; - } - } - - /* Copy to current? - */ - _playback_copy_to_current( ctx, node ); -} diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h index 25acdcfe947..10fee944e8d 100644 --- a/src/mesa/drivers/dri/i965/brw_structs.h +++ b/src/mesa/drivers/dri/i965/brw_structs.h @@ -519,7 +519,22 @@ struct thread3 struct brw_clip_unit_state { struct thread0 thread0; - struct thread1 thread1; + struct + { + GLuint pad0:7; + GLuint sw_exception_enable:1; + GLuint pad1:3; + GLuint mask_stack_exception_enable:1; + GLuint pad2:1; + GLuint illegal_op_exception_enable:1; + GLuint pad3:2; + GLuint floating_point_mode:1; + GLuint thread_priority:1; + GLuint binding_table_entry_count:8; + GLuint pad4:5; + GLuint single_program_flow:1; + } thread1; + struct thread2 thread2; struct thread3 thread3; @@ -532,8 +547,8 @@ struct brw_clip_unit_state GLuint pad1:1; GLuint urb_entry_allocation_size:5; GLuint pad2:1; - GLuint max_threads:6; /* may be less */ - GLuint pad3:1; + GLuint max_threads:1; /* may be less */ + GLuint pad3:6; } thread4; struct @@ -1322,6 +1337,7 @@ struct brw_instruction GLuint end_of_thread:1; } generic; + GLint d; GLuint ud; } bits3; }; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 1353325afff..af1ad0f1ef1 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -34,21 +34,15 @@ */ #include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" #include "macros.h" -static GLuint minify( GLuint d ) -{ - return MAX2(1, d>>1); -} - GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) { /* XXX: these vary depending on image format: */ /* GLint align_w = 4; */ - GLint align_h = 2; - switch (mt->target) { case GL_TEXTURE_CUBE_MAP: @@ -107,53 +101,10 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) break; } - default: { - GLuint level; - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, - x, y, - width, - mt->compressed ? height/4 : height, 1); - - if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = MAX2(align_h, height); - - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y + img_height); - - /* Layout_below: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += mt->pitch / 2; - x = (x + 3) & ~ 3; - } - else { - y += img_height; - y += align_h - 1; - y &= ~(align_h - 1); - } - - width = minify(width); - height = minify(height); - } + default: + i945_miptree_layout_2d(mt); break; } - } DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, mt->pitch, mt->total_height, diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index e5a28b96e32..74c9d88e464 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -54,12 +54,11 @@ static void do_vs_prog( struct brw_context *brw, c.vp = vp; c.prog_data.outputs_written = vp->program.Base.OutputsWritten; - c.prog_data.inputs_read = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); + c.prog_data.inputs_read = vp->program.Base.InputsRead; if (c.key.copy_edgeflag) { c.prog_data.outputs_written |= 1<<VERT_RESULT_EDGE; - c.prog_data.inputs_read |= 1<<BRW_ATTRIB_EDGEFLAG; + c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG; } if (0) diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c index 502d8283970..528e164db8c 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_constval.c +++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c @@ -162,6 +162,7 @@ static GLuint get_input_size(struct brw_context *brw, GLuint sizes_dword = brw->vb.info.sizes[attr/16]; GLuint sizes_bits = (sizes_dword>>((attr%16)*2)) & 0x3; return sizes_bits + 1; +/* return brw->vb.inputs[attr].glarray->Size; */ } /* Calculate sizes of vertex program outputs. Size is the largest @@ -176,8 +177,6 @@ static void calc_wm_input_sizes( struct brw_context *brw ) struct tracker t; GLuint insn; GLuint i; - GLuint64EXT inputs = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); memset(&t, 0, sizeof(t)); @@ -185,8 +184,8 @@ static void calc_wm_input_sizes( struct brw_context *brw ) if (brw->attribs.Light->Model.TwoSide) t.twoside = 1; - for (i = 0; i < BRW_ATTRIB_MAX; i++) - if (inputs & (1<<i)) + for (i = 0; i < VERT_ATTRIB_MAX; i++) + if (vp->program.Base.InputsRead & (1<<i)) set_active_component(&t, PROGRAM_INPUT, i, szflag[get_input_size(brw, i)]); diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 8403e1bd7b6..ffdb843e85f 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -77,8 +77,8 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) /* Allocate input regs: */ c->nr_inputs = 0; - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - if (c->prog_data.inputs_read & ((GLuint64EXT)1<<i)) { + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (c->prog_data.inputs_read & (1<<i)) { c->nr_inputs++; c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0); reg++; @@ -791,7 +791,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) if (c->key.copy_edgeflag) { brw_MOV(p, get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE), - get_reg(c, PROGRAM_INPUT, BRW_ATTRIB_EDGEFLAG)); + get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG)); } diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index b7893ca3e55..0d61092247a 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -114,7 +114,7 @@ static GLuint translate_texgen( GLboolean enabled, GLenum mode ) static void make_state_key( GLcontext *ctx, struct state_key *key ) { struct brw_context *brw = brw_context(ctx); - struct gl_fragment_program *fp = brw->fragment_program; + const struct gl_fragment_program *fp = brw->fragment_program; GLuint i; /* This now relies on texenvprogram.c being active: @@ -146,9 +146,13 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) } /* BRW_NEW_INPUT_VARYING */ - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; i < BRW_ATTRIB_MAX ; i++) - if (brw->vb.info.varying & ((GLuint64EXT)1<<i)) - key->light_material_mask |= 1<<(i-BRW_ATTRIB_MAT_FRONT_AMBIENT); + + /* For these programs, material values are stuffed into the + * generic slots: + */ + for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) + if (brw->vb.info.varying & (1<<(VERT_ATTRIB_GENERIC0 + i))) + key->light_material_mask |= 1<<i; for (i = 0; i < MAX_LIGHTS; i++) { struct gl_light *light = &brw->attribs.Light->Light[i]; @@ -374,17 +378,10 @@ static void release_temps( struct tnl_program *p ) static struct ureg register_input( struct tnl_program *p, GLuint input ) { - GLuint orig_input = input; - /* Cram the material flags into the generic range. We'll translate - * them back later. - */ - if (input >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - input -= BRW_ATTRIB_MAT_FRONT_AMBIENT - BRW_ATTRIB_GENERIC0; - assert(input < 32); p->program->Base.InputsRead |= (1<<input); - return make_ureg(PROGRAM_INPUT, orig_input); + return make_ureg(PROGRAM_INPUT, input); } static struct ureg register_output( struct tnl_program *p, GLuint output ) @@ -647,7 +644,7 @@ static void emit_passthrough( struct tnl_program *p, static struct ureg get_eye_position( struct tnl_program *p ) { if (is_undef(p->eye_position)) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position = reserve_temp(p); @@ -710,7 +707,7 @@ static struct ureg get_eye_position_normalized( struct tnl_program *p ) static struct ureg get_eye_normal( struct tnl_program *p ) { if (is_undef(p->eye_normal)) { - struct ureg normal = register_input(p, BRW_ATTRIB_NORMAL ); + struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, @@ -743,7 +740,7 @@ static struct ureg get_eye_normal( struct tnl_program *p ) static void build_hpos( struct tnl_program *p ) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; @@ -787,9 +784,9 @@ static struct ureg get_material( struct tnl_program *p, GLuint side, GLuint attrib = material_attrib(side, property); if (p->color_materials & (1<<attrib)) - return register_input(p, BRW_ATTRIB_COLOR0); + return register_input(p, VERT_ATTRIB_COLOR0); else if (p->materials & (1<<attrib)) - return register_input( p, attrib + BRW_ATTRIB_MAT_FRONT_AMBIENT ); + return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT ); else return register_param3( p, STATE_MATERIAL, side, property ); } @@ -1157,7 +1154,7 @@ static void build_fog( struct tnl_program *p ) input = swizzle1(get_eye_position(p), Z); } else { - input = swizzle1(register_input(p, BRW_ATTRIB_FOG), X); + input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); } if (p->state->fog_option && @@ -1299,7 +1296,7 @@ static void build_texture_transform( struct tnl_program *p ) for (j = 0; j < 4; j++) { switch (modes[j]) { case TXG_OBJ_LINEAR: { - struct ureg obj = register_input(p, BRW_ATTRIB_POS); + struct ureg obj = register_input(p, VERT_ATTRIB_POS); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); @@ -1348,7 +1345,7 @@ static void build_texture_transform( struct tnl_program *p ) } if (copy_mask) { - struct ureg in = register_input(p, BRW_ATTRIB_TEX0+i); + struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); } } @@ -1357,7 +1354,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg texmat[4]; struct ureg in = (!is_undef(out_texgen) ? out_texgen : - register_input(p, BRW_ATTRIB_TEX0+i)); + register_input(p, VERT_ATTRIB_TEX0+i)); if (PREFER_DP4) { register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 0, 3, STATE_MATRIX, texmat ); @@ -1373,7 +1370,7 @@ static void build_texture_transform( struct tnl_program *p ) release_temps(p); } else { - emit_passthrough(p, BRW_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); + emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } } } @@ -1425,10 +1422,10 @@ static void build_tnl_program( struct tnl_program *p ) build_lighting(p); else { if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) - emit_passthrough(p, BRW_ATTRIB_COLOR0, VERT_RESULT_COL0); + emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) - emit_passthrough(p, BRW_ATTRIB_COLOR1, VERT_RESULT_COL1); + emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); } } @@ -1628,7 +1625,7 @@ const struct brw_tracked_state brw_tnl_vertprog = { static void update_active_vertprog( struct brw_context *brw ) { - struct gl_vertex_program *prev = brw->vertex_program; + const struct gl_vertex_program *prev = brw->vertex_program; /* NEW_PROGRAM */ if (brw->attribs.VertexProgram->_Enabled) { diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index ac09754e3ae..786f30e641e 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -46,8 +46,6 @@ #include "brw_state.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_state.h" #include "brw_aub.h" #include "brw_fallback.h" @@ -68,9 +66,6 @@ static void brw_destroy_context( struct intel_context *intel ) brw_destroy_state(brw); brw_draw_destroy( brw ); - brw_exec_destroy( ctx ); - brw_save_destroy( ctx ); - brw_ProgramCacheDestroy( ctx ); brw_FrameBufferTexDestroy( brw ); } @@ -166,10 +161,7 @@ static GLuint brw_flush_cmd( void ) static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) { - GLcontext *ctx = &intel->ctx; - - brw_exec_invalidate_state(ctx, new_state); - brw_save_invalidate_state(ctx, new_state); + /* nothing */ } diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 4707a709e77..ff5cb31bdd1 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -122,7 +122,7 @@ static void upload_wm_unit(struct brw_context *brw ) /* BRW_NEW_FRAGMENT_PROGRAM */ { - struct gl_fragment_program *fp = brw->fragment_program; + const struct gl_fragment_program *fp = brw->fragment_program; if (fp->Base.InputsRead & (1<<FRAG_ATTRIB_WPOS)) wm.wm5.program_uses_depth = 1; /* as far as we can tell */ @@ -168,7 +168,7 @@ static void upload_wm_unit(struct brw_context *brw ) wm.wm5.line_stipple = 1; } - if (INTEL_DEBUG & DEBUG_STATS) + if (INTEL_DEBUG & DEBUG_STATS || intel->stats_wm) wm.wm4.stats_enable = 1; brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm ); diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index 6932522d3d3..e748c0d6d0b 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -199,9 +199,11 @@ void *bmFindVirtual( struct intel_context *intel, * For now they can stay, but will likely change/move before final: */ unsigned bmSetFence( struct intel_context * ); +unsigned bmSetFenceLock( struct intel_context * ); unsigned bmLockAndFence( struct intel_context *intel ); int bmTestFence( struct intel_context *, unsigned fence ); void bmFinishFence( struct intel_context *, unsigned fence ); +void bmFinishFenceLock( struct intel_context *, unsigned fence ); void bm_fake_NotifyContendedLockTake( struct intel_context * ); diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index ed88ab3797a..24ee11edd8c 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -338,7 +338,6 @@ static int evict_mru( struct intel_context *intel, GLuint *pool ) } - static int check_fenced( struct intel_context *intel ) { struct bufmgr *bm = intel->bm; @@ -1328,11 +1327,21 @@ unsigned bmSetFence( struct intel_context *intel ) return intel->bm->last_fence; } +unsigned bmSetFenceLock( struct intel_context *intel ) +{ + unsigned last; + LOCK(intel->bm); + last = bmSetFence(intel); + UNLOCK(intel->bm); + return last; +} unsigned bmLockAndFence( struct intel_context *intel ) { if (intel->bm->need_fence) { LOCK_HARDWARE(intel); + LOCK(intel->bm); bmSetFence(intel); + UNLOCK(intel->bm); UNLOCK_HARDWARE(intel); } @@ -1350,7 +1359,12 @@ void bmFinishFence( struct intel_context *intel, unsigned fence ) check_fenced(intel); } - +void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) +{ + LOCK(intel->bm); + bmFinishFence(intel, fence); + UNLOCK(intel->bm); +} /* Specifically ignore texture memory sharing. diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index c8c5bf93c95..173d1d5b6c2 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - bmFinishFence(intel, intel->last_swap_fence); + bmFinishFenceLock(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -155,7 +155,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intel_batchbuffer_flush( intel->batch ); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = bmSetFence( intel ); + intel->last_swap_fence = bmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index d13e287fa76..34560e4353e 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -33,11 +33,12 @@ #include "extensions.h" #include "framebuffer.h" #include "imports.h" +#include "points.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -60,6 +61,7 @@ #include "bufmgr.h" #include "utils.h" +#include "vblank.h" #ifndef INTEL_DEBUG int INTEL_DEBUG = (0); #endif @@ -70,6 +72,7 @@ int INTEL_DEBUG = (0); #define need_GL_ARB_vertex_buffer_object #define need_GL_ARB_vertex_program #define need_GL_ARB_window_pos +#define need_GL_ARB_occlusion_query #define need_GL_EXT_blend_color #define need_GL_EXT_blend_equation_separate #define need_GL_EXT_blend_func_separate @@ -84,11 +87,6 @@ int INTEL_DEBUG = (0); int VERBOSE = 0; #endif -#if DEBUG_LOCKING -char *prevLockFile; -int prevLockLine; -#endif - /*************************************** * Mesa's Driver Functions ***************************************/ @@ -182,7 +180,16 @@ const struct dri_extension card_extensions[] = { NULL, NULL } }; +const struct dri_extension arb_oc_extension = + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}; +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + struct intel_context *intel = ctx?intel_context(ctx):NULL; + driInitExtensions(ctx, card_extensions, enable_imaging); + if (!ctx || intel->intelScreen->drmMinor >= 8) + driInitSingleExtension (ctx, &arb_oc_extension); +} static const struct dri_debug_control debug_control[] = { @@ -216,7 +223,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); @@ -241,6 +248,37 @@ void intelFinish( GLcontext *ctx ) bmFinishFence(intel, bmLockAndFence(intel)); } +static void +intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + drmI830MMIO io = { + .read_write = MMIO_READ, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &q->Result + }; + intel->stats_wm++; + intelFinish(&intel->ctx); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); +} + +static void +intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + GLuint64EXT tmp; + drmI830MMIO io = { + .read_write = MMIO_READ, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &tmp + }; + intelFinish(&intel->ctx); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + q->Result = tmp - q->Result; + q->Ready = GL_TRUE; + intel->stats_wm--; +} + void intelInitDriverFunctions( struct dd_function_table *functions ) { @@ -250,6 +288,8 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) functions->Finish = intelFinish; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; + functions->BeginQuery = intelBeginQuery; + functions->EndQuery = intelEndQuery; /* CopyPixels can be accelerated even with the current memory * manager: @@ -292,6 +332,11 @@ GLboolean intelInitContext( struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i965"); + + intel->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; ctx->Const.MaxTextureMaxAnisotropy = 2.0; @@ -327,7 +372,7 @@ GLboolean intelInitContext( struct intel_context *intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -374,9 +419,7 @@ GLboolean intelInitContext( struct intel_context *intel, _mesa_printf("IRQs not active. Exiting\n"); exit(1); } - - driInitExtensions( ctx, card_extensions, - GL_TRUE ); + intelInitExtensions(ctx, GL_TRUE); INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), debug_control ); @@ -403,8 +446,8 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->front.pitch / intelScreen->cpp, intelScreen->height, - GL_FALSE); - + intelScreen->front.size, + intelScreen->front.tiled != 0); intel->back_region = intel_region_create_static(intel, @@ -414,7 +457,8 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->back.pitch / intelScreen->cpp, intelScreen->height, - (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1); + intelScreen->back.size, + intelScreen->back.tiled != 0); /* Still assuming front.cpp == depth.cpp * @@ -430,7 +474,8 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->depth.pitch / intelScreen->cpp, intelScreen->height, - (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1); + intelScreen->depth.size, + intelScreen->depth.tiled != 0); intel_bufferobj_init( intel ); intel->batch = intel_batchbuffer_alloc( intel ); @@ -472,7 +517,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ @@ -521,6 +566,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ + driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, + &intel->vbl_seq ); + intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); } @@ -655,3 +703,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) _glthread_UNLOCK_MUTEX(lockMutex); } + diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 8367a957109..a0f392f9353 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -177,6 +177,7 @@ struct intel_context GLuint second_last_swap_fence; GLboolean aub_wrap; + GLuint stats_wm; struct intel_batchbuffer *batch; @@ -499,6 +500,7 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); #define _NEW_WINDOW_POS 0x40000000 @@ -521,6 +523,5 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture return (struct intel_texture_image *)img; } - #endif diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index f3b76db2153..0a8e976f706 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -43,6 +43,26 @@ #include "drm.h" #include "bufmgr.h" +static int intelWaitIdleLocked( struct intel_context *intel ) +{ + static int in_wait_idle = 0; + unsigned int fence; + + if (!in_wait_idle) { + if (INTEL_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "waiting for idle\n"); + } + + in_wait_idle = 1; + fence = bmSetFence(intel); + intelWaitIrq(intel, fence); + in_wait_idle = 0; + + return bmTestFence(intel, fence); + } else { + return 1; + } +} int intelEmitIrqLocked( struct intel_context *intel ) { @@ -88,7 +108,8 @@ void intelWaitIrq( struct intel_context *intel, int seq ) /* This seems quite often to return before it should!?! */ - } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch)); + } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch) + || (ret == 0 && intel->sarea->last_dispatch - seq >= (1 << 24))); if ( ret ) { @@ -140,7 +161,11 @@ void intel_batch_ioctl( struct intel_context *intel, UNLOCK_HARDWARE(intel); exit(1); } - } + + if (INTEL_DEBUG & DEBUG_SYNC) { + intelWaitIdleLocked(intel); + } + } } void intel_cmd_ioctl( struct intel_context *intel, @@ -172,5 +197,9 @@ void intel_cmd_ioctl( struct intel_context *intel, UNLOCK_HARDWARE(intel); exit(1); } - } + + if (INTEL_DEBUG & DEBUG_SYNC) { + intelWaitIdleLocked(intel); + } + } } diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 398b0a0a3b5..835ecdd7257 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -122,10 +122,10 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ) { struct intel_region *region = calloc(sizeof(*region), 1); - GLuint size = cpp * pitch * height; GLint pool; DBG("%s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 2413f0de33c..d2235f1275b 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -78,6 +78,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ); /* Map/unmap regions. This is refcounted also: diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 56e6a792fa2..08f0bb340f7 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -38,6 +38,7 @@ #include "intel_screen.h" +#include "intel_context.h" #include "intel_tex.h" #include "intel_span.h" #include "intel_ioctl.h" @@ -61,8 +62,6 @@ const GLuint __driNConfigOptions = 4; static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; #endif /*USE_NEW_INTERFACE*/ -extern const struct dri_extension card_extensions[]; - /** * Map all the memory regions described by the screen. * \return GL_TRUE if success, GL_FALSE if error. @@ -230,16 +229,19 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; intelScreen->front.handle = sarea->front_handle; intelScreen->front.size = sarea->front_size; + intelScreen->front.tiled = sarea->front_tiled; intelScreen->back.offset = sarea->back_offset; intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; intelScreen->back.handle = sarea->back_handle; intelScreen->back.size = sarea->back_size; - + intelScreen->back.tiled = sarea->back_tiled; + intelScreen->depth.offset = sarea->depth_offset; intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; + intelScreen->depth.tiled = sarea->depth_tiled; intelScreen->tex.offset = sarea->tex_offset; intelScreen->logTextureGranularity = sarea->log_tex_granularity; @@ -249,6 +251,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelScreen->rotated.offset = sarea->rotated_offset; intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; intelScreen->rotated.size = sarea->rotated_size; + intelScreen->rotated.tiled = sarea->rotated_tiled; intelScreen->current_rotation = sarea->rotation; #if 0 matrix23Rotate(&intelScreen->rotMatrix, @@ -683,7 +686,6 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc (dri_priv->cpp == 2) ? 16 : 24, (dri_priv->cpp == 2) ? 0 : 8, GL_TRUE ); - /* Calling driInitExtensions here, with a NULL context pointer, does not actually * enable the extensions. It just makes sure that all the dispatch offsets for all * the extensions that *might* be enables are known. This is needed because the @@ -692,7 +694,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc * * Hello chicken. Hello egg. How are you two today? */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); + intelInitExtensions(NULL, GL_FALSE); } return (void *) psp; diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index 094158afd85..bf9a716082d 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -42,6 +42,7 @@ typedef struct { char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ int pitch; /* row stride, in pixels */ + unsigned int tiled; } intelRegion; typedef struct diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 120000 index 00000000000..fe61b441945 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h index e3bbdc79070..f320378c2a5 100644 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ b/src/mesa/drivers/dri/i965/server/i830_common.h @@ -52,6 +52,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_INIT_HEAP 0x0a #define DRM_I830_CMDBUFFER 0x0b #define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -199,5 +200,23 @@ typedef struct { int region; } drmI830MemDestroyHeap; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; #endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c new file mode 100644 index 00000000000..f3564802171 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <[email protected]> + * Michel Dänzer <[email protected]> + */ + +#include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" +#include "macros.h" + + +static int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + +void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) +{ + GLint align_h = 2, align_w = 4; + GLuint level; + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + + mt->pitch = mt->width0; + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap out past the width of its parent. + */ + if (mt->first_level != mt->last_level) { + GLuint mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + + if (mip1_width > mt->width0) + mt->pitch = mip1_width; + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; + mt->total_height = 0; + + for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, x, y, width, + mt->compressed ? height/4 : height, 1); + + if (mt->compressed) + img_height = MAX2(1, height/4); + else + img_height = align(height, align_h); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y + img_height); + + /* Layout_below: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += align(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } +} diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h new file mode 100644 index 00000000000..1e37f8f525f --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -0,0 +1,41 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <[email protected]> + * Michel Dänzer <[email protected]> + */ + +#include "macros.h" + + +static GLuint minify( GLuint d ) +{ + return MAX2(1, d>>1); +} + +extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ); diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 2ab1cf2617e..5a6c301da2d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -38,7 +38,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -225,7 +225,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -278,7 +278,7 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); if (release_texture_heaps) { diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c index d4804a2c550..667a3945206 100644 --- a/src/mesa/drivers/dri/mach64/mach64_state.c +++ b/src/mesa/drivers/dri/mach64/mach64_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1023,7 +1023,7 @@ static void mach64DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MACH64_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index f02913c6af2..f024f73eb6a 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -45,7 +45,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -593,7 +593,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -676,7 +676,7 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); mgaFreeVB( mmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 075fd348cf4..c20a76f29ef 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -41,7 +41,7 @@ #include "mgaregs.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1042,7 +1042,7 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MGA_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 00000000000..20d2de5eefb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -0,0 +1,53 @@ +# src/mesa/drivers/dri/nouveau/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +DRIVER_SOURCES = \ + nouveau_bufferobj.c \ + nouveau_buffers.c \ + nouveau_card.c \ + nouveau_context.c \ + nouveau_driver.c \ + nouveau_fifo.c \ + nouveau_lock.c \ + nouveau_object.c \ + nouveau_screen.c \ + nouveau_span.c \ + nouveau_state.c \ + nouveau_state_cache.c \ + nouveau_shader.c \ + nouveau_shader_0.c \ + nouveau_shader_1.c \ + nouveau_shader_2.c \ + nouveau_tex.c \ + nouveau_swtcl.c \ + nouveau_sync.c \ + nouveau_query.c \ + nv04_state.c \ + nv04_swtcl.c \ + nv10_state.c \ + nv10_swtcl.c \ + nv20_state.c \ + nv20_vertprog.c \ + nv30_state.c \ + nv30_fragprog.c \ + nv30_vertprog.c \ + nv40_fragprog.c \ + nv40_vertprog.c \ + nv50_state.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c new file mode 100644 index 00000000000..684ed7b017d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -0,0 +1,616 @@ +#include "bufferobj.h" +#include "enums.h" + +#include "nouveau_bufferobj.h" +#include "nouveau_buffers.h" +#include "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_object.h" +#include "nouveau_msg.h" + +#define NOUVEAU_MEM_FREE(mem) do { \ + nouveau_mem_free(ctx, (mem)); \ + (mem) = NULL; \ +} while(0) + +#define DEBUG(fmt,args...) do { \ + if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \ + fprintf(stderr, "%s: "fmt, __func__, ##args); \ + } \ +} while(0) + +static GLboolean +nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *in_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + /* If there's a permanent backing store, blit directly into it */ + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, + nbo->gpu_mem, + offset, offset, size); + } + } else { + DEBUG("..sys_mem\n"); + in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0); + if (in_mem) { + DEBUG("....via AGP\n"); + /* otherwise, try blitting to faster memory and + * copying from there + */ + nouveau_memformat_flat_emit(ctx, in_mem, nbo->gpu_mem, + 0, offset, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + _mesa_memcpy(nbo->cpu_mem_sys + offset, + in_mem->map, size); + NOUVEAU_MEM_FREE(in_mem); + } else { + DEBUG("....direct VRAM copy\n"); + /* worst case, copy directly from vram */ + _mesa_memcpy(nbo->cpu_mem_sys + offset, + nbo->gpu_mem + offset, + size); + } + } + + return GL_TRUE; +} + +static GLboolean +nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *out_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, + nbo->cpu_mem, + offset, offset, size); + } + } else { + out_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_MAPPED, + size, 0); + if (out_mem) { + DEBUG("....via AGP\n"); + _mesa_memcpy(out_mem->map, + nbo->cpu_mem_sys + offset, size); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem, + offset, 0, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + NOUVEAU_MEM_FREE(out_mem); + } else { + DEBUG("....direct VRAM copy\n"); + _mesa_memcpy(nbo->gpu_mem->map + offset, + nbo->cpu_mem_sys + offset, + size); + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + if (bo->OnCard) + return GL_TRUE; + assert(nbo->gpu_mem_flags); + + nbo->gpu_mem = nouveau_mem_alloc(ctx, nbo->gpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + assert(nbo->gpu_mem); + + if (nbo->cpu_mem_flags) { + if ((nbo->cpu_mem_flags|NOUVEAU_MEM_MAPPED) != nbo->gpu_mem->type) { + DEBUG("..need cpu_mem buffer\n"); + + nbo->cpu_mem = nouveau_mem_alloc(ctx, + nbo->cpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + + if (nbo->cpu_mem) { + DEBUG("....alloc ok, kill sys_mem buffer\n"); + _mesa_memcpy(nbo->cpu_mem->map, + nbo->cpu_mem_sys, bo->Size); + FREE(nbo->cpu_mem_sys); + } + } else { + DEBUG("..cpu direct access to GPU buffer\n"); + nbo->cpu_mem = nbo->gpu_mem; + } + } + nouveau_bo_upload_to_screen(ctx, 0, bo->Size, bo); + + bo->OnCard = GL_TRUE; + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint nr_dirty; + + DEBUG("bo=%p\n", bo); + if (!bo->OnCard) + return GL_TRUE; + + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + if (nbo->cpu_mem) { + if (nr_dirty && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + DEBUG("..destroy cpu_mem buffer\n"); + nbo->cpu_mem_sys = malloc(bo->Size); + assert(nbo->cpu_mem_sys); + _mesa_memcpy(nbo->cpu_mem_sys, nbo->cpu_mem->map, bo->Size); + if (nbo->cpu_mem == nbo->gpu_mem) + nbo->cpu_mem = NULL; + else + NOUVEAU_MEM_FREE(nbo->cpu_mem); + } + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + return GL_TRUE; +} + +static void +nouveau_bo_choose_storage_method(GLcontext *ctx, GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint gpu_type = 0; + GLuint cpu_type = 0; + + switch (usage) { + /* Client source, changes often, used by GL many times */ + case GL_DYNAMIC_DRAW_ARB: + gpu_type = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE; + cpu_type = NOUVEAU_MEM_AGP; + break; + /* GL source, changes often, client reads many times */ + case GL_DYNAMIC_READ_ARB: + /* Client source, specified once, used by GL many times */ + case GL_STATIC_DRAW_ARB: + /* GL source, specified once, client reads many times */ + case GL_STATIC_READ_ARB: + /* Client source, specified once, used by GL a few times */ + case GL_STREAM_DRAW_ARB: + /* GL source, specified once, client reads a few times */ + case GL_STREAM_READ_ARB: + /* GL source, changes often, used by GL many times*/ + case GL_DYNAMIC_COPY_ARB: + /* GL source, specified once, used by GL many times */ + case GL_STATIC_COPY_ARB: + /* GL source, specified once, used by GL a few times */ + case GL_STREAM_COPY_ARB: + gpu_type = NOUVEAU_MEM_FB; + break; + default: + assert(0); + } + + nbo->gpu_mem_flags = gpu_type; + nbo->cpu_mem_flags = cpu_type; + nbo->usage = usage; +} + +void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, + const GLvoid *data, + GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + /* Free up previous buffers if we can't reuse them */ + if (nbo->usage != usage || + (nbo->gpu_mem && (nbo->gpu_mem->size != size))) { + if (nbo->cpu_mem_sys) + FREE(nbo->cpu_mem_sys); + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->cpu_mem); + else + nbo->cpu_mem = NULL; + } + if (nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + nbo->cpu_mem_sys = calloc(1, size); + } + + nouveau_bo_choose_storage_method(ctx, usage, bo); + /* Force off flags that may not be ok for a given buffer */ + nbo->gpu_mem_flags &= valid_gpu_access; + + bo->Usage = usage; + bo->Size = size; + + if (data) { + GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo); + _mesa_memcpy(map, data, size); + nouveau_bo_dirty_all(ctx, GL_FALSE, bo); + nouveau_bo_unmap(ctx, bo); + } +} + +void * +nouveau_bo_map(GLcontext *ctx, GLenum access, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p, access=%s\n", bo, _mesa_lookup_enum_by_nr(access)); + + if (bo->OnCard && + (access == GL_READ_ONLY_ARB || access == GL_READ_WRITE_ARB)) { + GLuint nr_dirty; + + DEBUG("..on card\n"); + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + + /* nouveau_bo_download_dirty won't wait unless it needs to + * free a temp buffer, which isn't the case if cpu_mem is + * present. + */ + if (nr_dirty && nbo->cpu_mem && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + } + + if (nbo->cpu_mem) { + DEBUG("..access via cpu_mem\n"); + return nbo->cpu_mem->map; + } else { + DEBUG("..access via cpu_mem_sys\n"); + return nbo->cpu_mem_sys; + } +} + +void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo) +{ + DEBUG("unmap bo=%p\n", bo); +} + +uint32_t +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + assert(nbo->mapped == GL_FALSE); + + DEBUG("gpu_ref\n"); + + if (!bo->OnCard) { + nouveau_bo_move_in(ctx, bo); + bo->OnCard = GL_TRUE; + } + nouveau_bo_upload_dirty(ctx, bo); + + return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem); +} + +void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + uint32_t start = offset; + uint32_t end = offset + size; + int i; + + if (nbo->cpu_mem == nbo->gpu_mem) + return; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("on_card=%d, offset=%d, size=%d, bo=%p\n", + on_card, offset, size, bo); + + for (i=0; i<dirty->nr_dirty; i++) { + nouveau_bufferobj_region *r = &dirty->dirty[i]; + + /* already dirty */ + if (start >= r->start && end <= r->end) { + DEBUG("..already dirty\n"); + return; + } + + /* add to the end of a region */ + if (start >= r->start && start <= r->end) { + if (end > r->end) { + DEBUG("..extend end of region\n"); + r->end = end; + return; + } + } + + /* add to the start of a region */ + if (start < r->start && end >= r->end) { + DEBUG("..extend start of region\n"); + r->start = start; + /* .. and to the end */ + if (end > r->end) { + DEBUG("....and end\n"); + r->end = end; + } + return; + } + } + + /* new region */ + DEBUG("..new dirty\n"); + dirty->nr_dirty++; + dirty->dirty = realloc(dirty->dirty, + sizeof(nouveau_bufferobj_region) * + dirty->nr_dirty); + dirty->dirty[dirty->nr_dirty - 1].start = start; + dirty->dirty[dirty->nr_dirty - 1].end = end; +} + +void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("dirty all\n"); + if (dirty->nr_dirty) { + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + } + + nouveau_bo_dirty_linear(ctx, on_card, 0, bo->Size, bo); +} + +GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->cpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (!nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; i<nr_dirty; i++) { + nouveau_bufferobj_region *r = &dirty->dirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_upload_to_screen(ctx, + r->start, r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + +GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->gpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; i<nr_dirty; i++) { + nouveau_bufferobj_region *r = &dirty->dirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_download_from_screen(ctx, + r->start, + r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + +static void +nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ +} + +static struct gl_buffer_object * +nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target) +{ + nouveau_buffer_object *nbo; + + nbo = CALLOC_STRUCT(nouveau_buffer_object_t); + if (nbo) + _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); + DEBUG("bo=%p\n", nbo); + + return nbo ? &nbo->mesa : NULL; +} + +static void +nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + if (nbo->gpu_dirty.nr_dirty) + FREE(nbo->gpu_dirty.dirty); + if (nbo->cpu_dirty.nr_dirty) + FREE(nbo->cpu_dirty.dirty); + if (nbo->cpu_mem) nouveau_mem_free(ctx, nbo->cpu_mem); + if (nbo->gpu_mem) nouveau_mem_free(ctx, nbo->gpu_mem); + + _mesa_delete_buffer_object(ctx, obj); +} + +static void +nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size, + const GLvoid *data, GLenum usage, + struct gl_buffer_object *obj) +{ + GLuint gpu_flags; + + DEBUG("target=%s, size=%d, data=%p, usage=%s, obj=%p\n", + _mesa_lookup_enum_by_nr(target), + (GLuint)size, data, + _mesa_lookup_enum_by_nr(usage), + obj); + + switch (target) { + case GL_ELEMENT_ARRAY_BUFFER_ARB: + gpu_flags = 0; + break; + default: + gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_AGP_OK; + break; + } + nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj); +} + +static void +nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, + struct gl_buffer_object *obj) +{ + GLvoid *out; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", + _mesa_lookup_enum_by_nr(target), + (GLuint)offset, (GLuint)size, data, obj); + + out = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, obj); + _mesa_memcpy(out + offset, data, size); + nouveau_bo_dirty_linear(ctx, GL_FALSE, offset, size, obj); + nouveau_bo_unmap(ctx, obj); +} + +static void +nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, GLvoid *data, + struct gl_buffer_object *obj) +{ + const GLvoid *in; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", + _mesa_lookup_enum_by_nr(target), + (GLuint)offset, (GLuint)size, data, obj); + + in = nouveau_bo_map(ctx, GL_READ_ONLY_ARB, obj); + _mesa_memcpy(data, in + offset, size); + nouveau_bo_unmap(ctx, obj); +} + +static void * +nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access, + struct gl_buffer_object *obj) +{ + DEBUG("target=%s, access=%s, obj=%p\n", + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(access), + obj + ); + + /* Already mapped.. */ + if (obj->Pointer) + return NULL; + + /* Have to pass READ_WRITE here, nouveau_bo_map will only ensure that + * the cpu_mem buffer is up-to-date if we ask for read access. + * + * However, even if the client only asks for write access, we're still + * forced to reupload the entire buffer. So, we need the cpu_mem buffer + * to have the correct data all the time. + */ + obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj); + + /* The GL spec says that a client attempting to write to a bufferobj + * mapped READ_ONLY object may have unpredictable results, possibly + * even program termination. + * + * We're going to use this, and only mark the buffer as dirtied if + * the client asks for write access. + */ + if (target != GL_READ_ONLY_ARB) { + /* We have no way of knowing what was modified by the client, + * so the entire buffer gets dirtied. */ + nouveau_bo_dirty_all(ctx, GL_FALSE, obj); + } + + return obj->Pointer; +} + +static GLboolean +nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ + DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj); + + assert(obj->Pointer); + + nouveau_bo_unmap(ctx, obj); + obj->Pointer = NULL; + return GL_TRUE; +} + +void +nouveauInitBufferObjects(GLcontext *ctx) +{ + ctx->Driver.BindBuffer = nouveauBindBuffer; + ctx->Driver.NewBufferObject = nouveauNewBufferObject; + ctx->Driver.DeleteBuffer = nouveauDeleteBuffer; + ctx->Driver.BufferData = nouveauBufferData; + ctx->Driver.BufferSubData = nouveauBufferSubData; + ctx->Driver.GetBufferSubData = nouveauGetBufferSubData; + ctx->Driver.MapBuffer = nouveauMapBuffer; + ctx->Driver.UnmapBuffer = nouveauUnmapBuffer; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h new file mode 100644 index 00000000000..932450fd877 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -0,0 +1,77 @@ +#ifndef __NOUVEAU_BUFFEROBJ_H__ +#define __NOUVEAU_BUFFEROBJ_H__ + +#include "mtypes.h" +#include "nouveau_buffers.h" + +#define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE) +#define NOUVEAU_BO_AGP_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) + +typedef struct nouveau_bufferobj_region_t { + uint32_t start; + uint32_t end; +} nouveau_bufferobj_region; + +typedef struct nouveau_bufferobj_dirty_t { + nouveau_bufferobj_region *dirty; + int nr_dirty; +} nouveau_bufferobj_dirty; + +typedef struct nouveau_buffer_object_t { + /* Base class, must be first */ + struct gl_buffer_object mesa; + + GLboolean mapped; + GLenum usage; + + /* Memory used for GPU access to the buffer*/ + GLuint gpu_mem_flags; + nouveau_mem * gpu_mem; + nouveau_bufferobj_dirty gpu_dirty; + + /* Memory used for CPU access to the buffer */ + GLuint cpu_mem_flags; + nouveau_mem * cpu_mem; + GLvoid * cpu_mem_sys; + nouveau_bufferobj_dirty cpu_dirty; +} nouveau_buffer_object; + +extern void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, const GLvoid *data, GLenum usage, + struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void * +nouveau_bo_map(GLcontext *ctx, GLenum usage, struct gl_buffer_object *bo); + +extern void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo); + +extern uint32_t +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void +nouveauInitBufferObjects(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c new file mode 100644 index 00000000000..b54f68f4023 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -0,0 +1,434 @@ +#include "utils.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "fbobject.h" + +#include "nouveau_context.h" +#include "nouveau_buffers.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" + +#define MAX_MEMFMT_LENGTH 32768 + +/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */ +GLboolean +nouveau_memformat_flat_emit(GLcontext *ctx, + nouveau_mem *dst, nouveau_mem *src, + GLuint dst_offset, GLuint src_offset, + GLuint size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t src_handle, dst_handle; + GLuint count; + + if (src_offset + size > src->size) { + MESSAGE("src out of nouveau_mem bounds\n"); + return GL_FALSE; + } + if (dst_offset + size > dst->size) { + MESSAGE("dst out of nouveau_mem bounds\n"); + return GL_FALSE; + } + + src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + src_offset += nouveau_mem_gpu_offset_get(ctx, src); + dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); + + BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); + OUT_RING (src_handle); + OUT_RING (dst_handle); + + count = (size / MAX_MEMFMT_LENGTH) + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); + + while (count--) { + GLuint length = (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; + + BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RING (src_offset); + OUT_RING (dst_offset); + OUT_RING (0); /* pitch in */ + OUT_RING (0); /* pitch out */ + OUT_RING (length); /* line length */ + OUT_RING (1); /* number of lines */ + OUT_RING ((1 << 8) /* dst_inc */ | (1 << 0) /* src_inc */); + OUT_RING (0); /* buffer notify? */ + FIRE_RING(); + + src_offset += length; + dst_offset += length; + size -= length; + } + + return GL_TRUE; +} + +void +nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + drm_nouveau_mem_free_t memf; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); + } + + if (mem->map) + drmUnmap(mem->map, mem->size); + memf.flags = mem->type; + memf.region_offset = mem->offset; + drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf)); + FREE(mem); +} + +nouveau_mem * +nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + drm_nouveau_mem_alloc_t mema; + nouveau_mem *mem; + int ret; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: requested: type=0x%x, size=0x%x, align=0x%x\n", + __func__, type, (GLuint)size, align); + } + + mem = CALLOC(sizeof(nouveau_mem)); + if (!mem) + return NULL; + + mema.flags = type; + mema.size = mem->size = size; + mema.alignment = align; + mem->map = NULL; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, + &mema, sizeof(mema)); + if (ret) { + FREE(mem); + return NULL; + } + mem->offset = mema.region_offset; + mem->type = mema.flags; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); + } + + if (type & NOUVEAU_MEM_MAPPED) + ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map); + if (ret) { + mem->map = NULL; + nouveau_mem_free(ctx, mem); + mem = NULL; + } + + return mem; +} + +uint32_t +nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (mem->type & NOUVEAU_MEM_FB) + return (uint32_t)mem->offset - nmesa->vram_phys; + else if (mem->type & NOUVEAU_MEM_AGP) + return (uint32_t)mem->offset - nmesa->agp_phys; + else + return 0xDEADF00D; +} + +static GLboolean +nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *nrb, + GLenum internalFormat) +{ + nrb->mesa.InternalFormat = internalFormat; + + /*TODO: We probably want to extend this a bit, and maybe make + * card-specific? + */ + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA8: + nrb->mesa._BaseFormat = GL_RGBA; + nrb->mesa._ActualFormat= GL_RGBA8; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 8; + nrb->mesa.GreenBits = 8; + nrb->mesa.BlueBits = 8; + nrb->mesa.AlphaBits = 8; + nrb->cpp = 4; + break; + case GL_RGB: + case GL_RGB5: + nrb->mesa._BaseFormat = GL_RGB; + nrb->mesa._ActualFormat= GL_RGB5; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 5; + nrb->mesa.GreenBits = 6; + nrb->mesa.BlueBits = 5; + nrb->mesa.AlphaBits = 0; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat= GL_DEPTH_COMPONENT16; + nrb->mesa.DataType = GL_UNSIGNED_SHORT; + nrb->mesa.DepthBits = 16; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + nrb->mesa._BaseFormat = GL_STENCIL_INDEX; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + default: + return GL_FALSE; + break; + } + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, + GLuint height) +{ + nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; + + if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { + fprintf(stderr, "%s: unknown internalFormat\n", __func__); + return GL_FALSE; + } + + /* If this buffer isn't statically alloc'd, we may need to ask the + * drm for more memory */ + if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { + GLuint pitch; + + /* align pitches to 64 bytes */ + pitch = ((width * nrb->cpp) + 63) & ~63; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + nrb->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, + pitch*height, + 0); + if (!nrb->mem) + return GL_FALSE; + + /* update nouveau_renderbuffer info */ + nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); + nrb->pitch = pitch; + } + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; +} + +static void +nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + FREE(nrb); +} + +nouveau_renderbuffer * +nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map, + GLuint offset, GLuint pitch, + __DRIdrawablePrivate *dPriv) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, 0); + + nouveau_renderbuffer_pixelformat(nrb, internalFormat); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + + nrb->dPriv = dPriv; + nrb->offset = offset; + nrb->pitch = pitch; + nrb->map = map; + } + + return nrb; +} + +static void +nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, + nouveau_renderbuffer *nrb) +{ + __DRIdrawablePrivate *dPriv = nrb->dPriv; + + nmesa->numClipRects = dPriv->numClipRects; + nmesa->pClipRects = dPriv->pClipRects; + nmesa->drawX = dPriv->x; + nmesa->drawY = dPriv->y; +} + +static void +nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, + nouveau_renderbuffer *nrb) +{ + nmesa->numClipRects = 1; + nmesa->pClipRects = &nmesa->osClipRect; + nmesa->osClipRect.x1 = 0; + nmesa->osClipRect.y1 = 0; + nmesa->osClipRect.x2 = nrb->mesa.Width; + nmesa->osClipRect.y2 = nrb->mesa.Height; + nmesa->drawX = 0; + nmesa->drawY = 0; +} + +void +nouveau_window_moved(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; + + nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + if (!nrb) + return; + + if (!nrb->dPriv) + nouveau_cliprects_renderbuffer_set(nmesa, nrb); + else + nouveau_cliprects_drawable_set(nmesa, nrb); + + /* Viewport depends on window size/position, nouveauCalcViewport + * will take care of calling the hw-specific WindowMoved + */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + /* Scissor depends on window position */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +GLboolean +nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; + nouveau_renderbuffer *depth; + + _mesa_update_framebuffer(ctx); + _mesa_update_draw_buffer_bounds(ctx); + + color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0]; + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) + depth = (nouveau_renderbuffer *)fb->_DepthBuffer->Wrapped; + else + depth = (nouveau_renderbuffer *)fb->_DepthBuffer; + + if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) + return GL_FALSE; + nouveau_window_moved(ctx); + + return GL_TRUE; +} + +static void +nouveauDrawBuffer(GLcontext *ctx, GLenum buffer) +{ + nouveau_build_framebuffer(ctx, ctx->DrawBuffer); +} + +static struct gl_framebuffer * +nouveauNewFramebuffer(GLcontext *ctx, GLuint name) +{ + return _mesa_new_framebuffer(ctx, name); +} + +static struct gl_renderbuffer * +nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, name); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + } + return &nrb->mesa; +} + +static void +nouveauBindFramebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb) +{ + nouveau_build_framebuffer(ctx, fb); +} + +static void +nouveauFramebufferRenderbuffer(GLcontext *ctx, + struct gl_framebuffer *fb, + GLenum attachment, + struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + nouveau_build_framebuffer(ctx, fb); +} + +static void +nouveauRenderTexture(GLcontext *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ +} + +static void +nouveauFinishRenderTexture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) +{ +} + +void +nouveauInitBufferFuncs(struct dd_function_table *func) +{ + func->DrawBuffer = nouveauDrawBuffer; + + func->NewFramebuffer = nouveauNewFramebuffer; + func->NewRenderbuffer = nouveauNewRenderbuffer; + func->BindFramebuffer = nouveauBindFramebuffer; + func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; + func->RenderTexture = nouveauRenderTexture; + func->FinishRenderTexture = nouveauFinishRenderTexture; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h new file mode 100644 index 00000000000..d86455184c2 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h @@ -0,0 +1,48 @@ +#ifndef __NOUVEAU_BUFFERS_H__ +#define __NOUVEAU_BUFFERS_H__ + +#include <stdint.h> +#include "mtypes.h" +#include "utils.h" +#include "renderbuffer.h" + +typedef struct nouveau_mem_t { + int type; + uint64_t offset; + uint64_t size; + void* map; +} nouveau_mem; + +extern nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, int type, + GLuint size, GLuint align); +extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem); +extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem); + +extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx, + nouveau_mem *dst, + nouveau_mem *src, + GLuint dst_offset, + GLuint src_offset, + GLuint size); + +typedef struct nouveau_renderbuffer_t { + struct gl_renderbuffer mesa; /* must be first! */ + __DRIdrawablePrivate *dPriv; + + nouveau_mem *mem; + void * map; + + int cpp; + uint32_t offset; + uint32_t pitch; +} nouveau_renderbuffer; + +extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, + GLvoid *map, GLuint offset, GLuint pitch, __DRIdrawablePrivate *dPriv); +extern void nouveau_window_moved(GLcontext *ctx); +extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *); +extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *ctx); + +extern void nouveauInitBufferFuncs(struct dd_function_table *func); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c new file mode 100644 index 00000000000..91f12f0d704 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -0,0 +1,17 @@ + +#include "nouveau_card.h" +#include "nouveau_reg.h" +#include "nouveau_drm.h" +#include "nouveau_card_list.h" + + +nouveau_card* nouveau_card_lookup(uint32_t device_id) +{ + int i; + for(i=0;i<sizeof(nouveau_card_list)/sizeof(nouveau_card)-1;i++) + if (nouveau_card_list[i].id==(device_id&0xffff)) + return &(nouveau_card_list[i]); + return NULL; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.h b/src/mesa/drivers/dri/nouveau/nouveau_card.h new file mode 100644 index 00000000000..8a4c5f2244e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.h @@ -0,0 +1,49 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#ifndef __NOUVEAU_CARD_H__ +#define __NOUVEAU_CARD_H__ + +#include "dri_util.h" +#include "drm.h" +#include "nouveau_drm.h" + +typedef struct nouveau_card_t { + uint16_t id; /* last 4 digits of pci id, last digit is always 0 */ + char* name; /* the user-friendly card name */ + uint32_t class_3d; /* the object class this card uses for 3D */ + uint32_t type; /* the major card family */ + uint32_t flags; +} +nouveau_card; + +#define NV_HAS_LMA 0x00000001 + +extern nouveau_card* nouveau_card_lookup(uint32_t device_id); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h new file mode 100644 index 00000000000..8ec5c4a188a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -0,0 +1,232 @@ +static nouveau_card nouveau_card_list[]={ +{0x0008, "EDGE 3D", 0, NV_03, 0}, +{0x0009, "EDGE 3D", 0, NV_03, 0}, +{0x0010, "Mutara V08", 0, NV_03, 0}, +{0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002A, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002B, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "Vanta/Vanta LT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002E, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002F, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0040, "GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0041, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0042, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0043, "NV40.3", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0044, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0045, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0046, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0047, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0048, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0049, "NV40GL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x004D, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x004E, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0090, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0091, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0092, "GeForce 7800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0093, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0098, "GeForce Go 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0099, "GE Force Go 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x009D, "Quadro FX4500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00A0, "Aladdin TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x00C0, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00C1, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00C2, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00C3, "Geforce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00C8, "GeForce Go 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00C9, "GeForce Go 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00CC, "Quadro FX Go1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00CD, "Quadro FX 3450/4000 SDI", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00CE, "Quadro FX 1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F0, "GeForce 6800/GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F1, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F2, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F3, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F4, "GeForce 6600 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F5, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F6, "GeForce 6600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F8, "Quadro FX 3400/4400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00F9, "GeForce 6800 Ultra/GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, +{0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, +{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x00FF, "GeForce PCX 4300", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0100, "GeForce 256 SDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, +{0x0101, "GeForce 256 DDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, +{0x0103, "Quadro", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, +{0x0110, "GeForce2 MX/MX 400", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, +{0x0111, "GeForce2 MX 100 DDR/200 DDR", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, +{0x0112, "GeForce2 Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, +{0x0113, "Quadro2 MXR/EX/Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, +{0x0140, "GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0141, "GeForce 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0142, "GeForce 6600 PCIe", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0144, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0145, "GeForce 6610 XL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0146, "Geforce Go 6600TE/6200TE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0148, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0149, "GeForce Go 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014A, "Quadro NVS 440", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014C, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, +{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, +{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, +{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, +{0x0161, "GeForce 6200 TurboCache(TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0162, "GeForce 6200 SE TurboCache (TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0163, "GeForce 6200 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0164, "GeForce Go 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0165, "Quadro NVS 285", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0166, "GeForce Go 6400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0167, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0168, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0170, "GeForce4 MX 460", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0171, "GeForce4 MX 440", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0172, "GeForce4 MX 420", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0173, "GeForce4 MX 440-SE", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0174, "GeForce4 440 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0175, "GeForce4 420 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0176, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0177, "GeForce4 460 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0178, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0179, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x017A, "Quadro4 200/400 NVS", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x017B, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x017C, "Quadro4 500 GoGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x017D, "GeForce4 410 Go 16M", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0181, "GeForce4 MX 440 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0182, "GeForce4 MX 440SE AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0183, "GeForce4 MX 420 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0185, "GeForce4 MX 4000 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0186, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0187, "GeForce4 488 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0188, "Quadro4 580 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x018A, "Quadro4 NVS AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x018B, "Quadro4 380 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x018C, "Quadro NVS 50 PCI", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x018D, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0191, "GeForce 8800 GTX", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0}, +{0x0193, "GeForce 8800 GTS", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0}, +{0x01A0, "GeForce2 MX Integrated Graphics", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, +{0x01D1, "GeForce 7300 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01D6, "GeForce Go 7200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01D7, "Quadro NVS 110M / GeForce Go 7300", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01D8, "GeForce Go 7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01DA, "Quadro NVS 110M", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01DF, "GeForce 7300 GS", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01F0, "GeForce4 MX - nForce GPU", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0211, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0212, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0215, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0218, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0298, "GeForce Go 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0299, "GeForce Go 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029A, "Quadro FX 2500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029B, "Quadro FX 1500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029C, "Quadro FX 5500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029D, "Quadro FX 3500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029E, "Quadro FX 1500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x029F, "Quadro FX 4500 X2", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031C, "NVIDIA Quadro FX Go700", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0391, "GeForce 7600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0392, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0393, "GeForce 7300 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x0398, "GeForce Go 7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x03D0, "GeForce 6100 nForce 430", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x03D1, "GeForce 6100 nForce 405", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x03D2, "GeForce 6100 nForce 400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x03D5, "GeForce 6100 nForce 420", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0008, "NV1", 0, NV_03, 0}, +{0x0009, "DAC64", 0, NV_03, 0}, +{0x0018, "Riva128", 0, NV_03, 0}, +{0x0019, "Riva128ZX", 0, NV_03, 0}, +{0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "VTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x00A0, "ITNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +}; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c new file mode 100644 index 00000000000..f811dc1b72e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -0,0 +1,371 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "simple_list.h" +#include "imports.h" +#include "matrix.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "framebuffer.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vp_build.h" + +#include "drivers/common/driverfuncs.h" + +#include "nouveau_context.h" +#include "nouveau_driver.h" +//#include "nouveau_state.h" +#include "nouveau_span.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_tex.h" +#include "nouveau_msg.h" +#include "nouveau_reg.h" +#include "nouveau_lock.h" +#include "nouveau_query.h" +#include "nv04_swtcl.h" +#include "nv10_swtcl.h" + +#include "vblank.h" +#include "utils.h" +#include "texmem.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ + +#ifndef NOUVEAU_DEBUG +int NOUVEAU_DEBUG = 0; +#endif + +static const struct dri_debug_control debug_control[] = +{ + { "shaders" , DEBUG_SHADERS }, + { "mem" , DEBUG_MEM }, + { "bufferobj" , DEBUG_BUFFEROBJ }, + { NULL , 0 } +}; + +#define need_GL_ARB_vertex_program +#define need_GL_ARB_occlusion_query +#include "extension_helper.h" + +const struct dri_extension common_extensions[] = +{ + { NULL, 0 } +}; + +const struct dri_extension nv10_extensions[] = +{ + { NULL, 0 } +}; + +const struct dri_extension nv20_extensions[] = +{ + { NULL, 0 } +}; + +const struct dri_extension nv30_extensions[] = +{ + { "GL_ARB_fragment_program", NULL }, + { NULL, 0 } +}; + +const struct dri_extension nv40_extensions[] = +{ + /* ARB_vp can be moved to nv20/30 once the shader backend has been + * written for those cards. + */ + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, + { NULL, 0 } +}; + +const struct dri_extension nv50_extensions[] = +{ + { NULL, 0 } +}; + +/* Create the device specific context. + */ +GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct dd_function_table functions; + nouveauContextPtr nmesa; + nouveauScreenPtr screen; + + /* Allocate the context */ + nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) ); + if ( !nmesa ) + return GL_FALSE; + + nmesa->driContext = driContextPriv; + nmesa->driScreen = sPriv; + nmesa->driDrawable = NULL; + nmesa->hHWContext = driContextPriv->hHWContext; + nmesa->driHwLock = &sPriv->pSAREA->lock; + nmesa->driFd = sPriv->fd; + + nmesa->screen = (nouveauScreenPtr)(sPriv->private); + screen=nmesa->screen; + + /* Create the hardware context */ + if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL, + &nmesa->vram_phys)) + return GL_FALSE; + if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL, + &nmesa->agp_phys)) + return GL_FALSE; + if (!nouveauFifoInit(nmesa)) + return GL_FALSE; + nouveauObjectInit(nmesa); + + + /* Init default driver functions then plug in our nouveau-specific functions + * (the texture functions are especially important) + */ + _mesa_init_driver_functions( &functions ); + nouveauDriverInitFunctions( &functions ); + nouveauTexInitFunctions( &functions ); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + nmesa->glCtx = _mesa_create_context(glVisual, shareCtx, + &functions, (void *) nmesa); + if (!nmesa->glCtx) { + FREE(nmesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = nmesa; + ctx = nmesa->glCtx; + + /* Parse configuration files */ + driParseConfigFiles (&nmesa->optionCache, &screen->optionCache, + screen->driScreen->myNum, "nouveau"); + + nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA + + screen->sarea_priv_offset); + + /* Enable any supported extensions */ + driInitExtensions(ctx, common_extensions, GL_TRUE); + if (nmesa->screen->card->type >= NV_10) + driInitExtensions(ctx, nv10_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_20) + driInitExtensions(ctx, nv20_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_30) + driInitExtensions(ctx, nv30_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_40) + driInitExtensions(ctx, nv40_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_50) + driInitExtensions(ctx, nv50_extensions, GL_FALSE); + + nmesa->current_primitive = -1; + + nouveauShaderInitFuncs(ctx); + /* Install Mesa's fixed-function texenv shader support */ + if (nmesa->screen->card->type >= NV_40) + ctx->_MaintainTexEnvProgram = GL_TRUE; + + /* Initialize the swrast */ + _swrast_CreateContext( ctx ); + _vbo_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + _math_matrix_ctr(&nmesa->viewport); + + nouveauDDInitStateFuncs( ctx ); + nouveauSpanInitFunctions( ctx ); + nouveauDDInitState( nmesa ); + switch(nmesa->screen->card->type) + { + case NV_03: + //nv03TriInitFunctions( ctx ); + break; + case NV_04: + case NV_05: + nv04TriInitFunctions( ctx ); + break; + case NV_10: + case NV_20: + case NV_30: + case NV_40: + case NV_44: + case NV_50: + default: + nv10TriInitFunctions( ctx ); + break; + } + + nouveauInitBufferObjects(ctx); + if (!nouveauSyncInitFuncs(ctx)) + return GL_FALSE; + nouveauQueryInitFuncs(ctx); + nmesa->hw_func.InitCard(nmesa); + nouveauInitState(ctx); + + driContextPriv->driverPrivate = (void *)nmesa; + + NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ), + debug_control ); + + if (driQueryOptionb(&nmesa->optionCache, "no_rast")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1); + } + + return GL_TRUE; +} + +/* Destroy the device specific context. */ +void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate; + + assert(nmesa); + if ( nmesa ) { + /* free the option cache */ + driDestroyOptionCache (&nmesa->optionCache); + + FREE( nmesa ); + } + +} + + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate; + struct gl_framebuffer *draw_fb = + (struct gl_framebuffer*)driDrawPriv->driverPrivate; + struct gl_framebuffer *read_fb = + (struct gl_framebuffer*)driReadPriv->driverPrivate; + + driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq ); + nmesa->driDrawable = driDrawPriv; + + _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, + driDrawPriv->w, driDrawPriv->h); + if (draw_fb != read_fb) { + _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, + driReadPriv->w, + driReadPriv->h); + } + _mesa_make_current(nmesa->glCtx, draw_fb, read_fb); + + nouveau_build_framebuffer(nmesa->glCtx, + driDrawPriv->driverPrivate); + } else { + _mesa_make_current( NULL, NULL, NULL ); + } + + return GL_TRUE; +} + + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, + __DRIdrawablePrivate *dPriv) +{ + struct gl_framebuffer *fb; + nouveau_renderbuffer *src, *dst; + drm_clip_rect_t *box; + int nbox, i; + + fb = (struct gl_framebuffer *)dPriv->driverPrivate; + dst = (nouveau_renderbuffer*) + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + src = (nouveau_renderbuffer*) + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + +#ifdef ALLOW_MULTI_SUBCHANNEL + LOCK_HARDWARE(nmesa); + nbox = dPriv->numClipRects; + box = dPriv->pClipRects; + + if (nbox) { + BEGIN_RING_SIZE(NvSubCtxSurf2D, + NV10_CONTEXT_SURFACES_2D_FORMAT, 4); + if (src->mesa._ActualFormat == GL_RGBA8) + OUT_RING (6); /* X8R8G8B8 */ + else + OUT_RING (4); /* R5G6B5 */ + OUT_RING ((dst->pitch << 16) | src->pitch); + OUT_RING (src->offset); + OUT_RING (dst->offset); + } + + for (i=0; i<nbox; i++, box++) { + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3); + OUT_RING (((box->y1 - dPriv->y) << 16) | + (box->x1 - dPriv->x)); + OUT_RING ((box->y1 << 16) | box->x1); + OUT_RING (((box->y2 - box->y1) << 16) | + (box->x2 - box->x1)); + } + + UNLOCK_HARDWARE(nmesa); +#endif +} + +void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate; + + if (nmesa->glCtx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers(nmesa->glCtx); + nouveauDoSwapBuffers(nmesa, dPriv); + } + + } +} + +void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, + int x, int y, int w, int h) +{ +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h new file mode 100644 index 00000000000..f61fcbb48c0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -0,0 +1,233 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "dri_util.h" +#include "drm.h" +#include "nouveau_drm.h" + +#include "mtypes.h" +#include "tnl/t_vertex.h" + +#include "nouveau_screen.h" +#include "nouveau_state_cache.h" +#include "nouveau_buffers.h" +#include "nouveau_shader.h" +#include "nouveau_sync.h" + +#include "xmlconfig.h" + +typedef struct nouveau_fifo_t{ + u_int32_t* buffer; + u_int32_t* mmio; + u_int32_t put_base; + u_int32_t current; + u_int32_t put; + u_int32_t free; + u_int32_t max; +} +nouveau_fifo; + +#define TAG(x) nouveau##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +/* Subpixel offsets for window coordinates (triangles): */ +#define SUBPIXEL_X (0.0F) +#define SUBPIXEL_Y (0.125F) + +struct nouveau_context; + +typedef void (*nouveau_tri_func)( struct nouveau_context*, + nouveauVertex *, + nouveauVertex *, + nouveauVertex * ); + +typedef void (*nouveau_line_func)( struct nouveau_context*, + nouveauVertex *, + nouveauVertex * ); + +typedef void (*nouveau_point_func)( struct nouveau_context*, + nouveauVertex * ); + +typedef struct nouveau_hw_func_t { + /* Initialise any card-specific non-GL related state */ + GLboolean (*InitCard)(struct nouveau_context *); + /* Update buffer offset/pitch/format */ + GLboolean (*BindBuffers)(struct nouveau_context *, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth); + /* Update anything that depends on the window position/size */ + void (*WindowMoved)(struct nouveau_context *); +} nouveau_hw_func; + +typedef struct nouveau_context { + /* Mesa context */ + GLcontext *glCtx; + + /* The per-context fifo */ + nouveau_fifo fifo; + + /* The read-only regs */ + volatile unsigned char* mmio; + + /* Physical addresses of AGP/VRAM apertures */ + uint64_t vram_phys; + uint64_t agp_phys; + + /* Channel synchronisation */ + nouveau_notifier *syncNotifier; + + /* ARB_occlusion_query / EXT_timer_query */ + GLuint query_object_max; + GLboolean * query_alloc; + nouveau_notifier *queryNotifier; + + /* Additional hw-specific functions */ + nouveau_hw_func hw_func; + + /* FIXME : do we want to put all state into a separate struct ? */ + /* State for tris */ + GLuint color_offset; + GLuint specular_offset; + + /* Vertex state */ + GLuint vertex_size; + GLubyte *verts; + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + + /* Color buffer clear value */ + uint32_t clear_color_value; + + /* Depth/stencil clear value */ + uint32_t clear_value; + + /* Light state */ + GLboolean lighting_enabled; + uint32_t enabled_lights; + + /* Cached state */ + nouveau_state_cache state_cache; + + /* The drawing fallbacks */ + GLuint Fallback; + nouveau_tri_func draw_tri; + nouveau_line_func draw_line; + nouveau_point_func draw_point; + + /* Cliprects information */ + GLuint numClipRects; + drm_clip_rect_t *pClipRects; + drm_clip_rect_t osClipRect; + GLuint drawX, drawY; + + /* The rendering context information */ + GLenum current_primitive; /* the current primitive enum */ + DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */ + + /* Shader state */ + nvsFunc VPfunc; + nvsFunc FPfunc; + nouveauShader *current_fragprog; + nouveauShader *current_vertprog; + nouveauShader *passthrough_vp; + nouveauShader *passthrough_fp; + + nouveauScreenRec *screen; + drm_nouveau_sarea_t *sarea; + + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIscreenPrivate *driScreen; /* DRI screen */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + GLint lastStamp; + + drm_context_t hHWContext; + drm_hw_lock_t *driHwLock; + int driFd; + + /* Configuration cache */ + driOptionCache optionCache; + + /* vblank stuff */ + uint32_t vblank_flags; + uint32_t vblank_seq; + + GLuint new_state; + GLuint new_render_state; + GLuint render_index; + GLmatrix viewport; + GLfloat depth_scale; + +}nouveauContextRec, *nouveauContextPtr; + + +#define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) + +/* Flags for software fallback cases: */ +#define NOUVEAU_FALLBACK_TEXTURE 0x0001 +#define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002 +#define NOUVEAU_FALLBACK_READ_BUFFER 0x0004 +#define NOUVEAU_FALLBACK_STENCIL 0x0008 +#define NOUVEAU_FALLBACK_RENDER_MODE 0x0010 +#define NOUVEAU_FALLBACK_LOGICOP 0x0020 +#define NOUVEAU_FALLBACK_SEP_SPECULAR 0x0040 +#define NOUVEAU_FALLBACK_BLEND_EQ 0x0080 +#define NOUVEAU_FALLBACK_BLEND_FUNC 0x0100 +#define NOUVEAU_FALLBACK_PROJTEX 0x0200 +#define NOUVEAU_FALLBACK_DISABLE 0x0400 + + +extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void nouveauDestroyContext( __DRIcontextPrivate * ); + +extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); + +extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ); + +extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv); + +extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, + int x, int y, int w, int h); + +/* Debugging utils: */ +extern int NOUVEAU_DEBUG; + +#define DEBUG_SHADERS 0x00000001 +#define DEBUG_MEM 0x00000002 +#define DEBUG_BUFFEROBJ 0x00000004 + +#endif /* __NOUVEAU_CONTEXT_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h new file mode 100644 index 00000000000..c9b2d590077 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h @@ -0,0 +1,44 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin, Sylvain Munaut +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + + +#define NV03_STATUS 0x004006b0 +#define NV04_STATUS 0x00400700 + +#define NV03_FIFO_REGS_SIZE 0x10000 +# define NV03_FIFO_REGS_DMAPUT 0x00000040 +# define NV03_FIFO_REGS_DMAGET 0x00000044 + +/* Fifo commands. These are not regs, neither masks */ +#define NV03_FIFO_CMD_JUMP 0x20000000 +#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc +#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) + + +#define NONINC_METHOD 0x40000000 + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_dri.h b/src/mesa/drivers/dri/nouveau/nouveau_dri.h new file mode 100644 index 00000000000..ce3c3fb9cc4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +typedef struct { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +} NOUVEAUDRIRec, *NOUVEAUDRIPtr; + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c new file mode 100644 index 00000000000..00956aa8f8b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -0,0 +1,146 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +//#include "nouveau_state.h" +#include "nouveau_lock.h" +#include "nouveau_fifo.h" +#include "nouveau_driver.h" +#include "swrast/swrast.h" + +#include "context.h" +#include "framebuffer.h" + +#include "utils.h" + +/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */ +GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, + unsigned int param, + uint64_t* value) +{ + drm_nouveau_getparam_t getp; + + getp.param = param; + if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM, + &getp, sizeof(getp))) + return GL_FALSE; + *value = getp.value; + return GL_TRUE; +} + +/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */ +GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, + unsigned int param, + uint64_t value) +{ + drm_nouveau_setparam_t setp; + + setp.param = param; + setp.value = value; + if (drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_SETPARAM, &setp, + sizeof(setp))) + return GL_FALSE; + return GL_TRUE; +} + +/* Return the width and height of the current color buffer */ +static void nouveauGetBufferSize( GLframebuffer *buffer, + GLuint *width, GLuint *height ) +{ + GET_CURRENT_CONTEXT(ctx); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + LOCK_HARDWARE( nmesa ); + *width = nmesa->driDrawable->w; + *height = nmesa->driDrawable->h; + UNLOCK_HARDWARE( nmesa ); +} + +/* glGetString */ +static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + static char buffer[128]; + const char * card_name = "Unknown"; + GLuint agp_mode = 0; + + switch ( name ) { + case GL_VENDOR: + return (GLubyte *)DRIVER_AUTHOR; + + case GL_RENDERER: + card_name=nmesa->screen->card->name; + + switch(nmesa->screen->bus_type) + { + case NV_PCI: + case NV_PCIE: + default: + agp_mode=0; + break; + case NV_AGP: + agp_mode=nmesa->screen->agp_mode; + break; + } + driGetRendererString( buffer, card_name, DRIVER_DATE, + agp_mode ); + return (GLubyte *)buffer; + default: + return NULL; + } +} + +/* glFlush */ +static void nouveauFlush( GLcontext *ctx ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + FIRE_RING(); +} + +/* glFinish */ +static void nouveauFinish( GLcontext *ctx ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveauFlush( ctx ); + nouveauWaitForIdle( nmesa ); +} + +/* glClear */ +static void nouveauClear( GLcontext *ctx, GLbitfield mask ) +{ + // XXX we really should do something here... +} + +void nouveauDriverInitFunctions( struct dd_function_table *functions ) +{ + functions->GetBufferSize = nouveauGetBufferSize; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->GetString = nouveauGetString; + functions->Flush = nouveauFlush; + functions->Finish = nouveauFinish; + functions->Clear = nouveauClear; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h new file mode 100644 index 00000000000..6164012b5b7 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -0,0 +1,42 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NOUVEAU_DRIVER_H__ +#define __NOUVEAU_DRIVER_H__ + +#define DRIVER_DATE "20060219" +#define DRIVER_AUTHOR "Stephane Marchesin" + +extern void nouveauDriverInitFunctions( struct dd_function_table *functions ); +extern GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, unsigned int param, + uint64_t *value); +extern GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, unsigned int param, + uint64_t value); + +#endif /* __NOUVEAU_DRIVER_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c new file mode 100644 index 00000000000..7af9f1e3c2f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -0,0 +1,137 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#include "vblank.h" +#include <errno.h> +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" +#include "nouveau_context.h" +#include "nouveau_msg.h" +#include "nouveau_fifo.h" +#include "nouveau_lock.h" +#include "nouveau_object.h" +#include "nouveau_sync.h" + + +#define RING_SKIPS 8 + +void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) +{ +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + u_int32_t fifo_get; + while(nmesa->fifo.free < size+1) { + fifo_get = NV_FIFO_READ_GET(); + + if(nmesa->fifo.put >= fifo_get) { + nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; + if(nmesa->fifo.free < size+1) { + OUT_RING(NV03_FIFO_CMD_JUMP | nmesa->fifo.put_base); + if(fifo_get <= RING_SKIPS) { + if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */ + NV_FIFO_WRITE_PUT(RING_SKIPS + 1); + do { fifo_get = NV_FIFO_READ_GET(); } + while(fifo_get <= RING_SKIPS); + } + NV_FIFO_WRITE_PUT(RING_SKIPS); + nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS; + nmesa->fifo.free = fifo_get - (RING_SKIPS + 1); + } + } else + nmesa->fifo.free = fifo_get - nmesa->fifo.current - 1; + } +} + +/* + * Wait for the channel to be idle + */ +void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) +{ + /* Wait for FIFO idle */ + FIRE_RING(); + while(RING_AHEAD()>0); + + /* Wait on notifier to indicate all commands in the channel have + * been completed. + */ + nouveau_notifier_wait_nop(nmesa->glCtx, nmesa->syncNotifier, NvSub3D); +} + +void nouveauWaitForIdle(nouveauContextPtr nmesa) +{ + LOCK_HARDWARE(nmesa); + nouveauWaitForIdleLocked(nmesa); + UNLOCK_HARDWARE(nmesa); +} + +// here we call the fifo initialization ioctl and fill in stuff accordingly +GLboolean nouveauFifoInit(nouveauContextPtr nmesa) +{ + drm_nouveau_fifo_alloc_t fifo_init; + int i; + +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + + int ret; + ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); + if (ret) { + FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); + return GL_FALSE; + } + + ret = drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer); + if (ret) { + FATAL("Unable to map the fifo (returned %d)\n",ret); + return GL_FALSE; + } + ret = drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio); + if (ret) { + FATAL("Unable to map the control regs (returned %d)\n",ret); + return GL_FALSE; + } + + /* Setup our initial FIFO tracking params */ + nmesa->fifo.put_base = fifo_init.put_base; + nmesa->fifo.current = 0; + nmesa->fifo.put = 0; + nmesa->fifo.max = (fifo_init.cmdbuf_size >> 2) - 1; + nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; + + for (i=0; i<RING_SKIPS; i++) + OUT_RING(0); + nmesa->fifo.free -= RING_SKIPS; + + MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); + return GL_TRUE; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h new file mode 100644 index 00000000000..490089f71a4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -0,0 +1,179 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NOUVEAU_FIFO_H__ +#define __NOUVEAU_FIFO_H__ + +#include "nouveau_context.h" +#include "nouveau_ctrlreg.h" +#include "nouveau_state_cache.h" + +//#define NOUVEAU_RING_TRACE +//#define NOUVEAU_RING_DEBUG +//#define NOUVEAU_STATE_CACHE_DISABLE + +#ifndef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 0 +#else +#undef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 1 +#endif + +#define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) + +#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) +#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; +#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) +#define NV_FIFO_WRITE_PUT(val) do { \ + if (NOUVEAU_RING_TRACE) {\ + printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \ + fflush(stdout); \ + sleep(1); \ + } \ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \ +} while(0) + +/* + * Ring/fifo interface + * + * - Begin a ring section with BEGIN_RING_SIZE (if you know the full size in advance) + * - Output stuff to the ring with either OUT_RINGp (outputs a raw mem chunk), OUT_RING (1 uint32_t) or OUT_RINGf (1 float) + * - RING_AVAILABLE returns the available fifo (in uint32_ts) + * - RING_AHEAD returns how much ahead of the last submission point we are + * - FIRE_RING fires whatever we have that wasn't fired before + * - WAIT_RING waits for size (in uint32_ts) to be available in the fifo + */ + +/* Enable for ring debugging. Prints out writes to the ring buffer + * but does not actually write to it. + */ +#ifdef NOUVEAU_RING_DEBUG + +#define OUT_RINGp(ptr,sz) do { \ +uint32_t* p=(uint32_t*)(ptr); \ +int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;i<sz;i++) printf(" 0x%08x %f\n", *(p+i), *((float*)(p+i))); \ +}while(0) + +#define OUT_RING(n) do { \ + printf("OUT_RINGn: 0x%08x (%s)\n", n, __func__); \ +}while(0) + +#define OUT_RINGf(n) do { \ + printf("OUT_RINGf: %.04f (%s)\n", n, __func__); \ +}while(0) + +#else + +#define OUT_RINGp(ptr,sz) do{ \ + if (NOUVEAU_RING_TRACE) { \ + uint32_t* p=(uint32_t*)(ptr); \ + int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;i<sz;i++) printf(" [0x%08x] 0x%08x %f\n", (nmesa->fifo.current+i) << 2, *(p+i), *((float*)(p+i))); \ + } \ + memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ + nmesa->fifo.current+=(sz); \ +}while(0) + +#define OUT_RING(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \ +nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ +}while(0) + +#define OUT_RINGf(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \ +*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ +}while(0) + +#endif + +#define BEGIN_RING_SIZE(subchannel,tag,size) do { \ + nouveau_state_cache_flush(nmesa); \ + if (nmesa->fifo.free <= (size)) \ + WAIT_RING(nmesa,(size)); \ + OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ + nmesa->fifo.free -= ((size) + 1); \ +}while(0) + +extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); +extern void nouveau_state_cache_flush(nouveauContextPtr nmesa); +extern void nouveau_state_cache_init(nouveauContextPtr nmesa); + +#ifdef NOUVEAU_STATE_CACHE_DISABLE +#define BEGIN_RING_CACHE(subc,tag,size) BEGIN_RING_SIZE((subc), (tag), (size)) +#define OUT_RING_CACHE(n) OUT_RING((n)) +#define OUT_RING_CACHEf(n) OUT_RINGf((n)) +#define OUT_RING_CACHEp(ptr, sz) OUT_RINGp((ptr), (sz)) +#else +#define BEGIN_RING_CACHE(subchannel,tag,size) do { \ + nmesa->state_cache.dirty=1; \ + nmesa->state_cache.current_pos=((tag)/4); \ +}while(0) + +#define OUT_RING_CACHE(n) do { \ + if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \ + } \ + nmesa->state_cache.current_pos++; \ +}while(0) + +#define OUT_RING_CACHEf(n) do { \ + if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ + (*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ + } \ + nmesa->state_cache.current_pos++; \ +}while(0) + +#define OUT_RING_CACHEp(ptr,sz) do { \ +uint32_t* p=(uint32_t*)(ptr); \ +int i; for(i=0;i<sz;i++) OUT_RING_CACHE(*(p+i)); \ +}while(0) +#endif + +#define RING_AVAILABLE() (nmesa->fifo.free-1) + +#define RING_AHEAD() ((nmesa->fifo.put<=nmesa->fifo.current)?(nmesa->fifo.current-nmesa->fifo.put):nmesa->fifo.max-nmesa->fifo.put+nmesa->fifo.current) + +#define FIRE_RING() do { \ + if (nmesa->fifo.current!=nmesa->fifo.put) { \ + nmesa->fifo.put=nmesa->fifo.current; \ + NV_FIFO_WRITE_PUT(nmesa->fifo.put); \ + } \ +}while(0) + +extern void nouveauWaitForIdle(nouveauContextPtr nmesa); +extern void nouveauWaitForIdleLocked(nouveauContextPtr nmesa); +extern GLboolean nouveauFifoInit(nouveauContextPtr nmesa); + +#endif /* __NOUVEAU_FIFO_H__ */ + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c new file mode 100644 index 00000000000..c119d14dd75 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.c @@ -0,0 +1,81 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#include "nouveau_context.h" +#include "nouveau_lock.h" + +#include "drirenderbuffer.h" +#include "framebuffer.h" + + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = nmesa->driDrawable; + __DRIscreenPrivate *sPriv = nmesa->driScreen; + drm_nouveau_sarea_t *sarea = nmesa->sarea; + + drmGetLock( nmesa->driFd, nmesa->hHWContext, flags ); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + + /* If timestamps don't match, the window has been changed */ + if (nmesa->lastStamp != dPriv->lastStamp) { + struct gl_framebuffer *fb = (struct gl_framebuffer *)dPriv->driverPrivate; + + /* _mesa_resize_framebuffer will take care of calling the renderbuffer's + * AllocStorage function if we need more memory to hold it */ + if (fb->Width != dPriv->w || fb->Height != dPriv->h) { + _mesa_resize_framebuffer(nmesa->glCtx, fb, dPriv->w, dPriv->h); + /* resize buffers, will call nouveau_window_moved */ + nouveau_build_framebuffer(nmesa->glCtx, fb); + } else { + nouveau_window_moved(nmesa->glCtx); + } + + nmesa->lastStamp = dPriv->lastStamp; + } + + nmesa->numClipRects = dPriv->numClipRects; + nmesa->pClipRects = dPriv->pClipRects; + +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.h b/src/mesa/drivers/dri/nouveau/nouveau_lock.h new file mode 100644 index 00000000000..38bb0014258 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.h @@ -0,0 +1,69 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#ifndef __NOUVEAU_LOCK_H__ +#define __NOUVEAU_LOCK_H__ + +#include "nouveau_context.h" + +extern void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags ); + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( nmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( nmesa->driHwLock, nmesa->hHWContext, \ + (DRM_LOCK_HELD | nmesa->hHWContext), __ret ); \ + if ( __ret ) \ + nouveauGetLock( nmesa, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( nmesa ) \ + do { \ + DRM_UNLOCK( nmesa->driFd, \ + nmesa->driHwLock, \ + nmesa->hHWContext ); \ + DEBUG_RESET(); \ + } while (0) + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + + +#endif /* __NOUVEAU_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_msg.h b/src/mesa/drivers/dri/nouveau/nouveau_msg.h new file mode 100644 index 00000000000..5dea2189c72 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_msg.h @@ -0,0 +1,67 @@ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. +Copyright 2006 Stephane Marchesin. All Rights Reserved + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <[email protected]> + * Nicolai Haehnle <[email protected]> + */ + + +#ifndef __NOUVEAU_MSG_H__ +#define __NOUVEAU_MSG_H__ + +#define WARN_ONCE(a, ...) do {\ + static int warn##__LINE__=1;\ + if(warn##__LINE__){\ + fprintf(stderr, "*********************************WARN_ONCE*********************************\n");\ + fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__);\ + fprintf(stderr, a, ## __VA_ARGS__);\ + fprintf(stderr, "***************************************************************************\n");\ + warn##__LINE__=0;\ + } \ + }while(0) + +#define MESSAGE(a, ...) do{\ + fprintf(stderr, "************************************INFO***********************************\n");\ + fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \ + fprintf(stderr, a, ## __VA_ARGS__);\ + fprintf(stderr, "***************************************************************************\n");\ + }while(0) + +#define FATAL(a, ...) do{\ + fprintf(stderr, "***********************************FATAL***********************************\n");\ + fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \ + fprintf(stderr, a, ## __VA_ARGS__);\ + fprintf(stderr, "***************************************************************************\n");\ + }while(0) + +#endif /* __NOUVEAU_MSG_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c new file mode 100644 index 00000000000..302009c8b17 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -0,0 +1,101 @@ + +#include "nouveau_fifo.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" + + +GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) +{ + drm_nouveau_object_init_t cto; + int ret; + + cto.handle = handle; + cto.class = class; + cto.flags = flags; + cto.dma0= dma_in; + cto.dma1= dma_out; + cto.dma_notifier = dma_notifier; + ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto)); + + return ret == 0; +} + +GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, + uint32_t handle, + uint32_t offset, + uint32_t size, + int target, + int access) +{ + drm_nouveau_dma_object_init_t dma; + int ret; + + dma.handle = handle; + dma.target = target; + dma.access = access; + dma.offset = offset; + dma.size = size; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_DMA_OBJECT_INIT, + &dma, sizeof(dma)); + return ret == 0; +} + +void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle) +{ + BEGIN_RING_SIZE(subchannel, 0, 1); + OUT_RING(handle); +} + +void nouveauObjectInit(nouveauContextPtr nmesa) +{ +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + +/* We need to know vram size.. and AGP size (and even if the card is AGP..) */ + nouveauCreateDmaObject( nmesa, NvDmaFB, + 0, (256*1024*1024), + 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/); + nouveauCreateDmaObject( nmesa, NvDmaAGP, + nmesa->agp_phys, (128*1024*1024), + 3 /* AGP */, 0 /* RW */); + + nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, + 0, 0, 0, 0); + if (nmesa->screen->card->type>=NV_10) { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, + NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } else { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, + NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } + nouveauCreateContextObject(nmesa, NvMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT, + 0, 0, 0, 0); + +#ifdef ALLOW_MULTI_SUBCHANNEL + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D); + BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + + nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit); + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1); + OUT_RING(NvCtxSurf2D); + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1); + OUT_RING(3); /* SRCCOPY */ + + nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat); +#endif + + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); +} + + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h new file mode 100644 index 00000000000..daad281029f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -0,0 +1,44 @@ +#ifndef __NOUVEAU_OBJECT_H__ +#define __NOUVEAU_OBJECT_H__ + +#include "nouveau_context.h" + +#define ALLOW_MULTI_SUBCHANNEL + +void nouveauObjectInit(nouveauContextPtr nmesa); + +enum DMAObjects { + Nv3D = 0x80000019, + NvCtxSurf2D = 0x80000020, + NvImageBlit = 0x80000021, + NvMemFormat = 0x80000022, + NvCtxSurf3D = 0x80000023, + NvDmaFB = 0xD0FB0001, + NvDmaAGP = 0xD0AA0001, + NvSyncNotify = 0xD0000001, + NvQueryNotify = 0xD0000002 +}; + +enum DMASubchannel { + NvSubCtxSurf2D = 0, + NvSubImageBlit = 1, + NvSubMemFormat = 2, + NvSubCtxSurf3D = 3, + NvSub3D = 7, +}; + +extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle); + +extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, + int handle, int class, + uint32_t flags, + uint32_t dma_in, + uint32_t dma_out, + uint32_t dma_notifier); +extern GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, + uint32_t handle, + uint32_t offset, + uint32_t size, + int target, + int access); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c new file mode 100644 index 00000000000..de3f5b0378b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* GL_ARB_occlusion_query support for NV20/30/40 */ + +#include "mtypes.h" + +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" +#include "nouveau_sync.h" +#include "nouveau_query.h" + +static struct gl_query_object * +nouveauNewQueryObject(GLcontext *ctx, GLuint id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq; + int i; + + for (i=0; i<nmesa->query_object_max; i++) + if (nmesa->query_alloc[i] == GL_FALSE) + break; + if (i==nmesa->query_object_max) + return NULL; + + nq = CALLOC_STRUCT(nouveau_query_object_t); + if (nq) { + nq->notifier_id = i; + + nq->mesa.Id = id; + nq->mesa.Result = 0; + nq->mesa.Active = GL_FALSE; + nq->mesa.Ready = GL_TRUE; + } + + return (struct gl_query_object *)nq; +} + +static void +nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1); + OUT_RING_CACHE (1); + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + case NV_30: + case NV_40: + case NV_44: + /* I don't think this is OCC_QUERY enable, but it *is* needed to make + * the SET_OBJECT7 notifier block work with STORE_RESULT. + * + * Also, this appears to reset the pixel pass counter */ + BEGIN_RING_SIZE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE, + 1); + OUT_RING (1); + /* Probably OCC_QUERY_ENABLE */ + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } +} + +static void +nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + int status; + + status = nouveau_notifier_status(nmesa->queryNotifier, + nq->notifier_id); + + q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED); + if (q->Ready) + q->Result = nouveau_notifier_return_val(nmesa->queryNotifier, + nq->notifier_id); +} + +static void +nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id, + NV_NOTIFY_STATE_STATUS_COMPLETED, 0); + nouveauUpdateQuery(ctx, target, q); +} + +static void +nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveau_query_object *nq = (nouveau_query_object *)q; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } + FIRE_RING(); + + /*XXX: wait for query to complete, mesa doesn't give the driver + * an interface to query the status of a query object so + * this has to stall the channel. + */ + nouveauWaitQueryResult(ctx, target, q); + + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (0); +} + +void +nouveauQueryInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->screen->card->type < NV_20) + return; + + nmesa->query_object_max = (0x4000 / 32); + nmesa->queryNotifier = + nouveau_notifier_new(ctx, NvQueryNotify, + nmesa->query_object_max); + nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean)); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + default: + break; + }; + + ctx->Driver.NewQueryObject = nouveauNewQueryObject; + ctx->Driver.BeginQuery = nouveauBeginQuery; + ctx->Driver.EndQuery = nouveauEndQuery; +#if 0 + ctx->Driver.UpdateQuery = nouveauUpdateQuery; + ctx->Driver.WaitQueryResult = nouveauWaitQueryResult; +#endif +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h new file mode 100644 index 00000000000..3ded41417e1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __NOUVEAU_QUERY_H__ +#define __NOUVEAU_QUERY_H__ + +typedef struct nouveau_query_object_t { + struct gl_query_object mesa; + + int notifier_id; +} nouveau_query_object; + +extern void nouveauQueryInitFuncs(GLcontext *ctx); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h new file mode 100644 index 00000000000..8758b538c85 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -0,0 +1,1505 @@ +/* + Autogenerated file, do not edit ! + +************************************************************************** + + Copyright (C) 2006 : + Dmitry Baryshkov, + Laurent Carlier, + Matthieu Castet, + Dawid Gajownik, + Jeremy Kolb, + Stephane Loeuillet, + Patrice Mandin, + Stephane Marchesin, + Serge Martin, + Sylvain Munaut, + Ben Skeggs, + Erik Waling, + koala_br, + sturmflut. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +************************************************************************** + + Created from objects.c rev. 1.398 +*/ + +#ifndef _NOUVEAU_REG_H +#define _NOUVEAU_REG_H + +/****************************************** +Object NV01_CONTEXT_CLIP_RECTANGLE used on: NV03 NV04 NV10 NV15 NV20 NV40 G70 +*/ +#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019 +# define NV01_CONTEXT_CLIP_RECTANGLE_SET_POINT 0x00000300 /* Parameters: x y */ +# define NV01_CONTEXT_CLIP_RECTANGLE_SET_SIZE 0x00000304 /* Parameters: width height */ + +/****************************************** +Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 +# define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 +# define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 +# define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 +# define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN 0x00000184 +# define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_OUT 0x00000188 +# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c +# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT 0x00000310 +# define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_IN 0x00000314 +# define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 +# define NV_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c +# define NV_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 +# define NV_MEMORY_TO_MEMORY_FORMAT_FORMAT 0x00000324 /* Parameters: src_inc dst_inc */ +# define NV_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 + +/****************************************** +Object NV03_PRIMITIVE_RASTER_OP used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV03_PRIMITIVE_RASTER_OP 0x00000043 +# define NV03_PRIMITIVE_RASTER_OP_NOTIFY 0x00000100 +# define NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY 0x00000180 +# define NV03_PRIMITIVE_RASTER_OP_LOGIC_OP 0x00000300 /* Parameters: logic_op */ + +/****************************************** +Object NV04_GDI_RECTANGLE_TEXT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV04_GDI_RECTANGLE_TEXT 0x0000004a +# define NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY 0x00000180 +# define NV04_GDI_RECTANGLE_TEXT_PATTERN 0x00000188 +# define NV04_GDI_RECTANGLE_TEXT_ROP5 0x0000018c +# define NV04_GDI_RECTANGLE_TEXT_SURFACE 0x00000198 +# define NV04_GDI_RECTANGLE_TEXT_OPERATION 0x000002fc +# define NV04_GDI_RECTANGLE_TEXT_FORMAT 0x00000300 +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL 0x000005f4 /* Parameters: left top */ +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_BR 0x000005f8 /* Parameters: right bottom */ +# define NV04_GDI_RECTANGLE_TEXT_FILL_VALUE 0x000005fc +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_TL 0x00000600 /* Parameters: left top */ +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_BR 0x00000604 /* Parameters: right bottom */ + +/****************************************** +Object NV04_SWIZZLED_SURFACE used on: NV04 NV10 NV15 +*/ +#define NV04_SWIZZLED_SURFACE 0x00000052 +# define NV04_SWIZZLED_SURFACE_DMA_NOTIFY 0x00000180 +# define NV04_SWIZZLED_SURFACE_DMA_IMAGE 0x00000184 +# define NV04_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */ +# define NV04_SWIZZLED_SURFACE_OFFSET 0x00000304 + +/****************************************** +Object NV04_CONTEXT_SURFACES_3D used on: NV04 +*/ +#define NV04_CONTEXT_SURFACES_3D 0x00000053 +# define NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY 0x00000180 +# define NV04_CONTEXT_SURFACES_3D_DMA_COLOR 0x00000184 +# define NV04_CONTEXT_SURFACES_3D_DMA_ZETA 0x00000188 +# define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL 0x000002f8 /* Parameters: x width */ +# define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL 0x000002fc /* Parameters: y height */ +# define NV04_CONTEXT_SURFACES_3D_FORMAT 0x00000300 /* Parameters: color type width height */ +# define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE 0x00000304 /* Parameters: width height */ +# define NV04_CONTEXT_SURFACES_3D_PITCH 0x00000308 /* Parameters: color zeta */ +# define NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR 0x0000030c +# define NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA 0x00000310 + +/****************************************** +Object NV04_DX5_TEXTURED_TRIANGLE used on: NV04 +*/ +#define NV04_DX5_TEXTURED_TRIANGLE 0x00000054 +# define NV04_DX5_TEXTURED_TRIANGLE_NOP 0x00000100 +# define NV04_DX5_TEXTURED_TRIANGLE_NOTIFY 0x00000104 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_NOTIFY 0x00000180 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_1 0x00000184 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_2 0x00000188 +# define NV04_DX5_TEXTURED_TRIANGLE_SURFACE 0x0000018c +# define NV04_DX5_TEXTURED_TRIANGLE_COLOR_KEY 0x00000300 +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_OFFSET 0x00000304 +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FORMAT 0x00000308 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FILTER 0x0000030c /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX5_TEXTURED_TRIANGLE_BLEND 0x00000310 /* Parameters: texture benable dst src */ +# define NV04_DX5_TEXTURED_TRIANGLE_CONTROL 0x00000314 /* Parameters: alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */ +# define NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR 0x00000318 +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_S( d) (0x00000418 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_T( d) (0x0000041c + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_DRAW 0x00000600 /* Parameters: v0 v1 v2 v3 v4 v5 */ + +/****************************************** +Object NV04_DX6_MULTITEX_TRIANGLE used on: NV04 NV10 NV15 +*/ +#define NV04_DX6_MULTITEX_TRIANGLE 0x00000055 +# define NV04_DX6_MULTITEX_TRIANGLE_NOP 0x00000100 +# define NV04_DX6_MULTITEX_TRIANGLE_NOTIFY 0x00000104 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_NOTIFY 0x00000180 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_1 0x00000184 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_2 0x00000188 +# define NV04_DX6_MULTITEX_TRIANGLE_SURFACE 0x0000018c +# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET0 0x00000308 +# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET1 0x0000030c +# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT0 0x00000310 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT1 0x00000314 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX6_MULTITEX_TRIANGLE_FILTER0 0x00000318 /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX6_MULTITEX_TRIANGLE_FILTER1 0x0000031c /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA 0x00000320 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR 0x00000324 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA 0x0000032c +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR 0x00000330 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR 0x00000334 +# define NV04_DX6_MULTITEX_TRIANGLE_BLEND 0x00000338 /* Parameters: benable dst src */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0 0x0000033c /* Parameters: red_write green_write blue_write alpha_write alpha_write stencil_write alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1 0x00000340 /* Parameters: stencil_enable stencil_mask_write stencil_mask_read stencilref stencilfunc */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2 0x00000344 /* Parameters: stencil_fail stencil_zfail stencil_zpass */ +# define NV04_DX6_MULTITEX_TRIANGLE_FOG_COLOR 0x00000348 +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_S( d) (0x00000418 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_T( d) (0x0000041c + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_S( d) (0x00000420 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_T( d) (0x00000424 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_DRAW 0x00000540 /* Parameters: v0 v1 v2 v3 v4 v5 */ + +/****************************************** +Object NV04_COLOR_KEY used on: NV04 NV10 NV15 NV20 NV40 +*/ +#define NV04_COLOR_KEY 0x00000057 +# define NV04_COLOR_KEY_SET_DMA_NOTIFY 0x00000180 +# define NV04_COLOR_KEY_FORMAT 0x00000300 +# define NV04_COLOR_KEY_VALUE 0x00000304 + +/****************************************** +Object NV04_SOLID_LINE used on: NV04 +*/ +#define NV04_SOLID_LINE 0x0000005c +# define NV04_SOLID_LINE_CLIP_RECTANGLE 0x00000184 +# define NV04_SOLID_LINE_PATTERN 0x00000188 +# define NV04_SOLID_LINE_ROP 0x0000018c +# define NV04_SOLID_LINE_SURFACE 0x00000198 +# define NV04_SOLID_LINE_OPERATION 0x000002fc +# define NV04_SOLID_LINE_COLOR_FORMAT 0x00000300 +# define NV04_SOLID_LINE_COLOR_VALUE 0x00000304 +# define NV04_SOLID_LINE_START 0x00000400 /* Parameters: x y */ +# define NV04_SOLID_LINE_END 0x00000400 /* Parameters: x y */ + +/****************************************** +Object NV04_UNK005E used on: NV04 +*/ +#define NV04_UNK005E 0x0000005e +# define NV04_UNK005E_SET_SURFACE 0x00000198 +# define NV04_UNK005E_UNK02fc 0x000002fc +# define NV04_UNK005E_UNK0300 0x00000300 +# define NV04_UNK005E_COUNTER 0x00000304 + +/****************************************** +Object NV05_SCALED_IMAGE_FROM_MEMORY used on: NV04 +*/ +#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063 +# define NV05_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198 +# define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION 0x000002fc +# define NV05_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 + +/****************************************** +Object NV04_SCALED_IMAGE_FROM_MEMORY used on: NV04 +*/ +#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077 +# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY 0x00000180 +# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE 0x00000184 +# define NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198 +# define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT 0x00000300 +# define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_DU_DX 0x00000318 /* Parameters: int frac*0x100000 */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_DV_DY 0x0000031c /* Parameters: int frac*0x100000 */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch origin filter */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408 +# define NV04_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */ + +/****************************************** +Object NV_IMAGE_FROM_CPU used on: NV04 +*/ +#define NV_IMAGE_FROM_CPU 0x00000061 +# define NV_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +# define NV_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188 +# define NV_IMAGE_FROM_CPU_PATTERN 0x0000018c +# define NV_IMAGE_FROM_CPU_ROP 0x00000190 +# define NV_IMAGE_FROM_CPU_SURFACE 0x0000019c +# define NV_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV_IMAGE_FROM_CPU_FORMAT 0x00000300 + +/****************************************** +Object NV05_IMAGE_FROM_CPU used on: NV04 +*/ +#define NV05_IMAGE_FROM_CPU 0x00000065 +# define NV05_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +# define NV05_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188 +# define NV05_IMAGE_FROM_CPU_PATTERN 0x0000018c +# define NV05_IMAGE_FROM_CPU_ROP 0x00000190 +# define NV05_IMAGE_FROM_CPU_SURFACE 0x0000019c +# define NV05_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV05_IMAGE_FROM_CPU_FORMAT 0x00000300 +# define NV05_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_COLOR( d) (0x00000400 + d * 0x0004) + +/****************************************** +Object NV_IMAGE_BLIT used on: NV04 NV10 NV15 NV20 NV40 +*/ +#define NV_IMAGE_BLIT 0x0000005f +# define NV_IMAGE_BLIT_DMA_NOTIFY 0x00000180 +# define NV_IMAGE_BLIT_COLOR_KEY 0x00000184 +# define NV_IMAGE_BLIT_CLIP_RECTANGLE 0x00000188 +# define NV_IMAGE_BLIT_PATTERN 0x0000018c +# define NV_IMAGE_BLIT_ROP5 0x00000190 +# define NV_IMAGE_BLIT_SURFACE 0x0000019c +# define NV_IMAGE_BLIT_OPERATION 0x000002fc +# define NV_IMAGE_BLIT_POINT_IN 0x00000300 /* Parameters: x y */ +# define NV_IMAGE_BLIT_POINT_OUT 0x00000304 /* Parameters: x y */ +# define NV_IMAGE_BLIT_SIZE 0x00000308 /* Parameters: width height */ + +/****************************************** +Object NV10_TCL_PRIMITIVE_3D used on: NV10 +*/ +#define NV10_TCL_PRIMITIVE_3D 0x00000056 + +/****************************************** +Object NV17_TCL_PRIMITIVE_3D used on: NV15 +*/ +#define NV17_TCL_PRIMITIVE_3D 0x00000099 + +/****************************************** +Object NV11_TCL_PRIMITIVE_3D used on: NV15 +*/ +#define NV11_TCL_PRIMITIVE_3D 0x00000096 +# define NV10_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV10_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY 0x00000180 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST 0x0000018c +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2 0x00000194 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY3 0x00000198 +# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY4 0x000001ac +# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY5 0x000001b0 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV10_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00000218 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00000220 + d * 0x0004) /* Parameters: wrap_t wrap_s log2(height) log2(width) lod npot format cube_map */ +# define NV10_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00000228 + d * 0x0004) /* Parameters: enable anisotropy */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ +# define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ +# define NV10_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00000250 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_ENABLE 0x00000298 /* Parameters: specular diffuse ambient emission */ +# define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c +# define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 +# define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */ +# define NV17_TCL_PRIMITIVE_3D_COLOR_MASK_ENABLE 0x000002bc +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c +# define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 +# define NV10_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 +# define NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c +# define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 +# define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 +# define NV10_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c +# define NV10_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c +# define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 +# define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_R 0x000003a8 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_G 0x000003ac +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_B 0x000003b0 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_A 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ +# define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */ +# define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW1_MATRIX( d) (0x00000440 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000006a0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000006a4 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000006a8 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000006ac +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000006b0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000006b4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_W 0x000006f4 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x000006f8 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x000006fc +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000700 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000704 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000708 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00000800 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00000804 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00000808 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000080c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00000810 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00000814 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00000818 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000081c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00000820 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00000828 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000082c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00000830 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00000844 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00000848 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000084c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00000850 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00000854 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00000858 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000086c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00000870 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000c18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000c1c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000c20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00000c24 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000c30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000c34 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000c38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000c40 /* Parameters: y x */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000c44 /* Parameters: z */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000c50 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000c54 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000c58 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x00000c5c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000c60 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000c64 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000c68 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x00000c6c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000c80 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000c84 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000c88 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000c8c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00000c90 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00000c94 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00000c98 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000ca0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000ca4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000ca8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x00000cac +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000cb0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000cb4 /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x00000cb8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x00000cbc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00000cc0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000cc8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000ccc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000cd0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x00000cd4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000cd8 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x00000cdc /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 +# define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL 0x00000d08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL 0x00000d0c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL2 0x00000d10 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX0 0x00000d18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX1 0x00000d20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_NOR 0x00000d28 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_WGH 0x00000d30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000d44 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x00000d5c /* Parameters: pitch */ +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000d60 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_FILL_VALUE 0x00000d68 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_CLEAR_ENABLE 0x00000d6c +# define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc +# define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 /* Parameters: count-1 first */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001638 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x0000163c +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001640 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001644 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_ENABLE 0x00001658 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA 0x00001800 + +/****************************************** +Object NV10_IMAGE_FROM_CPU used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_IMAGE_FROM_CPU 0x0000008a +# define NV10_IMAGE_FROM_CPU_SET_DMA_NOTIFY 0x00000180 +# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_CLIP_RECTANGLE 0x00000188 +# define NV10_IMAGE_FROM_CPU_SET_IMAGE_PATTERN 0x0000018c +# define NV10_IMAGE_FROM_CPU_SET_RASTER_OP 0x00000190 +# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_SURFACES_2D 0x0000019c +# define NV10_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV10_IMAGE_FROM_CPU_FORMAT 0x00000300 +# define NV10_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */ +# define NV10_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: width height */ +# define NV10_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: width height */ +# define NV10_IMAGE_FROM_CPU_HLINE 0x00000400 + +/****************************************** +Object NV10_PRIMITIVE_2D used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_PRIMITIVE_2D 0x0000007b +# define NV10_PRIMITIVE_2D_SET_DMA_NOTIFY 0x00000180 +# define NV10_PRIMITIVE_2D_SET_SURFACE 0x00000184 +# define NV10_PRIMITIVE_2D_SET_FORMAT 0x00000300 +# define NV10_PRIMITIVE_2D_SET_POINT 0x00000304 /* Parameters: x y */ +# define NV10_PRIMITIVE_2D_SET_SIZE 0x00000308 /* Parameters: width height */ +# define NV10_PRIMITIVE_2D_SET_CLIP_HORIZ 0x0000030c /* Parameters: width x */ +# define NV10_PRIMITIVE_2D_SET_CLIP_VERT 0x00000310 /* Parameters: height y */ +# define NV10_PRIMITIVE_2D_SET_DATA( d) (0x00000400 + d * 0x0004) + +/****************************************** +Object NV10_IMAGE_BLIT used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_IMAGE_BLIT 0x0000009f +# define NV10_IMAGE_BLIT_NOP 0x00000100 +# define NV10_IMAGE_BLIT_NOTIFY 0x00000104 +# define NV10_IMAGE_BLIT_SET_DMA_NOTIFY 0x00000180 +# define NV10_IMAGE_BLIT_SET_CONTEXT_CLIP_RECTANGLE 0x00000188 +# define NV10_IMAGE_BLIT_SET_IMAGE_PATTERN 0x0000018c +# define NV10_IMAGE_BLIT_SET_RASTER_OP 0x00000190 +# define NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D 0x0000019c +# define NV10_IMAGE_BLIT_SET_OPERATION 0x000002fc +# define NV10_IMAGE_BLIT_SET_POINT 0x00000300 /* Parameters: x y */ +# define NV10_IMAGE_BLIT_SET_PITCH 0x00000304 /* Parameters: skip */ +# define NV10_IMAGE_BLIT_SET_SIZE 0x00000308 /* Parameters: width height */ + +/****************************************** +Object NV10_VIDEO_DISPLAY used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_VIDEO_DISPLAY 0x0000007c +# define NV10_VIDEO_DISPLAY_COUNTER 0x00000050 +# define NV10_VIDEO_DISPLAY_SET_DMA_FROM_MEMORY 0x00000180 +# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_VIDEO_DISPLAY_SET_OBJECT3 0x0000019c +# define NV10_VIDEO_DISPLAY_SIZE 0x000002f8 /* Parameters: height width */ +# define NV10_VIDEO_DISPLAY_OFFSET 0x00000300 + +/****************************************** +Object NV10_UNK0072 used on: NV10 NV15 NV20 NV40 G70 +*/ +#define NV10_UNK0072 0x00000072 +# define NV10_UNK0072_COUNTER 0x00000050 +# define NV40_UNK0072_SET_OBJECT 0x00000060 +# define NV10_UNK0072_SET_DMA_NOTIFY 0x00000180 + +/****************************************** +Object NV10_SCALED_IMAGE_FROM_MEMORY used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089 +# define NV10_SCALED_IMAGE_FROM_MEMORY_COUNTER 0x00000050 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_DMA_IN_MEMORY 0x00000184 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_RASTER_OP 0x0000018c +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_IMAGE_PATTERN 0x00000188 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_SURFACE 0x00000198 +# define NV10_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408 +# define NV10_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */ + +/****************************************** +Object NV10_CONTEXT_SURFACES_2D used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_CONTEXT_SURFACES_2D 0x00000062 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_CONTEXT_SURFACES_2D_FORMAT 0x00000300 /* Parameters: color type width height */ +# define NV10_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */ +# define NV10_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308 +# define NV10_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c + +/****************************************** +Object NV04_CONTEXT_SURFACES_2D used on: NV04 NV10 NV15 +*/ +#define NV04_CONTEXT_SURFACES_2D 0x00000042 +# define NV04_CONTEXT_SURFACES_2D_NOTIFY 0x00000104 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_SRC 0x00000184 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_DST 0x00000188 +# define NV04_CONTEXT_SURFACES_2D_FORMAT 0x00000300 +# define NV04_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */ +# define NV04_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308 +# define NV04_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c + +/****************************************** +Object NV04_IMAGE_PATTERN used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV04_IMAGE_PATTERN 0x00000044 +# define NV04_IMAGE_PATTERN_COLOR_FORMAT 0x00000300 +# define NV04_IMAGE_PATTERN_MONO_FORMAT 0x00000304 +# define NV04_IMAGE_PATTERN_SELECT 0x0000030c +# define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE 0x00000308 +# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR0 0x00000310 +# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR1 0x00000314 +# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN0 0x00000318 +# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN1 0x0000031c + +/****************************************** +Object NV20_SWIZZLED_SURFACE used on: NV20 NV30 NV40 G70 +*/ +#define NV20_SWIZZLED_SURFACE 0x0000009e +# define NV20_SWIZZLED_SURFACE_SET_OBJECT0 0x00000180 +# define NV20_SWIZZLED_SURFACE_SET_OBJECT1 0x00000184 +# define NV20_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */ +# define NV20_SWIZZLED_SURFACE_OFFSET 0x00000304 + +/****************************************** +Object NV20_TCL_PRIMITIVE_3D used on: NV20 +*/ +#define NV20_TCL_PRIMITIVE_3D 0x00000097 +# define NV20_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV20_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT3 0x00000194 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000198 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT5 0x0000019c +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a0 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a4 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001a8 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001ac +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b0 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ +# define NV20_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ +# define NV20_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ +# define NV20_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */ +# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONTROL 0x00000294 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_CONTROL 0x00000298 /* Parameters: back_specular back_ambient back_diffuse back_emission front_specular front_ambient front_diffuse front_emission */ +# define NV20_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c +# define NV20_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 +# define NV20_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 +# define NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c +# define NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 +# define NV20_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV20_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 +# define NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 +# define NV20_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c +# define NV20_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 +# define NV20_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c +# define NV20_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV20_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c +# define NV20_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 +# define NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a8 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 +# define NV20_TCL_PRIMITIVE_3D_SEPARATE_SPECULAR_ENABLE 0x000003b8 +# define NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x000003c0 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000420 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_POINT_SIZE 0x0000043c +# define NV20_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000840 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000844 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000848 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000084c + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000009c0 +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000009c4 +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000009c8 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000009e0 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000009e4 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000009e8 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000009ec +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000009f0 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000009f4 +# define NV20_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00000a1c /* Parameters: coord_replace r_mode enable */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OX 0x00000a20 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OY 0x00000a24 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_AVG_S 0x00000a28 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_A 0x00000a2c +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00000a30 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00000a34 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000a38 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000a3c +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000a40 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00000a44 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000a48 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000a4c +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PX_DIV2 0x00000af0 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PY_DIV2 0x00000af4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_HALF_S 0x00000af8 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_B 0x00000afc +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b00 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b04 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b08 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b0c +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000b80 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000b84 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000b88 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000b8c +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001ea4 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 +# define NV20_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00001b00 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00001b04 + d * 0x0040) /* Parameters: log2(height) log2(width) lod format cube_map */ +# define NV20_TCL_PRIMITIVE_3D_TX_WRAP(d) (0x00001b08 + d * 0x0040) /* Parameters: wrap_s wrap_t wrap_r */ +# define NV20_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00001b0c + d * 0x0040) /* Parameters: enable anisotropy */ +# define NV20_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00001b10 + d * 0x0040) /* Parameters: pitch */ +# define NV20_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00001b14 + d * 0x0040) /* Parameters: mag_filter min_filter */ +# define NV20_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00001b1c + d * 0x0040) /* Parameters: width height */ +# define NV20_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00001b20 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_RC_ENABLE 0x00001e60 /* Parameters: number of rc enabled */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_OP 0x00001e70 /* Parameters: op0 op1 op2 op3 */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_CULL_MODE 0x000017f8 /* Parameters: cull0 cull1 cull2 cull3 */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_PREVIOUS 0x00001e78 /* Parameters: prev2 prev3 */ +# define NV20_TCL_PRIMITIVE_3D_RC_COLOR0 0x00001e20 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_COLOR1 0x00001e24 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV20_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000ac0 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000a60 + d * 0x0004) /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x00000a80 + d * 0x0004) /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000aa0 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV20_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00001e40 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000105c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001060 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001064 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_AMBIENT(d) (0x00000c00 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_DIFFUSE(d) (0x00000c0c + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_SPECULAR(d) (0x00000c18 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001068 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000106c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001070 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001040 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001044 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001048 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000104c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001050 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001054 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001058 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e28 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e2c +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e30 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e34 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e38 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e3c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(d) (0x00001480 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00001500 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00001504 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00001508 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00001518 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x0000151c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00001520 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00001524 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00001528 /* Parameters: y x */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x0000152c /* Parameters: w z */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00001530 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00001534 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00001538 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00001540 /* Parameters: y x */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00001544 /* Parameters: z */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00001550 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00001554 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00001558 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000155c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00001560 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00001564 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00001568 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000156c /* Parameters: a b g r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00001580 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00001584 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00001588 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x0000158c /* Parameters: a b g r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00001590 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00001594 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001598 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x000015a0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x000015a4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x000015a8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x000015ac +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000015b0 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000015b4 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000015b8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000015bc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000015c0 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x000015c8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x000015cc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x000015d0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x000015d4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000015d8 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000015dc /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000015e0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000015e4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000015e8 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000015f0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000015f4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000015f8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000015fc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00001600 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00001604 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x00001608 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x0000160c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x00001610 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x00001620 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x00001624 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x00001628 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x0000162c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00001630 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x00001634 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001698 +# define NV20_TCL_PRIMITIVE_3D_EDGE_FLAG 0x000016bc +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR0_POS 0x00001720 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR1_WGH 0x00001724 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR2_NOR 0x00001728 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR3_COL 0x0000172c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR4_COL2 0x00001730 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR5_FOG 0x00001734 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR6 0x00001738 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR7 0x0000173c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0 0x00001740 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR9_TX1 0x00001744 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR10_TX2 0x00001748 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR11_TX3 0x0000174c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR12_TX4 0x00001750 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR13_TX5 0x00001754 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR14_TX6 0x00001758 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR15_TX7 0x0000175c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001760 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001760 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001764 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001768 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000176c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001770 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001774 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001778 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000177c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001780 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001784 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001788 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000178c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001790 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001794 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001798 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000179c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc +# define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 +# define NV20_TCL_PRIMITIVE_3D_BEGIN_END 0x000017fc +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1 0x00001c30 /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1 0x00001c50 /* Parameters: y2 y1 */ +# define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c +# define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 +# define NV20_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ +# define NV20_TCL_PRIMITIVE_3D_INDEX_DATA 0x00001800 /* Parameters: index1 index0 */ +# define NV20_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001810 /* Parameters: count_vertices offset_vertices */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001f00 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x00001f04 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001f08 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001f0c + +/****************************************** +Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 +*/ +#define NV30_TCL_PRIMITIVE_3D 0x00000097 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT3 0x0000018c +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000194 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT5 0x00000198 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a4 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a8 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001ac +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001b4 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b8 +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC0_OBJECT 0x0000019c +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC1_OBJECT 0x000001a0 +# define NV30_TCL_PRIMITIVE_3D_BUFFER0_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color0 buffer pitch */ +# define NV30_TCL_PRIMITIVE_3D_COLOR0_OFFSET 0x00000210 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV30_TCL_PRIMITIVE_3D_COLOR1_OFFSET 0x00000218 +# define NV30_TCL_PRIMITIVE_3D_BUFFER1_PITCH 0x0000021c /* Parameters: color1 buffer pitch */ +# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */ +# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230 +# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000240 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_BUFFER2_PITCH 0x00000280 +# define NV30_TCL_PRIMITIVE_3D_BUFFER3_PITCH 0x00000284 +# define NV30_TCL_PRIMITIVE_3D_BUFFER2_OFFSET 0x00000288 +# define NV30_TCL_PRIMITIVE_3D_BUFFER3_OFFSET 0x0000028c +# define NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000300 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000304 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00000308 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x0000030c +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000310 +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000314 +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000318 +# define NV30_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000031c /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000320 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000324 /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00000328 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x0000032c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00000330 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00000334 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x00000338 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x0000033c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00000340 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x00000344 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00000348 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x0000034c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x00000350 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000354 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000358 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x0000035c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x00000360 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x00000364 +# define NV30_TCL_PRIMITIVE_3D_SHADE_MODEL 0x00000368 +# define NV30_TCL_PRIMITIVE_3D_FOG_ENABLE 0x0000036c +# define NV30_TCL_PRIMITIVE_3D_FOG_COLOR 0x00000370 +# define NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123 0x00000370 /* Parameters: buffer3 b buffer3 g buffer3 r buffer3 a buffer2 b buffer2 g buffer2 r buffer2 a buffer1 b buffer1 g buffer1 r buffer1 a */ +# define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c +# define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003a4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003a8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 +# define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 +# define NV30_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x000003bc +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 +# define NV30_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000008c8 +# define NV30_TCL_PRIMITIVE_3D_FOG_MODE 0x000008cc +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000008d0 +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000008d4 +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000008d8 +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR0 0x000008ec /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR1 0x000008f0 /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_FINAL0 0x000008f4 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_FINAL1 0x000008f8 /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV30_TCL_PRIMITIVE_3D_RC_ENABLE 0x000008fc /* Parameters: number of rc enabled */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000900 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000904 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000908 + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x0000090c + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000910 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000914 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0 0x00000200 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM1 0x00000204 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0 0x000002c0 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS1 0x000002c4 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0 0x00000a00 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_1 0x00000a04 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 +# define NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x000008c0 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x000008c4 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00001ee8 /* Parameters: coord_replace r_mode enable */ +# define NV30_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001ee0 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00001ec0 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00001ec4 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00001ec8 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00001ecc +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00001ed0 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00001ed4 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00001ed8 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00001edc +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00001ee4 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX 0x00000a20 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OY 0x00000a24 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_NPF_DIV2 0x00000a28 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK0_0x0 0x00000a2c +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PX_DIV2 0x00000a30 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PY_DIV2 0x00000a34 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_FMN_DIV2 0x00000a38 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK1_0x0 0x00000a3c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000a60 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000a68 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000a6c +# define NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x00000a70 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x00000a74 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000a78 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000a7c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b80 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b84 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b88 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b8c +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 +# define NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE 0x000017c8 +# define NV30_TCL_PRIMITIVE_3D_STORE_RESULT 0x00001800 +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000e00 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000e04 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000e08 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x00000e0c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001228 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000122c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001230 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001200 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001204 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001208 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000120c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001210 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001214 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001218 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000121c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001220 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001224 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x00001400 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x00001404 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x00001408 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x0000140c +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x00001410 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x00001414 +# define NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x00001420 /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV30_TCL_PRIMITIVE_3D_UNK1D6C_OFFSET 0x00001d6c +# define NV30_TCL_PRIMITIVE_3D_UNK1D70_VALUE 0x00001d70 +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x00001db4 +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001db8 /* Parameters: factor pattern */ +# define NV30_TCL_PRIMITIVE_3D_BEGIN_END 0x00001808 +# define NV30_TCL_PRIMITIVE_3D_CULL_FACE 0x00001830 +# define NV30_TCL_PRIMITIVE_3D_FRONT_FACE 0x00001834 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00001838 +# define NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x0000183c +# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c +# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e20 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e24 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e28 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e2c +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e30 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e34 +# define NV30_TCL_PRIMITIVE_3D_DO_VERTICES 0x00001dac +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID 0x00001e9c +# define NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID 0x00001ea0 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001efc +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_X 0x00001f00 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Y 0x00001f04 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Z 0x00001f08 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_W 0x00001f0c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_X 0x00001f10 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Y 0x00001f14 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Z 0x00001f18 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_W 0x00001f1c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_X 0x00001f20 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Y 0x00001f24 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Z 0x00001f28 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_W 0x00001f2c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_X 0x00001f30 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Y 0x00001f34 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Z 0x00001f38 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_W 0x00001f3c +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3X(d) (0x00001500 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Y(d) (0x00001504 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Z(d) (0x00001508 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3W(d) (0x0000150c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4X(d) (0x00001c00 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Y(d) (0x00001c04 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Z(d) (0x00001c08 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4W(d) (0x00001c0c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: source: offset */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000a90 /* Parameters: y x */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000a94 /* Parameters: z */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000018c0 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000018c4 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000018c8 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000018cc +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000018d0 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000018d4 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000018d8 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000018dc +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001920 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00001924 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x00001928 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x0000192c /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000194c /* Parameters: a b g r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00001950 /* Parameters: a b g r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000019c0 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000019c4 /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000019c8 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000019cc /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x000019d0 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x000019d4 /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x000019d8 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x000019dc /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001e54 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0 0x00001718 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001740 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001740 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001744 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001748 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000174c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001750 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001754 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001758 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000175c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001760 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001764 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001768 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000176c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001770 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001774 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001778 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000177c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 +# define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 +# define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ +# define NV30_TCL_PRIMITIVE_3D_TX_WRAP_UNIT(d) (0x00001a08 + d * 0x0020) /* Parameters: wrap_s wrap_t wrap_r */ +# define NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(d) (0x00001a0c + d * 0x0020) /* Parameters: nv40_enable nv30_enable anisotropy */ +# define NV30_TCL_PRIMITIVE_3D_TX_SWIZZLE_UNIT(d) (0x00001a10 + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_FILTER_UNIT(d) (0x00001a14 + d * 0x0020) /* Parameters: filter_min filter_mag */ +# define NV30_TCL_PRIMITIVE_3D_TX_XY_DIM_UNIT(d) (0x00001a18 + d * 0x0020) /* Parameters: width height */ +# define NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(d) (0x00001a1c + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(d) (0x00001840 + d * 0x0004) /* Parameters: depth NPOT pitch */ +# define NV30_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001814 /* Parameters: count_vertices offset_vertices */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U16 0x0000180c /* Parameters: 1: 0: */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U32 0x00001810 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 +# define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000374 +# define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000378 +# define NV30_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST_MEM_OFFSET 0x0000181c +# define NV30_TCL_PRIMITIVE_3D_EXECUTE_DISPLAY_LIST 0x00001824 /* Parameters: length start offset */ +# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00001828 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x0000182c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001480 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES 0x00001478 +# define NV30_TCL_PRIMITIVE_3D_VP_IN_REG 0x00001ff0 /* Parameters: vertex pos weight normal primary color secondary color fogcoord texture coords 0 texture ccords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */ +# define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG 0x00001ff4 /* Parameters: primary color secondary color backface primary color backface secondary color fogcoord pointsize clip plane 0 clip plane 1 clip plane 2 clip plane 3 clip plane 4 clip plane 5 texture coords 0 texture coords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */ + +/****************************************** +Object NV30_CLEAR_BUFFER used on: NV30 NV40 G70 +*/ +#define NV30_CLEAR_BUFFER 0x00000066 +# define NV30_CLEAR_BUFFER_SET_DMA_NOTIFY 0x00000180 +# define NV30_CLEAR_BUFFER_SET_IMAGE_PATTERN 0x00000188 +# define NV30_CLEAR_BUFFER_SET_RASTER_OP 0x0000018c +# define NV30_CLEAR_BUFFER_SET_CONTEXT_SURFACE_2D 0x00000198 +# define NV30_CLEAR_BUFFER_UNK002fc 0x000002fc + +/****************************************** +Object NV50_TCL_PRIMITIVE_3D used on: +*/ +#define NV50_TCL_PRIMITIVE_3D 0x00000097 +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0( d) (0x00000180 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1( d) (0x000001c0 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000314 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_X 0x00000380 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_Y 0x00000384 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000003c0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000003c4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000003c8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000003cc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000003d0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000003d4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000003d8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000003dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000400 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000404 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000408 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000420 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000424 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000428 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000430 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000434 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000438 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000440 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000444 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000448 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000500 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000504 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000508 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x0000050c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000530 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000534 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000538 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000053c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000580 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000584 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000588 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x0000058c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000590 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000594 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000598 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x0000059c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000005a0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000005a4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000005a8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000005ac +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x000005b0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x000005b4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x000005b8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x000005bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x000006a0 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000006a4 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000006a8 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x000006ac /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00000700 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x00000704 /* Parameters: w z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000740 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000744 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000748 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x0000074c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00000750 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00000754 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00000758 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x0000075c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000790 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000794 /* Parameters: z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000088c /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000890 /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_X 0x00000a00 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Y 0x00000a04 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Z 0x00000a08 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_X 0x00000a0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Y 0x00000a10 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Z 0x00000a14 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000c08 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000c0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x00000d00 + d * 0x0008) /* Parameters: x2 x1 */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x00000d04 + d * 0x0008) /* Parameters: y2 y1 */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_FIRST 0x00000d74 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_COUNT 0x00000d78 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R 0x00000d80 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_G 0x00000d84 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_B 0x00000d88 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_A 0x00000d8c +# define NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH 0x00000d90 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL 0x00000da0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00000dac +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000db0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000db4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x00000e04 /* Parameters: w x */ +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x00000e08 /* Parameters: h y */ +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00000f00 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000f04 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000f08 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000f0c +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000f10 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000f54 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x00000f58 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000f5c +# define NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x000012cc +# define NV50_TCL_PRIMITIVE_3D_SHADE_MODEL 0x000012d4 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x000012e8 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x000012ec +# define NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x0000130c +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00001310 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00001314 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R 0x0000131c +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_G 0x00001320 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_B 0x00001324 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_A 0x00001328 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB 0x00001340 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB 0x00001344 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_RGB 0x00001348 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA 0x0000134c +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA 0x00001350 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_ALPHA 0x00001358 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00001380 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x00001384 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00001388 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x0000138c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00001390 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00001394 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x00001398 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x0000139c +# define NV50_TCL_PRIMITIVE_3D_LINE_WIDTH 0x000013b0 +# define NV50_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001518 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x0000156c +# define NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00001570 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00001594 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x00001598 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x0000159c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x000015a0 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x000015a4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x000015bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BEGIN 0x000015dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_END 0x000015e0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001640 +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x0000166c +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001680 /* Parameters: pattern factor */ +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000168c +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001700 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00001918 +# define NV50_TCL_PRIMITIVE_3D_FRONT_FACE 0x0000191c +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE 0x00001920 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE 0x000019c4 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP 0x000019c8 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS 0x000019d0 /* Parameters: color stencil depth */ +# define NV50_TCL_PRIMITIVE_3D_COLOR_MASK( d) (0x00001a00 + d * 0x0004) /* Parameters: a b g r */ + +/****************************************** +Object NV_DMA_FROM_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_FROM_MEMORY 0x00000002 + +/****************************************** +Object NV_DMA_TO_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_TO_MEMORY 0x00000003 + +/****************************************** +Object NV_DMA_IN_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_IN_MEMORY 0x0000003d + +/****************************************** +Object NvType0046 used on: NV04 +*/ +#define NvType0046 0x00000046 +# define NvType0046_DMA_NOTIFY 0x00000180 +# define NvType0046_DMA_MEM_1 0x00000184 +# define NvType0046_DMA_MEM_2 0x00000188 +# define NvType0046_DMA_3 0x0000018c +# define NvType0046_DMA_4 0x00000190 +# define NvType0046_OBJ_5 0x00000194 +# define NvType0046_OBJ_6 0x00000198 +# define NvType0046_PITCH1 0x00000304 +# define NvType0046_PITCH2 0x0000030c +# define NvType0046_SIZE 0x00000340 /* Parameters: width height */ +# define NvType0046_WIDTH 0x00000344 /* Parameters: visible_width blank_width */ +# define NvType0046_HSYNC 0x00000348 /* Parameters: hsync_start hsync_len */ +# define NvType0046_HEIGHT 0x0000034c /* Parameters: visible_height blank_height */ +# define NvType0046_VSYNC 0x00000350 /* Parameters: vsync_start vsync_len */ +# define NvType0046_FULL_SIZE 0x00000354 /* Parameters: full_width full_height */ +# define NvType0046_PIXEL_CLK 0x00000358 +# define NvType0046_FLAGS 0x0000035c /* Parameters: doublescan -hsync -vsync depth */ + +/****************************************** +Object NvType0047 used on: NV04 +*/ +#define NvType0047 0x00000047 +# define NvType0047_DMA_NOTIFY 0x00000180 +# define NvType0047_UNK19C 0x0000019c +# define NvType0047_UNK1A0 0x000001a0 + +/****************************************** +Object NvType0049 used on: NV04 +*/ +#define NvType0049 0x00000049 +# define NvType0049_DMA_NOTIFY 0x00000180 +# define NvType0049_DMA_MEM_1 0x00000184 +# define NvType0049_DMA_MEM_2 0x00000188 + +/****************************************** +Object NvType004D used on: NV04 +*/ +#define NvType004D 0x0000004d +# define NvType004D_DMA_NOTIFY 0x00000180 +# define NvType004D_DMA_MEM_1 0x00000184 +# define NvType004D_DMA_MEM_2 0x00000188 +# define NvType004D_DMA_MEM_3 0x0000018c +# define NvType004D_DMA_MEM_4 0x00000190 + +#endif /* _NOUVEAU_REG_H */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c new file mode 100644 index 00000000000..881b20149f0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -0,0 +1,380 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "glheader.h" +#include "imports.h" +#include "mtypes.h" +#include "framebuffer.h" +#include "renderbuffer.h" + +#include "nouveau_context.h" +#include "nouveau_screen.h" +#include "nouveau_object.h" +#include "nouveau_span.h" + +#include "utils.h" +#include "context.h" +#include "vblank.h" +#include "drirenderbuffer.h" + +#include "GL/internal/dri_interface.h" + +#include "xmlpool.h" + +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_DEBUG + DRI_CONF_NO_RAST(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +static const GLuint __driNConfigOptions = 1; + +extern const struct dri_extension common_extensions[]; +extern const struct dri_extension nv10_extensions[]; +extern const struct dri_extension nv20_extensions[]; +extern const struct dri_extension nv30_extensions[]; +extern const struct dri_extension nv40_extensions[]; +extern const struct dri_extension nv50_extensions[]; + +static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) +{ + nouveauScreenPtr screen; + NOUVEAUDRIPtr dri_priv=(NOUVEAUDRIPtr)sPriv->pDevPriv; + + /* allocate screen */ + screen = (nouveauScreenPtr) CALLOC( sizeof(*screen) ); + if ( !screen ) { + __driUtilMessage("%s: Could not allocate memory for screen structure",__FUNCTION__); + return NULL; + } + + screen->card=nouveau_card_lookup(dri_priv->device_id); + if (!screen->card) { + __driUtilMessage("%s: Unknown card type 0x%04x:0x%04x\n", + __func__, dri_priv->device_id >> 16, dri_priv->device_id & 0xFFFF); + FREE(screen); + return NULL; + } + + /* parse information in __driConfigOptions */ + driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions); + + screen->fbFormat = dri_priv->bpp / 8; + screen->frontOffset = dri_priv->front_offset; + screen->frontPitch = dri_priv->front_pitch; + screen->backOffset = dri_priv->back_offset; + screen->backPitch = dri_priv->back_pitch; + screen->depthOffset = dri_priv->depth_offset; + screen->depthPitch = dri_priv->depth_pitch; + + screen->driScreen = sPriv; + return screen; +} + +static void +nouveauDestroyScreen(__DRIscreenPrivate *sPriv) +{ + nouveauScreenPtr screen = (nouveauScreenPtr)sPriv->private; + + if (!screen) return; + + /* free all option information */ + driDestroyOptionInfo (&screen->optionCache); + + FREE(screen); + sPriv->private = NULL; +} + +static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv) +{ + sPriv->private = (void *) nouveauCreateScreen( sPriv ); + if ( !sPriv->private ) { + nouveauDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + +/** + * Create the Mesa framebuffer and renderbuffers for a given window/drawable. + * + * \todo This function (and its interface) will need to be updated to support + * pbuffers. + */ +static GLboolean +nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap) +{ + nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private; + nouveau_renderbuffer *nrb; + struct gl_framebuffer *fb; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; + GLenum color_format = screen->fbFormat == 4 ? GL_RGBA8 : GL_RGB5; + + if (isPixmap) + return GL_FALSE; /* not implemented */ + + fb = _mesa_create_framebuffer(mesaVis); + if (!fb) + return GL_FALSE; + + /* Front buffer */ + nrb = nouveau_renderbuffer_new(color_format, + driScrnPriv->pFB + screen->frontOffset, + screen->frontOffset, + screen->frontPitch * screen->fbFormat, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa); + + if (0 /* unified buffers if we choose to support them.. */) { + } else { + if (mesaVis->doubleBufferMode) { + nrb = nouveau_renderbuffer_new(color_format, NULL, + 0, 0, + NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); + } + + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, + 0, 0, + NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); + } else if (mesaVis->depthBits == 24) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, + 0, 0, + NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + } else if (mesaVis->depthBits == 16) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, + 0, 0, + NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + } + } + + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + GL_FALSE, /* depth */ + swStencil, + swAccum, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); + + driDrawPriv->driverPrivate = (void *) fb; + return (driDrawPriv->driverPrivate != NULL); +} + + +static void +nouveauDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +static int +nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo) +{ + return -1; +} + +static const struct __DriverAPIRec nouveauAPI = { + .InitDriver = nouveauInitDriver, + .DestroyScreen = nouveauDestroyScreen, + .CreateContext = nouveauCreateContext, + .DestroyContext = nouveauDestroyContext, + .CreateBuffer = nouveauCreateBuffer, + .DestroyBuffer = nouveauDestroyBuffer, + .SwapBuffers = nouveauSwapBuffers, + .MakeCurrent = nouveauMakeCurrent, + .UnbindContext = nouveauUnbindContext, + .GetSwapInfo = nouveauGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = nouveauCopySubBuffer +}; + + +static __GLcontextModes * +nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer ) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + int i; + + static const struct { + GLenum format; + GLenum type; + } fb_format_array[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + + depth_buffer_factor = 4; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = ((pixel_bits==16) ? 1 : 2) * + depth_buffer_factor * back_buffer_factor * 4; + modes = (*dri_interface->createContextModes)(num_modes, + sizeof(__GLcontextModes)); + m = modes; + + for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_DIRECT_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC +void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) + +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 2, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 0, 0, 3 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("nouveau", + dri_version, & dri_expected, + ddx_version, & ddx_expected, + drm_version, & drm_expected)) { + return NULL; + } + + // temporary lock step versioning + if (drm_expected.patch!=drm_version->patch) { + __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", + __func__, + drm_expected.patch, drm_version->patch); + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &nouveauAPI); + if ( psp != NULL ) { + NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv; + + *driver_modes = nouveauFillInModes(dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, + (dri_priv->bpp == 16) ? 0 : 8, + 1 + ); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, common_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv30_extensions, GL_FALSE ); + driInitExtensions( NULL, nv40_extensions, GL_FALSE ); + driInitExtensions( NULL, nv50_extensions, GL_FALSE ); + } + + return (void *) psp; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h new file mode 100644 index 00000000000..decdafa86d5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -0,0 +1,61 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include "xmlconfig.h" + +#include "nouveau_dri.h" +#include "nouveau_card.h" + +typedef struct { + nouveau_card* card; + u_int32_t bus_type; + u_int32_t agp_mode; + + GLint fbFormat; + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + GLuint spanOffset; + + __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; + + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; + +} nouveauScreenRec, *nouveauScreenPtr; + + +#endif /* __NOUVEAU_SCREEN_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c new file mode 100644 index 00000000000..ba471325aaa --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Authors: + * Ben Skeggs <[email protected]> + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" +#include "extensions.h" + +#include "program.h" +#include "tnl/tnl.h" +#include "shader/arbprogparse.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" + +/***************************************************************************** + * Mesa entry points + */ +static void +nouveauBindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog) +{ +} + +static struct gl_program * +nouveauNewProgram(GLcontext *ctx, GLenum target, GLuint id) +{ + nouveauShader *nvs; + + nvs = CALLOC_STRUCT(_nouveauShader); + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, &nvs->mesa.vp, target, id); + case GL_FRAGMENT_PROGRAM_ARB: + return _mesa_init_fragment_program(ctx, &nvs->mesa.fp, target, id); + default: + _mesa_problem(ctx, "Unsupported shader target"); + break; + } + + FREE(nvs); + return NULL; +} + +static void +nouveauDeleteProgram(GLcontext *ctx, struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + if (nvs->translated) + FREE(nvs->program); + _mesa_delete_program(ctx, prog); +} + +static void +nouveauProgramStringNotify(GLcontext *ctx, GLenum target, + struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + if (nvs->translated) + FREE(nvs->program); + nvs->translated = 0; + + _tnl_program_string(ctx, target, prog); +} + +static GLboolean +nouveauIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + return nvs->translated; +} + +GLboolean +nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program_parameter_list *plist; + int i; + + /* Translate to HW format now if necessary */ + if (!nvs->translated) { + /* Mesa ASM shader -> nouveauShader */ + if (!nouveau_shader_pass0(ctx, nvs)) + return GL_FALSE; + /* Basic dead code elimination + register usage info */ + if (!nouveau_shader_pass1(nvs)) + return GL_FALSE; + /* nouveauShader -> HW bytecode, HW register alloc */ + if (!nouveau_shader_pass2(nvs)) + return GL_FALSE; + assert(nvs->translated); + assert(nvs->program); + } + + /* Update state parameters */ + plist = nvs->mesa.vp.Base.Parameters; + _mesa_load_state_parameters(ctx, plist); + for (i=0; i<nvs->param_high; i++) { + if (!nvs->params[i].in_use) + continue; + + if (!nvs->on_hardware) { + /* if we've been kicked off the hardware there's no guarantee our + * consts are still there.. reupload them all + */ + nvs->func->UpdateConst(ctx, nvs, i); + } else if (nvs->params[i].source_val) { + /* update any changed state parameters */ + if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) + nvs->func->UpdateConst(ctx, nvs, i); + } + } + + /* Upload program to hardware, this must come after state param update + * as >=NV30 fragprogs inline consts into the bytecode. + */ + if (!nvs->on_hardware) { + nouveauShader **current; + + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + current = &nmesa->current_vertprog; + else + current = &nmesa->current_fragprog; + if (*current) (*current)->on_hardware = 0; + + nvs->func->UploadToHW(ctx, nvs); + nvs->on_hardware = 1; + + *current = nvs; + } + + return GL_TRUE; +} + +nouveauShader * +nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) +{ + nouveauShader *nvs; + + nvs = CALLOC_STRUCT(_nouveauShader); + if (!nvs) + return NULL; + + if (target == GL_VERTEX_PROGRAM_ARB) { + _mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0); + _mesa_parse_arb_vertex_program(ctx, + GL_VERTEX_PROGRAM_ARB, + text, + strlen(text), + &nvs->mesa.vp); + } else if (target == GL_FRAGMENT_PROGRAM_ARB) { + _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0); + _mesa_parse_arb_fragment_program(ctx, + GL_FRAGMENT_PROGRAM_ARB, + text, + strlen(text), + &nvs->mesa.fp); + } + + nouveau_shader_pass0(ctx, nvs); + nouveau_shader_pass1(nvs); + nouveau_shader_pass2(nvs); + + return nvs; +} + +static void +nvsBuildPassthroughVP(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + const char *vp_text = + "!!ARBvp1.0\n" + "OPTION ARB_position_invariant;" + "" + "MOV result.color, vertex.color;\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.texcoord[1], vertex.texcoord[1];\n" + "MOV result.texcoord[2], vertex.texcoord[2];\n" + "MOV result.texcoord[3], vertex.texcoord[3];\n" + "MOV result.texcoord[4], vertex.texcoord[4];\n" + "MOV result.texcoord[5], vertex.texcoord[5];\n" + "MOV result.texcoord[6], vertex.texcoord[6];\n" + "MOV result.texcoord[7], vertex.texcoord[7];\n" + "END"; + + nmesa->passthrough_vp = nvsBuildTextShader(ctx, + GL_VERTEX_PROGRAM_ARB, + vp_text); +} + +static void +nvsBuildPassthroughFP(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + const char *fp_text = + "!!ARBfp1.0\n" + "MOV result.color, fragment.color;\n" + "END"; + + nmesa->passthrough_fp = nvsBuildTextShader(ctx, + GL_FRAGMENT_PROGRAM_ARB, + fp_text); +} + +void +nouveauShaderInitFuncs(GLcontext * ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + NV20VPInitShaderFuncs(&nmesa->VPfunc); + break; + case NV_30: + NV30VPInitShaderFuncs(&nmesa->VPfunc); + NV30FPInitShaderFuncs(&nmesa->FPfunc); + break; + case NV_40: + case NV_44: + NV40VPInitShaderFuncs(&nmesa->VPfunc); + NV40FPInitShaderFuncs(&nmesa->FPfunc); + break; + case NV_50: + default: + return; + } + + /* Build a vertex program that simply passes through all attribs. + * Needed to do swtcl on nv40 + */ + if (nmesa->screen->card->type >= NV_40) + nvsBuildPassthroughVP(ctx); + + /* Needed on NV30, even when using swtcl, if you want to get colours */ + if (nmesa->screen->card->type >= NV_30) + nvsBuildPassthroughFP(ctx); + + ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeTexIndirections = + ctx->Const.VertexProgram.MaxNativeTexInstructions; + ctx->Const.VertexProgram.MaxNativeAttribs = nmesa->VPfunc.MaxAttrib; + ctx->Const.VertexProgram.MaxNativeTemps = nmesa->VPfunc.MaxTemp; + ctx->Const.VertexProgram.MaxNativeAddressRegs = nmesa->VPfunc.MaxAddress; + ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst; + + if (nmesa->screen->card->type >= NV_30) { + ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeTexIndirections = + ctx->Const.FragmentProgram.MaxNativeTexInstructions; + ctx->Const.FragmentProgram.MaxNativeAttribs = nmesa->FPfunc.MaxAttrib; + ctx->Const.FragmentProgram.MaxNativeTemps = nmesa->FPfunc.MaxTemp; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = nmesa->FPfunc.MaxAddress; + ctx->Const.FragmentProgram.MaxNativeParameters = nmesa->FPfunc.MaxConst; + } + + ctx->Driver.NewProgram = nouveauNewProgram; + ctx->Driver.BindProgram = nouveauBindProgram; + ctx->Driver.DeleteProgram = nouveauDeleteProgram; + ctx->Driver.ProgramStringNotify = nouveauProgramStringNotify; + ctx->Driver.IsProgramNative = nouveauIsProgramNative; +} + + +/***************************************************************************** + * Disassembly support structs + */ +#define CHECK_RANGE(idx, arr) ((idx)<sizeof(_##arr)/sizeof(const char *)) \ + ? _##arr[(idx)] : #arr"_OOB" + +#define NODS (1<<0) +#define BRANCH_TR (1<<1) +#define BRANCH_EL (1<<2) +#define BRANCH_EN (1<<3) +#define BRANCH_RE (1<<4) +#define BRANCH_ALL (BRANCH_TR|BRANCH_EL|BRANCH_EN) +#define COUNT_INC (1<<4) +#define COUNT_IND (1<<5) +#define COUNT_NUM (1<<6) +#define COUNT_ALL (COUNT_INC|COUNT_IND|COUNT_NUM) +#define TI_UNIT (1<<7) +struct _opcode_info +{ + const char *name; + int numsrc; + int flags; +}; + +static struct _opcode_info ops[] = { + [NVS_OP_ABS] = {"ABS", 1, 0}, + [NVS_OP_ADD] = {"ADD", 2, 0}, + [NVS_OP_ARA] = {"ARA", 1, 0}, + [NVS_OP_ARL] = {"ARL", 1, 0}, + [NVS_OP_ARR] = {"ARR", 1, 0}, + [NVS_OP_BRA] = {"BRA", 0, NODS | BRANCH_TR}, + [NVS_OP_BRK] = {"BRK", 0, NODS}, + [NVS_OP_CAL] = {"CAL", 0, NODS | BRANCH_TR}, + [NVS_OP_CMP] = {"CMP", 2, 0}, + [NVS_OP_COS] = {"COS", 1, 0}, + [NVS_OP_DIV] = {"DIV", 2, 0}, + [NVS_OP_DDX] = {"DDX", 1, 0}, + [NVS_OP_DDY] = {"DDY", 1, 0}, + [NVS_OP_DP2] = {"DP2", 2, 0}, + [NVS_OP_DP2A] = {"DP2A", 3, 0}, + [NVS_OP_DP3] = {"DP3", 2, 0}, + [NVS_OP_DP4] = {"DP4", 2, 0}, + [NVS_OP_DPH] = {"DPH", 2, 0}, + [NVS_OP_DST] = {"DST", 2, 0}, + [NVS_OP_EX2] = {"EX2", 1, 0}, + [NVS_OP_EXP] = {"EXP", 1, 0}, + [NVS_OP_FLR] = {"FLR", 1, 0}, + [NVS_OP_FRC] = {"FRC", 1, 0}, + [NVS_OP_IF] = {"IF", 0, NODS | BRANCH_EL | BRANCH_EN}, + [NVS_OP_KIL] = {"KIL", 1, 0}, + [NVS_OP_LG2] = {"LG2", 1, 0}, + [NVS_OP_LIT] = {"LIT", 1, 0}, + [NVS_OP_LOG] = {"LOG", 1, 0}, + [NVS_OP_LOOP] = {"LOOP", 0, NODS | COUNT_ALL | BRANCH_EN}, + [NVS_OP_LRP] = {"LRP", 3, 0}, + [NVS_OP_MAD] = {"MAD", 3, 0}, + [NVS_OP_MAX] = {"MAX", 2, 0}, + [NVS_OP_MIN] = {"MIN", 2, 0}, + [NVS_OP_MOV] = {"MOV", 1, 0}, + [NVS_OP_MUL] = {"MUL", 2, 0}, + [NVS_OP_NRM] = {"NRM", 1, 0}, + [NVS_OP_PK2H] = {"PK2H", 1, 0}, + [NVS_OP_PK2US] = {"PK2US", 1, 0}, + [NVS_OP_PK4B] = {"PK4B", 1, 0}, + [NVS_OP_PK4UB] = {"PK4UB", 1, 0}, + [NVS_OP_POW] = {"POW", 2, 0}, + [NVS_OP_POPA] = {"POPA", 0, 0}, + [NVS_OP_PUSHA] = {"PUSHA", 1, NODS}, + [NVS_OP_RCC] = {"RCC", 1, 0}, + [NVS_OP_RCP] = {"RCP", 1, 0}, + [NVS_OP_REP] = {"REP", 0, NODS | BRANCH_EN | COUNT_NUM}, + [NVS_OP_RET] = {"RET", 0, NODS}, + [NVS_OP_RFL] = {"RFL", 1, 0}, + [NVS_OP_RSQ] = {"RSQ", 1, 0}, + [NVS_OP_SCS] = {"SCS", 1, 0}, + [NVS_OP_SEQ] = {"SEQ", 2, 0}, + [NVS_OP_SFL] = {"SFL", 2, 0}, + [NVS_OP_SGE] = {"SGE", 2, 0}, + [NVS_OP_SGT] = {"SGT", 2, 0}, + [NVS_OP_SIN] = {"SIN", 1, 0}, + [NVS_OP_SLE] = {"SLE", 2, 0}, + [NVS_OP_SLT] = {"SLT", 2, 0}, + [NVS_OP_SNE] = {"SNE", 2, 0}, + [NVS_OP_SSG] = {"SSG", 1, 0}, + [NVS_OP_STR] = {"STR", 2, 0}, + [NVS_OP_SUB] = {"SUB", 2, 0}, + [NVS_OP_TEX] = {"TEX", 1, TI_UNIT}, + [NVS_OP_TXB] = {"TXB", 1, TI_UNIT}, + [NVS_OP_TXD] = {"TXD", 3, TI_UNIT}, + [NVS_OP_TXL] = {"TXL", 1, TI_UNIT}, + [NVS_OP_TXP] = {"TXP", 1, TI_UNIT}, + [NVS_OP_UP2H] = {"UP2H", 1, 0}, + [NVS_OP_UP2US] = {"UP2US", 1, 0}, + [NVS_OP_UP4B] = {"UP4B", 1, 0}, + [NVS_OP_UP4UB] = {"UP4UB", 1, 0}, + [NVS_OP_X2D] = {"X2D", 3, 0}, + [NVS_OP_XPD] = {"XPD", 2, 0}, + [NVS_OP_NOP] = {"NOP", 0, NODS}, +}; + +static struct _opcode_info * +_get_op_info(int op) +{ + if (op >= (sizeof(ops) / sizeof(struct _opcode_info))) + return NULL; + if (ops[op].name == NULL) + return NULL; + return &ops[op]; +} + +static const char *_SFR_STRING[] = { + [NVS_FR_POSITION] = "position", + [NVS_FR_WEIGHT] = "weight", + [NVS_FR_NORMAL] = "normal", + [NVS_FR_COL0] = "color", + [NVS_FR_COL1] = "color.secondary", + [NVS_FR_BFC0] = "bfc", + [NVS_FR_BFC1] = "bfc.secondary", + [NVS_FR_FOGCOORD] = "fogcoord", + [NVS_FR_POINTSZ] = "pointsize", + [NVS_FR_TEXCOORD0] = "texcoord[0]", + [NVS_FR_TEXCOORD1] = "texcoord[1]", + [NVS_FR_TEXCOORD2] = "texcoord[2]", + [NVS_FR_TEXCOORD3] = "texcoord[3]", + [NVS_FR_TEXCOORD4] = "texcoord[4]", + [NVS_FR_TEXCOORD5] = "texcoord[5]", + [NVS_FR_TEXCOORD6] = "texcoord[6]", + [NVS_FR_TEXCOORD7] = "texcoord[7]", + [NVS_FR_FRAGDATA0] = "data[0]", + [NVS_FR_FRAGDATA1] = "data[1]", + [NVS_FR_FRAGDATA2] = "data[2]", + [NVS_FR_FRAGDATA3] = "data[3]", + [NVS_FR_CLIP0] = "clip_plane[0]", + [NVS_FR_CLIP1] = "clip_plane[1]", + [NVS_FR_CLIP2] = "clip_plane[2]", + [NVS_FR_CLIP3] = "clip_plane[3]", + [NVS_FR_CLIP4] = "clip_plane[4]", + [NVS_FR_CLIP5] = "clip_plane[5]", + [NVS_FR_CLIP6] = "clip_plane[6]", + [NVS_FR_FACING] = "facing", +}; + +#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING) + +static const char *_SWZ_STRING[] = { + [NVS_SWZ_X] = "x", + [NVS_SWZ_Y] = "y", + [NVS_SWZ_Z] = "z", + [NVS_SWZ_W] = "w" +}; + +#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING) + +static const char *_NVS_PREC_STRING[] = { + [NVS_PREC_FLOAT32] = "R", + [NVS_PREC_FLOAT16] = "H", + [NVS_PREC_FIXED12] = "X", + [NVS_PREC_UNKNOWN] = "?" +}; + +#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING) + +static const char *_NVS_COND_STRING[] = { + [NVS_COND_FL] = "FL", + [NVS_COND_LT] = "LT", + [NVS_COND_EQ] = "EQ", + [NVS_COND_LE] = "LE", + [NVS_COND_GT] = "GT", + [NVS_COND_NE] = "NE", + [NVS_COND_GE] = "GE", + [NVS_COND_TR] = "TR", + [NVS_COND_UNKNOWN] = "??" +}; + +#define NVS_COND_STRING(idx) CHECK_RANGE((idx), NVS_COND_STRING) + +/***************************************************************************** + * ShaderFragment dumping + */ +static void +nvsDumpIndent(int lvl) +{ + while (lvl--) + printf(" "); +} + +static void +nvsDumpSwizzle(nvsSwzComp *swz) +{ + printf(".%s%s%s%s", + SWZ_STRING(swz[0]), + SWZ_STRING(swz[1]), SWZ_STRING(swz[2]), SWZ_STRING(swz[3]) + ); +} + +static void +nvsDumpReg(nvsInstruction * inst, nvsRegister * reg) +{ + if (reg->negate) + printf("-"); + if (reg->abs) + printf("abs("); + + switch (reg->file) { + case NVS_FILE_TEMP: + printf("R%d", reg->index); + nvsDumpSwizzle(reg->swizzle); + break; + case NVS_FILE_ATTRIB: + printf("attrib.%s", SFR_STRING(reg->index)); + nvsDumpSwizzle(reg->swizzle); + break; + case NVS_FILE_ADDRESS: + printf("A%d", reg->index); + break; + case NVS_FILE_CONST: + if (reg->indexed) + printf("const[A%d.%s + %d]", + reg->addr_reg, SWZ_STRING(reg->addr_comp), reg->index); + else + printf("const[%d]", reg->index); + nvsDumpSwizzle(reg->swizzle); + break; + default: + printf("UNKNOWN_FILE"); + break; + } + + if (reg->abs) + printf(")"); +} + +static void +nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl) +{ + struct _opcode_info *opr = &ops[inst->op]; + int i; + + nvsDumpIndent(lvl); + printf("%s ", opr->name); + + if (!opr->flags & NODS) { + switch (inst->dest.file) { + case NVS_FILE_RESULT: + printf("result.%s", SFR_STRING(inst->dest.index)); + break; + case NVS_FILE_TEMP: + printf("R%d", inst->dest.index); + break; + case NVS_FILE_ADDRESS: + printf("A%d", inst->dest.index); + break; + default: + printf("UNKNOWN_DST_FILE"); + break; + } + + if (inst->mask != SMASK_ALL) { + printf("."); + if (inst->mask & SMASK_X) + printf("x"); + if (inst->mask & SMASK_Y) + printf("y"); + if (inst->mask & SMASK_Z) + printf("z"); + if (inst->mask & SMASK_W) + printf("w"); + } + + if (opr->numsrc) + printf(", "); + } + + for (i = 0; i < opr->numsrc; i++) { + nvsDumpReg(inst, &inst->src[i]); + if (i != opr->numsrc - 1) + printf(", "); + } + if (opr->flags & TI_UNIT) + printf(", texture[%d]", inst->tex_unit); + + printf("\n"); +} + +void +nvsDumpFragmentList(nvsFragmentHeader *f, int lvl) +{ + while (f) { + switch (f->type) { + case NVS_INSTRUCTION: + nvsDumpInstruction((nvsInstruction*)f, 0, lvl); + break; + default: + fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in" + "nvsFragmentList!\n", __func__); + return; + } + f = f->next; + } +} + +/***************************************************************************** + * HW shader disassembly + */ +static void +nvsDisasmHWShaderOp(nvsFunc * shader, int merged) +{ + struct _opcode_info *opi; + nvsOpcode op; + nvsRegFile file; + nvsSwzComp swz[4]; + int i; + + op = shader->GetOpcode(shader, merged); + opi = _get_op_info(op); + if (!opi) { + printf("NO OPINFO!"); + return; + } + + printf("%s", opi->name); + if (shader->GetPrecision && + (!(opi->flags & BRANCH_ALL)) && (!(opi->flags * NODS)) && + (op != NVS_OP_NOP)) + printf("%s", NVS_PREC_STRING(shader->GetPrecision(shader))); + if (shader->SupportsConditional && shader->SupportsConditional(shader)) { + if (shader->GetConditionUpdate(shader)) { + printf("C%d", shader->GetCondRegID(shader)); + } + } + if (shader->GetSaturate && shader->GetSaturate(shader)) + printf("_SAT"); + + if (!(opi->flags & NODS)) { + int mask = shader->GetDestMask(shader, merged); + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_ADDRESS: + printf(" A%d", shader->GetDestID(shader, merged)); + break; + case NVS_FILE_TEMP: + printf(" R%d", shader->GetDestID(shader, merged)); + break; + case NVS_FILE_RESULT: + printf(" result.%s", (SFR_STRING(shader->GetDestID(shader, merged)))); + break; + default: + printf(" BAD_RESULT_FILE"); + break; + } + + if (mask != SMASK_ALL) { + printf("."); + if (mask & SMASK_X) printf("x"); + if (mask & SMASK_Y) printf("y"); + if (mask & SMASK_Z) printf("z"); + if (mask & SMASK_W) printf("w"); + } + } + + if (shader->SupportsConditional && shader->SupportsConditional(shader) && + shader->GetConditionTest(shader)) { + shader->GetCondRegSwizzle(shader, swz); + + printf(" (%s%d.%s%s%s%s)", + NVS_COND_STRING(shader->GetCondition(shader)), + shader->GetCondRegID(shader), + SWZ_STRING(swz[NVS_SWZ_X]), + SWZ_STRING(swz[NVS_SWZ_Y]), + SWZ_STRING(swz[NVS_SWZ_Z]), + SWZ_STRING(swz[NVS_SWZ_W]) + ); + } + + /* looping */ + if (opi->flags & COUNT_ALL) { + printf(" { "); + if (opi->flags & COUNT_NUM) { + printf("%d", shader->GetLoopCount(shader)); + } + if (opi->flags & COUNT_IND) { + printf(", %d", shader->GetLoopInitial(shader)); + } + if (opi->flags & COUNT_INC) { + printf(", %d", shader->GetLoopIncrement(shader)); + } + printf(" }"); + } + + /* branching */ + if (opi->flags & BRANCH_TR) + printf(" %d", shader->GetBranch(shader)); + if (opi->flags & BRANCH_EL) + printf(" ELSE %d", shader->GetBranchElse(shader)); + if (opi->flags & BRANCH_EN) + printf(" END %d", shader->GetBranchEnd(shader)); + + if (!(opi->flags & NODS) && opi->numsrc) + printf(","); + printf(" "); + + for (i = 0; i < opi->numsrc; i++) { + if (shader->GetSourceAbs(shader, merged, i)) + printf("abs("); + if (shader->GetSourceNegate(shader, merged, i)) + printf("-"); + + file = shader->GetSourceFile(shader, merged, i); + switch (file) { + case NVS_FILE_TEMP: + printf("R%d", shader->GetSourceID(shader, merged, i)); + break; + case NVS_FILE_CONST: + if (shader->GetSourceIndexed(shader, merged, i)) { + printf("c[A%d.%s + 0x%x]", + shader->GetRelAddressRegID(shader), + SWZ_STRING(shader->GetRelAddressSwizzle(shader)), + shader->GetSourceID(shader, merged, i) + ); + } else { + float val[4]; + + if (shader->GetSourceConstVal) { + shader->GetSourceConstVal(shader, merged, i, val); + printf("{ %.02f, %.02f, %.02f, %.02f }", + val[0], val[1], val[2], val[3]); + } else { + printf("c[0x%x]", shader->GetSourceID(shader, merged, i)); + } + } + break; + case NVS_FILE_ATTRIB: + if (shader->GetSourceIndexed(shader, merged, i)) { + printf("attrib[A%d.%s + %d]", + shader->GetRelAddressRegID(shader), + SWZ_STRING(shader->GetRelAddressSwizzle(shader)), + shader->GetSourceID(shader, merged, i) + ); + } + else { + printf("attrib.%s", + SFR_STRING(shader->GetSourceID(shader, merged, i)) + ); + } + break; + case NVS_FILE_ADDRESS: + printf("A%d", shader->GetRelAddressRegID(shader)); + break; + default: + printf("UNKNOWN_SRC_FILE"); + break; + } + + shader->GetSourceSwizzle(shader, merged, i, swz); + if (file != NVS_FILE_ADDRESS && + (swz[NVS_SWZ_X] != NVS_SWZ_X || swz[NVS_SWZ_Y] != NVS_SWZ_Y || + swz[NVS_SWZ_Z] != NVS_SWZ_Z || swz[NVS_SWZ_W] != NVS_SWZ_W)) { + printf(".%s%s%s%s", SWZ_STRING(swz[NVS_SWZ_X]), + SWZ_STRING(swz[NVS_SWZ_Y]), + SWZ_STRING(swz[NVS_SWZ_Z]), + SWZ_STRING(swz[NVS_SWZ_W])); + } + + if (shader->GetSourceAbs(shader, merged, i)) + printf(")"); + if (shader->GetSourceScale) { + int scale = shader->GetSourceScale(shader, merged, i); + if (scale > 1) + printf("{scaled %dx}", scale); + } + if (i < (opi->numsrc - 1)) + printf(", "); + } + + if (shader->IsLastInst(shader)) + printf(" + END"); +} + +void +nvsDisasmHWShader(nvsPtr nvs) +{ + nvsFunc *shader = nvs->func; + unsigned int iaddr = 0; + + if (!nvs->program) { + fprintf(stderr, "No HW program present"); + return; + } + + shader->inst = nvs->program; + while (1) { + if (shader->inst >= (nvs->program + nvs->program_size)) { + fprintf(stderr, "Reached end of program, but HW inst has no END"); + break; + } + + printf("\t0x%08x:\n", shader->inst[0]); + printf("\t0x%08x:\n", shader->inst[1]); + printf("\t0x%08x:\n", shader->inst[2]); + printf("\t0x%08x:", shader->inst[3]); + + printf("\n\t\tINST %d.0: ", iaddr); + nvsDisasmHWShaderOp(shader, 0); + if (shader->HasMergedInst(shader)) { + printf("\n\t\tINST %d.1: ", iaddr); + nvsDisasmHWShaderOp(shader, 1); + } + printf("\n"); + + if (shader->IsLastInst(shader)) + break; + + shader->inst += shader->GetOffsetNext(shader); + iaddr++; + } + + printf("\n"); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h new file mode 100644 index 00000000000..b2df3546f62 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -0,0 +1,441 @@ +#ifndef __SHADER_COMMON_H__ +#define __SHADER_COMMON_H__ + +#include "mtypes.h" +#include "bufferobj.h" + +typedef struct _nvsFunc nvsFunc; + +#define NVS_MAX_TEMPS 32 +#define NVS_MAX_ATTRIBS 16 +#define NVS_MAX_CONSTS 256 +#define NVS_MAX_ADDRESS 2 +#define NVS_MAX_INSNS 4096 + +typedef struct _nvs_fragment_header { + struct _nvs_fragment_header *parent; + struct _nvs_fragment_header *prev; + struct _nvs_fragment_header *next; + enum { + NVS_INSTRUCTION, + NVS_BRANCH, + NVS_LOOP, + NVS_SUBROUTINE + } type; +} nvsFragmentHeader; + +typedef union { + struct { + GLboolean uses_kil; + GLuint num_regs; + } NV30FP; + struct { + uint32_t vp_in_reg; + uint32_t vp_out_reg; + uint32_t clip_enables; + } NV30VP; +} nvsCardPriv; + +typedef struct _nouveauShader { + union { + struct gl_vertex_program vp; + struct gl_fragment_program fp; + } mesa; + GLcontext *ctx; + nvsFunc *func; + + /* State of the final program */ + GLboolean translated; + GLboolean on_hardware; + unsigned int *program; + unsigned int program_size; + unsigned int program_alloc_size; + unsigned int program_start_id; + unsigned int program_current; + struct gl_buffer_object *program_buffer; + int inst_count; + + nvsCardPriv card_priv; + int vp_attrib_map[NVS_MAX_ATTRIBS]; + + struct { + GLboolean in_use; + + GLfloat *source_val; /* NULL if invariant */ + float val[4]; + /* Hardware-specific tracking, currently only nv30_fragprog + * makes use of it. + */ + int *hw_index; + int hw_index_cnt; + } params[NVS_MAX_CONSTS]; + int param_high; + + /* Pass-private data */ + void *pass_rec; + + nvsFragmentHeader *program_tree; +} nouveauShader, *nvsPtr; + +typedef enum { + NVS_FILE_NONE, + NVS_FILE_TEMP, + NVS_FILE_ATTRIB, + NVS_FILE_CONST, + NVS_FILE_RESULT, + NVS_FILE_ADDRESS, + NVS_FILE_UNKNOWN +} nvsRegFile; + +typedef enum { + NVS_OP_UNKNOWN = 0, + NVS_OP_NOP, + NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR, + NVS_OP_BRA, NVS_OP_BRK, + NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS, + NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3, + NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST, + NVS_OP_EX2, NVS_OP_EXP, + NVS_OP_FLR, NVS_OP_FRC, + NVS_OP_IF, + NVS_OP_KIL, + NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP, + NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL, + NVS_OP_NRM, + NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW, + NVS_OP_POPA, NVS_OP_PUSHA, + NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ, + NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN, + NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB, + NVS_OP_SWZ, + NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP, + NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB, + NVS_OP_X2D, NVS_OP_XPD, + NVS_OP_EMUL +} nvsOpcode; + +typedef enum { + NVS_PREC_FLOAT32, + NVS_PREC_FLOAT16, + NVS_PREC_FIXED12, + NVS_PREC_UNKNOWN +} nvsPrecision; + +typedef enum { + NVS_SWZ_X = 0, + NVS_SWZ_Y = 1, + NVS_SWZ_Z = 2, + NVS_SWZ_W = 3 +} nvsSwzComp; + +typedef enum { + NVS_FR_POSITION = 0, + NVS_FR_WEIGHT = 1, + NVS_FR_NORMAL = 2, + NVS_FR_COL0 = 3, + NVS_FR_COL1 = 4, + NVS_FR_FOGCOORD = 5, + NVS_FR_TEXCOORD0 = 8, + NVS_FR_TEXCOORD1 = 9, + NVS_FR_TEXCOORD2 = 10, + NVS_FR_TEXCOORD3 = 11, + NVS_FR_TEXCOORD4 = 12, + NVS_FR_TEXCOORD5 = 13, + NVS_FR_TEXCOORD6 = 14, + NVS_FR_TEXCOORD7 = 15, + NVS_FR_BFC0 = 16, + NVS_FR_BFC1 = 17, + NVS_FR_POINTSZ = 18, + NVS_FR_FRAGDATA0 = 19, + NVS_FR_FRAGDATA1 = 20, + NVS_FR_FRAGDATA2 = 21, + NVS_FR_FRAGDATA3 = 22, + NVS_FR_CLIP0 = 23, + NVS_FR_CLIP1 = 24, + NVS_FR_CLIP2 = 25, + NVS_FR_CLIP3 = 26, + NVS_FR_CLIP4 = 27, + NVS_FR_CLIP5 = 28, + NVS_FR_CLIP6 = 29, + NVS_FR_FACING = 30, + NVS_FR_UNKNOWN +} nvsFixedReg; + +typedef enum { + NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT, + NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN, + NVS_COND_UNKNOWN +} nvsCond; + +typedef struct { + nvsRegFile file; + unsigned int index; + + unsigned int indexed; + unsigned int addr_reg; + nvsSwzComp addr_comp; + + nvsSwzComp swizzle[4]; + int negate; + int abs; +} nvsRegister; + +static const nvsRegister nvr_unused = { + .file = NVS_FILE_ATTRIB, + .index = 0, + .indexed = 0, + .addr_reg = 0, + .addr_comp = NVS_SWZ_X, + .swizzle = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W}, + .negate = 0, + .abs = 0, +}; + +typedef enum { + NVS_TEX_TARGET_1D, + NVS_TEX_TARGET_2D, + NVS_TEX_TARGET_3D, + NVS_TEX_TARGET_CUBE, + NVS_TEX_TARGET_RECT, + NVS_TEX_TARGET_UNKNOWN = 0 +} nvsTexTarget; + +typedef enum { + NVS_SCALE_1X = 0, + NVS_SCALE_2X = 1, + NVS_SCALE_4X = 2, + NVS_SCALE_8X = 3, + NVS_SCALE_INV_2X = 5, + NVS_SCALE_INV_4X = 6, + NVS_SCALE_INV_8X = 7, +} nvsScale; + +/* Arith/TEX instructions */ +typedef struct nvs_instruction { + nvsFragmentHeader header; + + nvsOpcode op; + unsigned int saturate; + + nvsRegister dest; + unsigned int mask; + nvsScale dest_scale; + + nvsRegister src[3]; + + unsigned int tex_unit; + nvsTexTarget tex_target; + + nvsCond cond; + nvsSwzComp cond_swizzle[4]; + int cond_reg; + int cond_test; + int cond_update; +} nvsInstruction; + +/* BRA, CAL, IF */ +typedef struct nvs_branch { + nvsFragmentHeader header; + + nvsOpcode op; + + nvsCond cond; + nvsSwzComp cond_swizzle[4]; + int cond_test; + + nvsFragmentHeader *target_head; + nvsFragmentHeader *target_tail; + nvsFragmentHeader *else_head; + nvsFragmentHeader *else_tail; +} nvsBranch; + +/* LOOP+ENDLOOP */ +typedef struct { + nvsFragmentHeader header; + + int count; + int initial; + int increment; + + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsLoop; + +/* label+following instructions */ +typedef struct nvs_subroutine { + nvsFragmentHeader header; + + char * label; + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsSubroutine; + +#define SMASK_X (1<<0) +#define SMASK_Y (1<<1) +#define SMASK_Z (1<<2) +#define SMASK_W (1<<3) +#define SMASK_ALL (SMASK_X|SMASK_Y|SMASK_Z|SMASK_W) + +#define SPOS_ADDRESS 3 +struct _op_xlat { + unsigned int NV; + nvsOpcode SOP; + int srcpos[3]; +}; +#define MOD_OPCODE(t,hw,sop,s0,s1,s2) do { \ + t[hw].NV = hw; \ + t[hw].SOP = sop; \ + t[hw].srcpos[0] = s0; \ + t[hw].srcpos[1] = s1; \ + t[hw].srcpos[2] = s2; \ +} while(0) + +extern unsigned int NVVP_TX_VOP_COUNT; +extern unsigned int NVVP_TX_NVS_OP_COUNT; +extern struct _op_xlat NVVP_TX_VOP[]; +extern struct _op_xlat NVVP_TX_SOP[]; + +extern unsigned int NVFP_TX_AOP_COUNT; +extern unsigned int NVFP_TX_BOP_COUNT; +extern struct _op_xlat NVFP_TX_AOP[]; +extern struct _op_xlat NVFP_TX_BOP[]; + +extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz); +extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; + +#define SCAP_SRC_ABS (1<<0) + +struct _nvsFunc { + nvsCardPriv *card_priv; + + unsigned int MaxInst; + unsigned int MaxAttrib; + unsigned int MaxTemp; + unsigned int MaxAddress; + unsigned int MaxConst; + unsigned int caps; + + unsigned int *inst; + void (*UploadToHW) (GLcontext *, nouveauShader *); + void (*UpdateConst) (GLcontext *, nouveauShader *, int); + + struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged); + struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id); + + void (*InitInstruction) (nvsFunc *); + int (*SupportsOpcode) (nvsFunc *, nvsOpcode); + int (*SupportsResultScale) (nvsFunc *, nvsScale); + void (*SetOpcode) (nvsFunc *, unsigned int opcode, + int slot); + void (*SetCCUpdate) (nvsFunc *); + void (*SetCondition) (nvsFunc *, int on, nvsCond, int reg, + nvsSwzComp *swizzle); + void (*SetResult) (nvsFunc *, nvsRegister *, + unsigned int mask, int slot); + void (*SetResultScale) (nvsFunc *, nvsScale); + void (*SetSource) (nvsFunc *, nvsRegister *, int pos); + void (*SetTexImageUnit) (nvsFunc *, int unit); + void (*SetSaturate) (nvsFunc *); + void (*SetLastInst) (nvsFunc *); + + void (*SetBranchTarget) (nvsFunc *, int addr); + void (*SetBranchElse) (nvsFunc *, int addr); + void (*SetBranchEnd) (nvsFunc *, int addr); + void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc); + + int (*HasMergedInst) (nvsFunc *); + int (*IsLastInst) (nvsFunc *); + int (*GetOffsetNext) (nvsFunc *); + + int (*GetOpcodeSlot) (nvsFunc *, int merged); + unsigned int (*GetOpcodeHW) (nvsFunc *, int slot); + nvsOpcode (*GetOpcode) (nvsFunc *, int merged); + + nvsPrecision (*GetPrecision) (nvsFunc *); + int (*GetSaturate) (nvsFunc *); + + nvsRegFile (*GetDestFile) (nvsFunc *, int merged); + unsigned int (*GetDestID) (nvsFunc *, int merged); + unsigned int (*GetDestMask) (nvsFunc *, int merged); + + unsigned int (*GetSourceHW) (nvsFunc *, int merged, int pos); + nvsRegFile (*GetSourceFile) (nvsFunc *, int merged, int pos); + int (*GetSourceID) (nvsFunc *, int merged, int pos); + int (*GetTexImageUnit) (nvsFunc *); + int (*GetSourceNegate) (nvsFunc *, int merged, int pos); + int (*GetSourceAbs) (nvsFunc *, int merged, int pos); + void (*GetSourceSwizzle) (nvsFunc *, int merged, int pos, + nvsSwzComp *swz); + int (*GetSourceIndexed) (nvsFunc *, int merged, int pos); + void (*GetSourceConstVal) (nvsFunc *, int merged, int pos, + float *val); + int (*GetSourceScale) (nvsFunc *, int merged, int pos); + + int (*GetRelAddressRegID) (nvsFunc *); + nvsSwzComp (*GetRelAddressSwizzle) (nvsFunc *); + + int (*SupportsConditional) (nvsFunc *); + int (*GetConditionUpdate) (nvsFunc *); + int (*GetConditionTest) (nvsFunc *); + nvsCond (*GetCondition) (nvsFunc *); + void (*GetCondRegSwizzle) (nvsFunc *, nvsSwzComp *swz); + int (*GetCondRegID) (nvsFunc *); + int (*GetBranch) (nvsFunc *); + int (*GetBranchElse) (nvsFunc *); + int (*GetBranchEnd) (nvsFunc *); + + int (*GetLoopCount) (nvsFunc *); + int (*GetLoopInitial) (nvsFunc *); + int (*GetLoopIncrement) (nvsFunc *); +}; + +static inline nvsRegister +nvsNegate(nvsRegister reg) +{ + reg.negate = !reg.negate; + return reg; +} + +static inline nvsRegister +nvsAbs(nvsRegister reg) +{ + reg.abs = 1; + return reg; +} + +static inline nvsRegister +nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y, + nvsSwzComp z, nvsSwzComp w) +{ + nvsSwzComp sc[4] = { x, y, z, w }; + nvsSwzComp oc[4]; + int i; + + for (i=0;i<4;i++) + oc[i] = reg.swizzle[i]; + for (i=0;i<4;i++) + reg.swizzle[i] = oc[sc[i]]; + return reg; +} + +extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs); +extern void nvsDisasmHWShader(nvsPtr); +extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl); +extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target, + const char *text); + +extern void NV20VPInitShaderFuncs(nvsFunc *); +extern void NV30VPInitShaderFuncs(nvsFunc *); +extern void NV40VPInitShaderFuncs(nvsFunc *); + +extern void NV30FPInitShaderFuncs(nvsFunc *); +extern void NV40FPInitShaderFuncs(nvsFunc *); + +extern void nouveauShaderInitFuncs(GLcontext *ctx); + +extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs); +extern GLboolean nouveau_shader_pass1(nvsPtr nvs); +extern GLboolean nouveau_shader_pass2(nvsPtr nvs); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c new file mode 100644 index 00000000000..73c1f7c2a53 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -0,0 +1,1006 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Authors: + * Ben Skeggs <[email protected]> + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "programopt.h" +#include "program_instruction.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" +#include "nouveau_msg.h" + +static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, + NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ +}; + +static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { + NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, + NVS_FR_UNKNOWN /* DEPR */ +}; + +static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsSwzComp _tx_mesa_swizzle[4] = { + NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W +}; + +static nvsOpcode _tx_mesa_opcode[] = { + [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, + [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, + [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, + [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, + [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, + [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, + [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, + [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, + [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, + [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, + [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, + [OPCODE_LOG] = NVS_OP_LOG, + [OPCODE_LRP] = NVS_OP_LRP, + [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, + [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, + [OPCODE_MUL] = NVS_OP_MUL, + [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, + [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, + [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, + [OPCODE_PUSHA] = NVS_OP_PUSHA, + [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, + [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, + [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, + [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, + [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, + [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, + [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, + [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, + [OPCODE_SWZ] = NVS_OP_MOV, + [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, + [OPCODE_TXD] = NVS_OP_TXD, + [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, + [OPCODE_TXP_NV] = NVS_OP_TXP, + [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, + [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, + [OPCODE_X2D] = NVS_OP_X2D, + [OPCODE_XPD] = NVS_OP_XPD +}; + +static nvsCond _tx_mesa_condmask[] = { + NVS_COND_TR, /* workaround mesa not filling a valid value */ + NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL +}; + +struct pass0_rec { + int nvs_ipos; + int next_temp; + + int mesa_const_base; + int mesa_const_last; + + int swzconst_done; + int swzconst_id; + nvsRegister const_half; +}; + +#define X NVS_SWZ_X +#define Y NVS_SWZ_Y +#define Z NVS_SWZ_Z +#define W NVS_SWZ_W + +#define FILL_CONDITION_FLAGS(fragment) do { \ + (fragment)->cond = \ + pass0_make_condmask(inst->DstReg.CondMask); \ + if ((fragment)->cond != NVS_COND_TR) \ + (fragment)->cond_test = 1; \ + (fragment)->cond_reg = inst->CondDst; \ + pass0_make_swizzle((fragment)->cond_swizzle, inst->DstReg.CondSwizzle);\ +} while(0) + +#define ARITH(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ + FILL_CONDITION_FLAGS(nvsinst); \ +} while(0) + +#define ARITHu(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ +} while(0) + +static void +pass0_append_fragment(nvsFragmentHeader *parent, + nvsFragmentHeader *fragment, + int pos) +{ + nvsFragmentHeader **head, **tail; + assert(parent && fragment); + + switch (parent->type) { + case NVS_BRANCH: + if (pos == 0) { + head = &((nvsBranch *)parent)->target_head; + tail = &((nvsBranch *)parent)->target_tail; + } else { + head = &((nvsBranch *)parent)->else_head; + tail = &((nvsBranch *)parent)->else_tail; + } + break; + case NVS_LOOP: + head = &((nvsLoop *)parent)->insn_head; + tail = &((nvsLoop *)parent)->insn_tail; + break; + case NVS_SUBROUTINE: + head = &((nvsSubroutine *)parent)->insn_head; + tail = &((nvsSubroutine *)parent)->insn_tail; + break; + default: + assert(0); + break; + } + + fragment->parent = parent; + fragment->prev = *tail; + fragment->next = NULL; + if (!(*head)) + *head = fragment; + else + (*tail)->next = fragment; + *tail = fragment; + +} + +static nvsSubroutine * +pass0_create_subroutine(nouveauShader *nvs, const char *label) +{ + nvsSubroutine *sub; + + sub = CALLOC_STRUCT(nvs_subroutine); + if (sub) { + sub->header.type = NVS_SUBROUTINE; + sub->label = strdup(label); + if (!nvs->program_tree) + nvs->program_tree = &sub->header; + else + pass0_append_fragment(nvs->program_tree, + &sub->header, 0); + } + + return sub; +} + +static void +pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, + nvsRegFile file, unsigned int index) +{ + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; +} + +static void +pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) +{ + int i; + + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; +} + +static nvsOpcode +pass0_make_opcode(enum prog_opcode op) +{ + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; +} + +static nvsCond +pass0_make_condmask(GLuint mesa) +{ + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; +} + +static unsigned int +pass0_make_mask(GLuint mesa_mask) +{ + unsigned int mask = 0; + + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + + return mask; +} + +static nvsTexTarget +pass0_make_tex_target(GLuint mesa) +{ + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } +} + +static void +pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, + struct prog_dst_register *dst) +{ + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } +} + +static void +pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + int i; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + for (i=0; i<NVS_MAX_ATTRIBS; i++) { + if (nvs->vp_attrib_map[i] == src->Index) { + reg->index = i; + break; + } + } + if (i==NVS_MAX_ATTRIBS) + reg->index = NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : + NVS_FR_UNKNOWN; + } + break; + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + reg->file = NVS_FILE_CONST; + reg->index = src->Index + rec->mesa_const_base; + reg->indexed = src->RelAddr; + if (reg->indexed) { + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); +} + +static nvsInstruction * +pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, + nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, + nvsRegister src0, nvsRegister src1, nvsRegister src2) +{ + nvsInstruction *sif; + + sif = CALLOC_STRUCT(nvs_instruction); + if (!sif) + return NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->dest_scale = NVS_SCALE_1X; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update= 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(parent, &sif->header, fpos); + + return sif; +} + +static void +pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, + struct prog_src_register *src, + unsigned int sm1, + unsigned int sm2) +{ + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsInstruction *nvsinst; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, + sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && + sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, + * so move the const into a temp, and swizzle from there. + * + * TODO: should just emit the swizzled const, instead of + * swizzling it in the shader.. would need to reswizzle + * any state params when they change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + ARITHu(NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, + NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + ARITHu(NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + ARITHu(NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; +} + +#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) +static void +pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) +{ + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<<c)) + SET_SWZ(sm_2, c, SWIZZLE_Z); /* -1.0 */ + else + SET_SWZ(sm_2, c, SWIZZLE_X); /* 1.0 */ + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<<c)) + SET_SWZ(sm_1, c, SWIZZLE_Z); /* -[xyzw] */ + else + SET_SWZ(sm_1, c, SWIZZLE_X); /*[xyzw]*/ + SET_SWZ(sm_2, c, SWIZZLE_Y); + } + } + + /* Unless we're multiplying by 1.0 or -1.0 on all components, + * and we're adding nothing to any component we have to + * emulate the swizzle. + */ + if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) && + sm_1 != MAKE_SWIZZLE4(2,2,2,2)) || + sm_2 != MAKE_SWIZZLE4(1,1,1,1)) { + pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2); + /* The source is definitely in a temp now, so don't + * bother checking for multiple ATTRIB/CONST regs. + */ + continue; + } + + /* HW can't use more than one ATTRIB or PARAM in a single + * instruction */ + switch (src->File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa + * instruction to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } +} + +static GLboolean +pass0_emulate_instruction(nouveauShader *nvs, + nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) +{ + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + ARITH(NVS_OP_MOV, dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + ARITH(NVS_OP_MAX, dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_CMP: + /*XXX: this will clobber CC0... */ + ARITH (NVS_OP_MOV, dest, mask, sat, + src[2], nvr_unused, nvr_unused); + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + ARITH (NVS_OP_MOV, dest, mask, sat, + src[1], nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + break; + case OPCODE_DPH: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_DP3, temp, SMASK_X, 0, + src[0], src[1], nvr_unused); + ARITH (NVS_OP_ADD, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], W, W, W, W), + nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + *XXX: might have to worry with GLSL however... + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + ARITHu(NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, SWIZZLE_NOOP); + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + ARITH (NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, nvr_unused); + nvsinst->dest_scale = NVS_SCALE_INV_2X; + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsNegate(nvsSwizzle(temp, X, X, X, X)), + nvr_unused, nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + ARITH(NVS_OP_COS, dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, nvr_unused); + if (mask & SMASK_Y) + ARITH(NVS_OP_SIN, dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, nvr_unused); + break; + case OPCODE_SUB: + ARITH(NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + ARITH (NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + WARN_ONCE("hw doesn't support opcode \"%s\"," + "and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean +pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog, + int ipos, int fpos, + nvsFragmentHeader *parent) +{ + struct prog_instruction *inst = &prog->Instructions[ipos]; + nvsFunc *shader = nvs->func; + nvsInstruction *nvsinst; + GLboolean ret; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, parent, fpos, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction + * conversion + */ + if (shader->SupportsOpcode(shader, + pass0_make_opcode(inst->Opcode))) { + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + ARITH(pass0_make_opcode(inst->Opcode), dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + + ret = GL_TRUE; + } else + ret = pass0_emulate_instruction(nvs, parent, fpos, inst); + + return ret; +} + +static GLboolean +pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, + nvsFragmentHeader *parent) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + + while (1) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + switch (inst->Opcode) { + case OPCODE_END: + return GL_TRUE; + case OPCODE_BRA: + case OPCODE_CAL: + case OPCODE_RET: + //case OPCODE_LOOP: + //case OPCODE_ENDLOOP: + //case OPCODE_IF: + //case OPCODE_ELSE: + //case OPCODE_ENDIF: + WARN_ONCE("branch ops unimplemented\n"); + return GL_FALSE; + break; + default: + if (!pass0_translate_arith(nvs, prog, + ipos, fpos, parent)) + return GL_FALSE; + break; + } + + ipos++; + } + + return GL_TRUE; +} + +static void +pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) +{ + GLuint inputs_read = vp->Base.InputsRead; + GLuint input_alloc = ~0xFFFF; + int i; + + for (i=0; i<NVS_MAX_ATTRIBS; i++) + nvs->vp_attrib_map[i] = -1; + + while (inputs_read) { + int in = ffs(inputs_read) - 1; + int hw; + inputs_read &= ~(1<<in); + + if (vp->IsNVProgram) { + /* NVvp: must alias */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = in - VERT_ATTRIB_GENERIC0; + else + hw = in; + } else { + /* ARBvp: may alias (but we won't) + * GL2.0: must not alias + */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = ffs(~input_alloc) - 1; + else + hw = in; + input_alloc |= (1<<hw); + } + + nvs->vp_attrib_map[hw] = in; + } + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + printf("vtxprog attrib map:\n"); + for (i=0; i<NVS_MAX_ATTRIBS; i++) { + printf(" hw:%d = attrib:%d\n", + i, nvs->vp_attrib_map[i]); + } + } +} + +static void +pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) +{ + struct gl_program *prog = &nvs->mesa.vp.Base; + nvsFragmentHeader *parent = nvs->program_tree; + nvsInstruction *nvsinst; + GLuint fpos = 0; + nvsRegister opos, epos, eqn, mv[4]; + GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 }; + GLint id; + int i; + + /* modelview transform */ + pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION); + pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1); + for (i=0; i<4; i++) { + tokens[3] = tokens[4] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id); + } + ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused); + + /* Emit code to emulate fixed-function glClipPlane */ + for (i=0; i<6; i++) { + GLuint clipmask = SMASK_X; + nvsRegister clip; + + if (!(ctx->Transform.ClipPlanesEnabled & (1<<i))) + continue; + + /* Point a const at a user clipping plane */ + tokens[0] = STATE_CLIPPLANE; + tokens[1] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id); + pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i); + + /*XXX: something else needs to take care of modifying the + * instructions to write to the correct hw clip register. + */ + switch (i) { + case 0: case 3: clipmask = SMASK_Y; break; + case 1: case 4: clipmask = SMASK_Z; break; + case 2: case 5: clipmask = SMASK_W; break; + } + + /* Emit transform */ + ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused); + } +} + +static void +pass0_rebase_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct prog_instruction *inst = prog->Instructions; + int i; + + /*XXX: not a good idea, params->hw_index is malloc'd */ + memset(nvs->params, 0x00, sizeof(nvs->params)); + + /* When doing relative addressing on constants, the hardware needs us + * to fill the "const id" field with a positive value. Determine the + * most negative index that is used so that all accesses to a + * mesa-provided constant can be rebased to a positive index. + */ + while (inst->Opcode != OPCODE_END) { + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + + switch (src->File) { + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_NAMED_PARAM: + if (src->RelAddr && src->Index < 0) { + int base = src->Index * -1; + if (rec->mesa_const_base < base) + rec->mesa_const_base = base; + } + break; + default: + break; + } + } + + inst++; + } +} + +static void +pass0_resolve_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + + /* Init all const tracking/alloc info from the parameter list, rather + * than doing it as we translate the program. Otherwise: + * 1) we can't get at the correct constant info when relative + * addressing is being used due to src->Index not pointing + * at the exact const; + * 2) as we add extra consts to the program, mesa will call realloc() + * and we get invalid pointers to the const data. + */ + rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; + nvs->param_high = rec->mesa_const_last; + for (i=0; i<plist->NumParameters; i++) { + int hw = rec->mesa_const_base + i; + + switch (plist->Parameters[i].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = plist->ParameterValues[i]; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + case PROGRAM_CONSTANT: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = NULL; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + default: + assert(0); + break; + } + } +} + +GLboolean +nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret = GL_FALSE; + + rec = CALLOC_STRUCT(pass0_rec); + if (!rec) + return GL_FALSE; + + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (!nvs->program_tree) { + FREE(rec); + return GL_FALSE; + } + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); + pass0_rebase_mesa_consts(nvs); + + if (!prog->String && ctx->Transform.ClipPlanesEnabled) + pass0_vp_insert_ff_clip_planes(ctx, nvs); + + pass0_build_attrib_map(nvs, vp); + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + pass0_rebase_mesa_consts(nvs); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + FREE(rec); + /* DESTROY TREE!! */ + return GL_FALSE; + } + nvs->func->card_priv = &nvs->card_priv; + + ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + if (ret) + pass0_resolve_mesa_consts(nvs); + /*XXX: if (!ret) DESTROY TREE!!! */ + + FREE(rec); + return ret; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c new file mode 100644 index 00000000000..90c57d38078 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c @@ -0,0 +1,14 @@ +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "nouveau_shader.h" + +GLboolean +nouveau_shader_pass1(nvsPtr nvs) +{ + + return GL_TRUE; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c new file mode 100644 index 00000000000..b043f877e42 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Authors: + * Ben Skeggs <[email protected]> + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" +#include "nouveau_msg.h" + +struct pass2_rec { + /* Map nvsRegister temp ID onto hw temp ID */ + unsigned int temps[NVS_MAX_TEMPS]; + /* Track free hw registers */ + unsigned int hw_temps[NVS_MAX_TEMPS]; +}; + +static int +pass2_alloc_hw_temp(nvsPtr nvs) +{ + struct pass2_rec *rec = nvs->pass_rec; + int i; + + for (i=0; i<nvs->func->MaxTemp; i++) { + /* This is a *horrible* hack.. R0 is both temp0 and result.color + * in NV30/40 fragprogs, we can use R0 as a temp before result + * is written however.. + */ + if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) + continue; + if (rec->hw_temps[i] == 0) { + rec->hw_temps[i] = 1; + return i; + } + } + + return -1; +} + +static nvsRegister +pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) +{ + struct pass2_rec *rec = nvs->pass_rec; + + if (reg.file == NVS_FILE_TEMP) { + if (rec->temps[reg.index] == -1) + rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); + reg.index = rec->temps[reg.index]; + } + + return reg; +} + +static void +pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, + struct _op_xlat *op, int slot) +{ + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, + NVS_SWZ_Z, NVS_SWZ_W }; + nvsFunc *shader = nvs->func; + nvsRegister reg; + int i; + + shader->SetOpcode(shader, op->NV, slot); + if (inst->saturate ) shader->SetSaturate(shader); + if (inst->cond_update ) shader->SetCCUpdate(shader); + if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, + inst->cond_reg, + inst->cond_swizzle); + else shader->SetCondition(shader, 0, NVS_COND_TR, + 0, + default_swz); + switch (inst->op) { + case NVS_OP_TEX: + case NVS_OP_TXB: + case NVS_OP_TXL: + case NVS_OP_TXP: + case NVS_OP_TXD: + shader->SetTexImageUnit(shader, inst->tex_unit); + break; + default: + break; + } + + for (i = 0; i < 3; i++) { + if (op->srcpos[i] != -1) { + reg = pass2_mangle_reg(nvs, inst, inst->src[i]); + + shader->SetSource(shader, ®, op->srcpos[i]); + + if (reg.file == NVS_FILE_CONST && + shader->GetSourceConstVal) { + int idx_slot = + nvs->params[reg.index].hw_index_cnt++; + nvs->params[reg.index].hw_index = realloc( + nvs->params[reg.index].hw_index, + sizeof(int) * idx_slot+1); + nvs->params[reg.index].hw_index[idx_slot] = + nvs->program_current + 4; + } + } + } + + reg = pass2_mangle_reg(nvs, inst, inst->dest); + shader->SetResult(shader, ®, inst->mask, slot); + + if (inst->dest_scale != NVS_SCALE_1X) { + shader->SetResultScale(shader, inst->dest_scale); + } +} + +static int +pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) +{ + nvsFunc *shader = nvs->func; + struct _op_xlat *op; + unsigned int hw_inst[8]; + int slot; + int instsz; + int i; + + shader->inst = hw_inst; + + /* Assemble this instruction */ + if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) + return 0; + shader->InitInstruction(shader); + pass2_add_instruction(nvs, inst, op, slot); + if (last) + shader->SetLastInst(shader); + + instsz = shader->GetOffsetNext(nvs->func); + if (nvs->program_size + instsz >= nvs->program_alloc_size) { + nvs->program_alloc_size *= 2; + nvs->program = realloc(nvs->program, + nvs->program_alloc_size * + sizeof(uint32_t)); + } + + for (i=0; i<instsz; i++) + nvs->program[nvs->program_current++] = hw_inst[i]; + nvs->program_size = nvs->program_current; + return 1; +} + +static GLboolean +pass2_translate(nvsPtr nvs, nvsFragmentHeader *f) +{ + nvsFunc *shader = nvs->func; + GLboolean last; + + while (f) { + last = (f == ((nvsSubroutine*)nvs->program_tree)->insn_tail); + + switch (f->type) { + case NVS_INSTRUCTION: + if (!pass2_assemble_instruction(nvs, + (nvsInstruction *)f, + last)) + return GL_FALSE; + break; + default: + WARN_ONCE("Unimplemented fragment type\n"); + return GL_FALSE; + } + + f = f->next; + } + + return GL_TRUE; +} + +/* Translate program into hardware format */ +GLboolean +nouveau_shader_pass2(nvsPtr nvs) +{ + struct pass2_rec *rec; + int i; + + rec = calloc(1, sizeof(struct pass2_rec)); + for (i=0; i<NVS_MAX_TEMPS; i++) + rec->temps[i] = -1; + nvs->pass_rec = rec; + + /* Start off with allocating 4 uint32_t's for each inst, will be grown + * if necessary.. + */ + nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; + nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); + nvs->program_size = 0; + nvs->program_current = 0; + + if (!pass2_translate(nvs, + ((nvsSubroutine*)nvs->program_tree)->insn_head)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; + } + + /* Shrink allocated memory to only what we need */ + nvs->program = realloc(nvs->program, + nvs->program_size * sizeof(uint32_t)); + nvs->program_alloc_size = nvs->program_size; + + nvs->translated = 1; + nvs->on_hardware = 0; + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + fflush(stdout); fflush(stderr); + fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n", + _mesa_lookup_enum_by_nr( + nvs->mesa.vp.Base.Target), + nvs->mesa.vp.Base.Id); + fflush(stdout); fflush(stderr); + _mesa_print_program(&nvs->mesa.vp.Base); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + nvsDisasmHWShader(nvs); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + } + + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c new file mode 100644 index 00000000000..74dec66afcf --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -0,0 +1,125 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_fifo.h" +#include "nouveau_lock.h" + +#include "swrast/swrast.h" + +#define HAVE_HW_DEPTH_SPANS 0 +#define HAVE_HW_DEPTH_PIXELS 0 +#define HAVE_HW_STENCIL_SPANS 0 +#define HAVE_HW_STENCIL_PIXELS 0 + +#define HW_CLIPLOOP() \ + do { \ + int _nc = nmesa->numClipRects; \ + while ( _nc-- ) { \ + int minx = nmesa->pClipRects[_nc].x1 - nmesa->drawX; \ + int miny = nmesa->pClipRects[_nc].y1 - nmesa->drawY; \ + int maxx = nmesa->pClipRects[_nc].x2 - nmesa->drawX; \ + int maxy = nmesa->pClipRects[_nc].y2 - nmesa->drawY; + +#define LOCAL_VARS \ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *)rb; \ + GLuint height = nrb->mesa.Height; \ + GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \ + (nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \ + GLuint p; \ + (void) p; + +#define Y_FLIP( _y ) (height - _y - 1) + +#define HW_LOCK() + +#define HW_UNLOCK() + + + +/* ================================================================ + * Color buffers + */ + +/* RGB565 */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 + +#define TAG(x) nouveau##x##_RGB565 +#define TAG2(x,y) nouveau##x##_RGB565##y +#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp) +#include "spantmp2.h" + + +/* ARGB8888 */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) nouveau##x##_ARGB8888 +#define TAG2(x,y) nouveau##x##_ARGB8888##y +#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp) +#include "spantmp2.h" + +static void +nouveauSpanRenderStart( GLcontext *ctx ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + FIRE_RING(); + LOCK_HARDWARE(nmesa); + nouveauWaitForIdleLocked( nmesa ); +} + +static void +nouveauSpanRenderFinish( GLcontext *ctx ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + _swrast_flush( ctx ); + nouveauWaitForIdleLocked( nmesa ); + UNLOCK_HARDWARE( nmesa ); +} + +void nouveauSpanInitFunctions( GLcontext *ctx ) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = nouveauSpanRenderStart; + swdd->SpanRenderFinish = nouveauSpanRenderFinish; +} + + +/** + * Plug in the Get/Put routines for the given driRenderbuffer. + */ +void +nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis) +{ + if (nrb->mesa._ActualFormat == GL_RGBA8) + nouveauInitPointers_ARGB8888(&nrb->mesa); + else if (nrb->mesa._ActualFormat == GL_RGB5) + nouveauInitPointers_RGB565(&nrb->mesa); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h new file mode 100644 index 00000000000..bc39ecd17b5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.h @@ -0,0 +1,39 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NOUVEAU_SPAN_H__ +#define __NOUVEAU_SPAN_H__ + +#include "drirenderbuffer.h" +#include "nouveau_buffers.h" + +extern void nouveauSpanInitFunctions( GLcontext *ctx ); +extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis); + +#endif /* __NOUVEAU_SPAN_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c new file mode 100644 index 00000000000..e9fd188d73e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -0,0 +1,345 @@ +/************************************************************************** + +Copyright 2006 Jeremy Kolb +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_state.h" +#include "nouveau_swtcl.h" +#include "nouveau_fifo.h" + +#include "swrast/swrast.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static __inline__ GLuint nouveauPackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (format) { + case 2: + return PACK_COLOR_565( r, g, b ); + case 4: + return PACK_COLOR_8888( r, g, b, a); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} + +static void nouveauCalcViewport(GLcontext *ctx) +{ + /* Calculate the Viewport Matrix */ + + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = nmesa->viewport.m; + GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY; + + nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale; + + nmesa->hw_func.WindowMoved(nmesa); +} + +static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* + * Need to send (at least on an nv35 the following: + * cons = 4 (this may be bytes per pixel) + * + * The viewport: + * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ? + * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons + * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons + * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons + * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons + * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS + * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x + * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y) + * + */ + + nouveauCalcViewport(ctx); +} + +static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far) +{ + nouveauCalcViewport(ctx); +} + +static void nouveauDDUpdateHWState(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int new_state = nmesa->new_state; + + if ( new_state || nmesa->new_render_state & _NEW_TEXTURE ) + { + nmesa->new_state = 0; + + /* Update the various parts of the context's state. + */ + /* + if ( new_state & NOUVEAU_NEW_ALPHA ) + nouveauUpdateAlphaMode( ctx ); + + if ( new_state & NOUVEAU_NEW_DEPTH ) + nouveauUpdateZMode( ctx ); + + if ( new_state & NOUVEAU_NEW_FOG ) + nouveauUpdateFogAttrib( ctx ); + + if ( new_state & NOUVEAU_NEW_CLIP ) + nouveauUpdateClipping( ctx ); + + if ( new_state & NOUVEAU_NEW_CULL ) + nouveauUpdateCull( ctx ); + + if ( new_state & NOUVEAU_NEW_MASKS ) + nouveauUpdateMasks( ctx ); + + if ( new_state & NOUVEAU_NEW_WINDOW ) + nouveauUpdateWindow( ctx ); + + if ( nmesa->new_render_state & _NEW_TEXTURE ) { + nouveauUpdateTextureState( ctx ); + }*/ + } +} + +static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state; +} + +/* Initialize the context's hardware state. */ +void nouveauDDInitState(nouveauContextPtr nmesa) +{ + uint32_t type = nmesa->screen->card->type; + switch(type) + { + case NV_03: + /* Unimplemented */ + break; + case NV_04: + case NV_05: + nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; + case NV_10: + nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; + case NV_20: + nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; + case NV_30: + case NV_40: + case NV_44: + nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; + case NV_50: + nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; + default: + break; + } + nouveau_state_cache_init(nmesa); +} + +/* Initialize the driver's state functions */ +void nouveauDDInitStateFuncs(GLcontext *ctx) +{ + ctx->Driver.UpdateState = nouveauDDInvalidateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = NULL; //nouveauDDClearColor; + ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil; + ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer; + ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = NULL; //nouveauDDColorMask; + ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc; + ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate; + ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate; + ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth; + ctx->Driver.CullFace = NULL; //nouveauDDCullFace; + ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace; + ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc; + ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask; + ctx->Driver.Enable = NULL; //nouveauDDEnable; + ctx->Driver.Fogfv = NULL; //nouveauDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv; + ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple; + ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode; + ctx->Driver.Scissor = NULL; //nouveauDDScissor; + ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel; + ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate; + ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate; + ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate; + + ctx->Driver.DepthRange = nouveauDepthRange; + ctx->Driver.Viewport = nouveauViewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} + +#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a + +void nouveauInitState(GLcontext *ctx) +{ + /* + * Mesa should do this for us: + */ + + STATE_INIT(AlphaFunc)( ctx, + ctx->Color.AlphaFunc, + ctx->Color.AlphaRef); + + STATE_INIT(BlendColor)( ctx, + ctx->Color.BlendColor ); + + STATE_INIT(BlendEquationSeparate)( ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + STATE_INIT(BlendFuncSeparate)( ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, + ctx->Color.BlendDstA); + + STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor); + STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear); + STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear); + + STATE_INIT(ColorMask)( ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode ); + STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func ); + STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask ); + + STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); + STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled ); + STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); + STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); + STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); + STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); + STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag ); + STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled ); + STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled ); + STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag ); + STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint); + STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); + STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); + STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); + + STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 ); + STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start ); + STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End ); + + STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace ); + + { + GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; + STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); + } + + STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern ); + STATE_INIT(LineWidth)( ctx, ctx->Line.Width ); + STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp ); + STATE_INIT(PointSize)( ctx, ctx->Point.Size ); + STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode ); + STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode ); + STATE_INIT(PolygonOffset)( ctx, + ctx->Polygon.OffsetFactor, + ctx->Polygon.OffsetUnits ); + STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple ); + STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel ); + STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0] ); + STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1] ); + STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); + STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); + STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + STATE_INIT(StencilOpSeparate)( ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h new file mode 100644 index 00000000000..dbac71760b6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -0,0 +1,50 @@ +/************************************************************************** + +Copyright 2006 Jeremy Kolb +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __NOUVEAU_STATE_H__ +#define __NOUVEAU_STATE_H__ + +#include "nouveau_context.h" + +extern void nouveauDDInitState(nouveauContextPtr nmesa); +extern void nouveauDDInitStateFuncs(GLcontext *ctx); + +extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); + +extern void nouveauInitState(GLcontext *ctx); + +/* +extern void nouveauDDUpdateState(GLcontext *ctx); +extern void nouveauDDUpdateHWState(GLcontext *ctx); + +extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa); +*/ +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c new file mode 100644 index 00000000000..cb4b9d30270 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c @@ -0,0 +1,69 @@ + +#include "nouveau_state_cache.h" +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" + +#define BEGIN_RING_NOFLUSH(subchannel,tag,size) do { \ + if (nmesa->fifo.free <= (size)) \ + WAIT_RING(nmesa,(size)); \ + OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ + nmesa->fifo.free -= ((size) + 1); \ +}while(0) + +// flush all the dirty state +void nouveau_state_cache_flush(nouveauContextPtr nmesa) +{ + int i=0; + int run=0; + + // fast-path no state changes + if (!nmesa->state_cache.dirty) + return; + nmesa->state_cache.dirty=0; + + do + { + // jump to a dirty state + while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES)) + i=(i&~(NOUVEAU_STATE_CACHE_HIER_SIZE-1))+NOUVEAU_STATE_CACHE_HIER_SIZE; + while((nmesa->state_cache.atoms[i].dirty==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES)) + i++; + + // figure out a run of dirty values + run=0; + while((nmesa->state_cache.atoms[i+run].dirty)&&(i+run<NOUVEAU_STATE_CACHE_ENTRIES)) + run++; + + // output everything as a single run + if (run>0) { + int j; + + BEGIN_RING_NOFLUSH(NvSub3D, i*4, run); + for(j=0;j<run;j++) + { + OUT_RING(nmesa->state_cache.atoms[i+j].value); + nmesa->state_cache.atoms[i+j].dirty=0; + if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0) + nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; + } + i+=run; + } + } + while(i<NOUVEAU_STATE_CACHE_ENTRIES); + nmesa->state_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; +} + + +// inits the state cache +void nouveau_state_cache_init(nouveauContextPtr nmesa) +{ + int i; + for(i=0;i<NOUVEAU_STATE_CACHE_ENTRIES;i++) + { + nmesa->state_cache.atoms[i].dirty=0; + nmesa->state_cache.atoms[i].value=0xDEADBEEF; // nvidia cards like beef + } + nmesa->state_cache.dirty=0; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h new file mode 100644 index 00000000000..5f9d426450b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h @@ -0,0 +1,29 @@ + +#ifndef __NOUVEAU_STATE_CACHE_H__ +#define __NOUVEAU_STATE_CACHE_H__ + +#include "mtypes.h" + +#define NOUVEAU_STATE_CACHE_ENTRIES 2048 +// size of a dirty requests block +// you can play with that and tune the value to increase/decrease performance +// but keep it a power of 2 ! +#define NOUVEAU_STATE_CACHE_HIER_SIZE 32 + +typedef struct nouveau_state_atom_t{ + uint32_t value; + uint32_t dirty; +}nouveau_state_atom; + +typedef struct nouveau_state_cache_t{ + nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES]; + uint32_t current_pos; + // hierarchical dirty flags + uint8_t hdirty[NOUVEAU_STATE_CACHE_ENTRIES/NOUVEAU_STATE_CACHE_HIER_SIZE]; + // master dirty flag + uint8_t dirty; +}nouveau_state_cache; + + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c new file mode 100644 index 00000000000..8a013bd9995 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -0,0 +1,127 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* Common software TCL code */ + +#include "nouveau_context.h" +#include "nouveau_swtcl.h" +#include "nv10_swtcl.h" +#include "nouveau_span.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + +/* Common tri functions */ + +/* The fallbacks */ +void nouveau_fallback_tri(struct nouveau_context *nmesa, + nouveauVertex *v0, + nouveauVertex *v1, + nouveauVertex *v2) +{ + GLcontext *ctx = nmesa->glCtx; + SWvertex v[3]; + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swsetup_Translate(ctx, v2, &v[2]); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); +} + + +void nouveau_fallback_line(struct nouveau_context *nmesa, + nouveauVertex *v0, + nouveauVertex *v1) +{ + GLcontext *ctx = nmesa->glCtx; + SWvertex v[2]; + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swrast_Line(ctx, &v[0], &v[1]); +} + + +void nouveau_fallback_point(struct nouveau_context *nmesa, + nouveauVertex *v0) +{ + GLcontext *ctx = nmesa->glCtx; + SWvertex v[1]; + _swsetup_Translate(ctx, v0, &v[0]); + _swrast_Point(ctx, &v[0]); +} + +void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = nmesa->glCtx; + GLuint oldfallback = nmesa->Fallback; + + if (mode) { + nmesa->Fallback |= bit; + if (oldfallback == 0) { + if (nmesa->screen->card->type<NV_10) { + //nv04FinishPrimitive(nmesa); + } else { + //nv10FinishPrimitive(nmesa); + } + + _swsetup_Wakeup(ctx); + nmesa->render_index = ~0; + } + } + else { + nmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + + if (nmesa->screen->card->type<NV_10) { + nv04TriInitFunctions(ctx); + } else { + nv10TriInitFunctions(ctx); + } + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + nmesa->viewport.m, 0 ); + } + } +} + + +void nouveauRunPipeline( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + _tnl_run_pipeline( ctx ); +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h new file mode 100644 index 00000000000..ba4d8725a65 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h @@ -0,0 +1,55 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NOUVEAU_SWTCL_H__ +#define __NOUVEAU_SWTCL_H__ + +#include "nouveau_context.h" + +extern void nouveau_fallback_tri(struct nouveau_context *nmesa, + nouveauVertex *v0, + nouveauVertex *v1, + nouveauVertex *v2); + +extern void nouveau_fallback_line(struct nouveau_context *nmesa, + nouveauVertex *v0, + nouveauVertex *v1); + +extern void nouveau_fallback_point(struct nouveau_context *nmesa, + nouveauVertex *v0); + +extern void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode); + +extern void nouveauRunPipeline( GLcontext *ctx ); + +extern void nouveauTriInitFunctions( GLcontext *ctx ); + + +#endif /* __NOUVEAU_SWTCL_H__ */ + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c new file mode 100644 index 00000000000..c47ff3a985d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "vblank.h" /* for DO_USLEEP */ + +#include "nouveau_context.h" +#include "nouveau_buffers.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" +#include "nouveau_sync.h" + +nouveau_notifier * +nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_notifier *notifier; + +#ifdef NOUVEAU_RING_DEBUG + return NULL; +#endif + + notifier = CALLOC_STRUCT(nouveau_notifier_t); + if (!notifier) + return NULL; + + notifier->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, + count * NV_NOTIFIER_SIZE, + 0); + if (!notifier->mem) { + FREE(notifier); + return NULL; + } + + if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset, + notifier->mem->size, + 0 /* NV_DMA_TARGET_FB */, + 0 /* NV_DMA_ACCESS_RW */)) { + nouveau_mem_free(ctx, notifier->mem); + FREE(notifier); + return NULL; + } + + notifier->handle = handle; + return notifier; +} + +void +nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) +{ + /*XXX: free DMA object.. */ + nouveau_mem_free(ctx, notifier->mem); + FREE(notifier); +} + +void +nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +GLuint +nouveau_notifier_status(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +GLuint +nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + +GLboolean +nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, + GLuint status, GLuint timeout) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + unsigned int time = 0; + +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + + while (time <= timeout) { + if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { + MESSAGE("Notifier returned error: 0x%04x\n", + n[NV_NOTIFY_STATE] & + NV_NOTIFY_STATE_ERROR_CODE_MASK); + return GL_FALSE; + } + + if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >> + NV_NOTIFY_STATE_STATUS_SHIFT) == status) + return GL_TRUE; + + if (timeout) { + DO_USLEEP(1); + time++; + } + } + + MESSAGE("Notifier timed out\n"); + return GL_FALSE; +} + +void +nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, + GLuint subc) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLboolean ret; + + nouveau_notifier_reset(notifier, 0); + + BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); + OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); + BEGIN_RING_SIZE(subc, NV_NOP, 1); + OUT_RING (0); + FIRE_RING(); + + ret = nouveau_notifier_wait_status(notifier, 0, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0 /* no timeout */); + if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); +} + +GLboolean nouveauSyncInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1); + if (!nmesa->syncNotifier) { + MESSAGE("Failed to create channel sync notifier\n"); + return GL_FALSE; + } + + /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D + * object classes + */ + BEGIN_RING_CACHE(NvSub3D, 0x180, 1); + OUT_RING_CACHE (NvSyncNotify); +#ifdef ALLOW_MULTI_SUBCHANNEL + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (NvSyncNotify); +#endif + + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h new file mode 100644 index 00000000000..019d5f6629b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __NOUVEAU_SYNC_H__ +#define __NOUVEAU_SYNC_H__ + +#include "nouveau_buffers.h" + +#define NV_NOTIFIER_SIZE 32 +#define NV_NOTIFY_TIME_0 0x00000000 +#define NV_NOTIFY_TIME_1 0x00000004 +#define NV_NOTIFY_RETURN_VALUE 0x00000008 +#define NV_NOTIFY_STATE 0x0000000C +#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000 +#define NV_NOTIFY_STATE_STATUS_SHIFT 24 +#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00 +#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01 +#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF +#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0 + +/* Methods that (hopefully) all objects have */ +#define NV_NOP 0x00000100 +#define NV_NOTIFY 0x00000104 +#define NV_NOTIFY_STYLE_WRITE_ONLY 0 + +typedef struct nouveau_notifier_t { + GLuint handle; + nouveau_mem *mem; +} nouveau_notifier; + +extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle, + GLuint count); +extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); +extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id); +extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id, + GLuint status, GLuint timeout); +extern void nouveau_notifier_wait_nop(GLcontext *ctx, + nouveau_notifier *, GLuint subc); + +extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/src/mesa/drivers/dri/nouveau/nouveau_tex.c new file mode 100644 index 00000000000..0a8d2796695 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.c @@ -0,0 +1,49 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#include "nouveau_tex.h" + +// XXX needs some love +void nouveauTexInitFunctions( struct dd_function_table *functions ) +{ +/* + functions->TexEnv = nouveauTexEnv; + functions->ChooseTextureFormat = nouveauChooseTextureFormat; + functions->TexImage1D = nouveauTexImage1D; + functions->TexSubImage1D = nouveauTexSubImage1D; + functions->TexImage2D = nouveauTexImage2D; + functions->TexSubImage2D = nouveauTexSubImage2D; + functions->TexParameter = nouveauTexParameter; + functions->BindTexture = nouveauBindTexture; + functions->NewTextureObject = nouveauNewTextureObject; + functions->DeleteTexture = nouveauDeleteTexture; + functions->IsTextureResident = driIsTextureResident; + + driInitTextureFormats(); +*/ +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.h b/src/mesa/drivers/dri/nouveau/nouveau_tex.h new file mode 100644 index 00000000000..7ac71f8300b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.h @@ -0,0 +1,38 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#ifndef __NOUVEAU_TEX_H__ +#define __NOUVEAU_TEX_H__ + +#include <errno.h> +#include "mtypes.h" +#include "macros.h" +#include "dd.h" + +extern void nouveauTexInitFunctions( struct dd_function_table *functions ); + +#endif /* __NOUVEAU_TEX_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c new file mode 100644 index 00000000000..4129ecc50ea --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -0,0 +1,538 @@ +/************************************************************************** + +Copyright 2007 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static uint32_t nv04_compare_func(GLuint f) +{ + switch ( f ) { + case GL_NEVER: return 1; + case GL_LESS: return 2; + case GL_EQUAL: return 3; + case GL_LEQUAL: return 4; + case GL_GREATER: return 5; + case GL_NOTEQUAL: return 6; + case GL_GEQUAL: return 7; + case GL_ALWAYS: return 8; + } + WARN_ONCE("Unable to find the function\n"); + return 0; +} + +static uint32_t nv04_blend_func(GLuint f) +{ + switch ( f ) { + case GL_ZERO: return 0x1; + case GL_ONE: return 0x2; + case GL_SRC_COLOR: return 0x3; + case GL_ONE_MINUS_SRC_COLOR: return 0x4; + case GL_SRC_ALPHA: return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: return 0x6; + case GL_DST_ALPHA: return 0x7; + case GL_ONE_MINUS_DST_ALPHA: return 0x8; + case GL_DST_COLOR: return 0x9; + case GL_ONE_MINUS_DST_COLOR: return 0xA; + case GL_SRC_ALPHA_SATURATE: return 0xB; + } + WARN_ONCE("Unable to find the function 0x%x\n",f); + return 0; +} + +static void nv04_emit_control(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t control,cull; + GLubyte alpha_ref; + + CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef); + control=alpha_ref; + control|=(nv04_compare_func(ctx->Color.AlphaFunc)<<8); + control|=(ctx->Color.AlphaEnabled<<12); + control|=(1<<13); + control|=(ctx->Depth.Test<<14); + control|=(nv04_compare_func(ctx->Depth.Func)<<16); + if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK)) + { + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=2; + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=2; + } + else + if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK) + cull=0; + else + cull=1; + control|=(cull<<20); + control|=(ctx->Color.DitherFlag<<22); + if ((ctx->Depth.Test)&&(ctx->Depth.Mask)) + control|=(1<<24); + + control|=(1<<30); // integer zbuffer format + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING_CACHE(control); +} + +static void nv04_emit_blend(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + switch(ctx->Light.ShadeModel) { + case GL_SMOOTH:blend|=(1<<6);break; + case GL_FLAT: blend|=(2<<6);break; + default:break; + } + if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST) + blend|=(1<<8); + blend|=(ctx->Fog.Enabled<<16); + blend|=(ctx->Color.BlendEnabled<<20); + blend|=(nv04_blend_func(ctx->Color.BlendSrcRGB)<<24); + blend|=(nv04_blend_func(ctx->Color.BlendDstRGB)<<28); + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING_CACHE(blend); +} + +static void nv04_emit_fog_color(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ); + c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] ); + c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] ); + c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] ); + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); +} + +static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nv04_emit_control(ctx); +} + +static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nv04_emit_blend(ctx); +} + +static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nv04_emit_blend(ctx); +} + + +static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nv04_emit_blend(ctx); +} + +static void nv04Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + +static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + /* TODO */ +} + +static void nv04ClearDepth(GLcontext *ctx, GLclampd d) +{ + /* TODO */ +} + +static void nv04ClearStencil(GLcontext *ctx, GLint s) +{ + /* TODO */ +} + +static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* TODO */ +} + +static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + /* TODO */ +} + +static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO I need love */ +} + +static void nv04CullFace(GLcontext *ctx, GLenum mode) +{ + nv04_emit_control(ctx); +} + +static void nv04FrontFace(GLcontext *ctx, GLenum mode) +{ + /* TODO */ +} + +static void nv04DepthFunc(GLcontext *ctx, GLenum func) +{ + nv04_emit_control(ctx); +} + +static void nv04DepthMask(GLcontext *ctx, GLboolean flag) +{ + /* TODO */ +} + +static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + /* TODO */ +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + switch(cap) + { + case GL_ALPHA_TEST: + nv04_emit_control(ctx); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + nv04_emit_blend(ctx); + break; +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: +// case GL_COLOR_LOGIC_OP: +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + nv04_emit_control(ctx); + break; + case GL_DEPTH_TEST: + nv04_emit_control(ctx); + break; + case GL_DITHER: + nv04_emit_control(ctx); + break; + case GL_FOG: + nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: +// case GL_POLYGON_OFFSET_POINT: +// case GL_POLYGON_OFFSET_LINE: +// case GL_POLYGON_OFFSET_FILL: +// case GL_POLYGON_SMOOTH: +// case GL_POLYGON_STIPPLE: +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: +// case GL_STENCIL_TEST: +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); +} + +static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + switch(target) + { + case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break; + default:break; + } +} + +static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + /* TODO not even in your dreams */ +} + +static void nv04LineWidth(GLcontext *ctx, GLfloat width) +{ + /* TODO */ +} + +static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + /* TODO */ +} + +static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* TODO */ +} + +static void nv04PointSize(GLcontext *ctx, GLfloat size) +{ + /* TODO */ +} + +static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO */ +} + +/** Set the scale and units used to calculate depth values */ +static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + /* TODO */ +} + +/** Set the polygon stippling pattern */ +static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* TODO */ +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO */ +} + +/** Select flat or smooth shading */ +static void nv04ShadeModel(GLcontext *ctx, GLenum mode) +{ + nv04_emit_blend(ctx); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + /* TODO */ +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +/* Update anything that depends on the window position/size */ +static void nv04WindowMoved(nouveauContextPtr nmesa) +{ +} + +/* Initialise any card-specific non-GL related state */ +static GLboolean nv04InitCard(nouveauContextPtr nmesa) +{ + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1); + OUT_RING(NvCtxSurf3D); + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(color[0]->pitch|(depth?(depth->pitch<<16):0)); + OUT_RING(color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RING(depth->offset); + } + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING((w<<16)|x); + OUT_RING((h<<16)|y); + + /* FIXME not sure... */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1); + OUT_RING((h<<16)|w); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING(108/*A8R8G8B8*/); + else + OUT_RING(103/*R5G6B5*/); + + return GL_TRUE; +} + +void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv04AlphaFunc; + func->BlendColor = nv04BlendColor; + func->BlendEquationSeparate = nv04BlendEquationSeparate; + func->BlendFuncSeparate = nv04BlendFuncSeparate; + func->Clear = nv04Clear; + func->ClearColor = nv04ClearColor; + func->ClearDepth = nv04ClearDepth; + func->ClearStencil = nv04ClearStencil; + func->ClipPlane = nv04ClipPlane; + func->ColorMask = nv04ColorMask; + func->ColorMaterial = nv04ColorMaterial; + func->CullFace = nv04CullFace; + func->FrontFace = nv04FrontFace; + func->DepthFunc = nv04DepthFunc; + func->DepthMask = nv04DepthMask; + func->DepthRange = nv04DepthRange; + func->Enable = nv04Enable; + func->Fogfv = nv04Fogfv; + func->Hint = nv04Hint; +/* func->Lightfv = nv04Lightfv;*/ +/* func->LightModelfv = nv04LightModelfv; */ + func->LineStipple = nv04LineStipple; /* Not for NV04 */ + func->LineWidth = nv04LineWidth; + func->LogicOpcode = nv04LogicOpcode; + func->PointParameterfv = nv04PointParameterfv; + func->PointSize = nv04PointSize; + func->PolygonMode = nv04PolygonMode; + func->PolygonOffset = nv04PolygonOffset; + func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */ +/* func->ReadBuffer = nv04ReadBuffer;*/ +/* func->RenderMode = nv04RenderMode;*/ + func->Scissor = nv04Scissor; + func->ShadeModel = nv04ShadeModel; + func->StencilFuncSeparate = nv04StencilFuncSeparate; + func->StencilMaskSeparate = nv04StencilMaskSeparate; + func->StencilOpSeparate = nv04StencilOpSeparate; +/* func->TexGen = nv04TexGen;*/ +/* func->TexParameter = nv04TexParameter;*/ +/* func->TextureMatrix = nv04TextureMatrix;*/ + + nmesa->hw_func.InitCard = nv04InitCard; + nmesa->hw_func.BindBuffers = nv04BindBuffers; + nmesa->hw_func.WindowMoved = nv04WindowMoved; +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c new file mode 100644 index 00000000000..9b5332b77a7 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c @@ -0,0 +1,618 @@ +/* + * Copyright 2007 Stephane Marchesin. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Software TCL for NV04, NV05, NV06 */ + +#include <stdio.h> +#include <math.h> + +#include "glheader.h" +#include "context.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" +#include "enums.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "nouveau_swtcl.h" +#include "nv04_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" + +static void nv04RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +static void nv04RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv04ResetLineStipple( GLcontext *ctx ); + + +static inline void nv04_2triangles(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3,nouveauVertex* v4,nouveauVertex* v5) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RINGp(v4,8); + OUT_RINGp(v5,8); + OUT_RING(0xFEDCBA); +} + +static inline void nv04_1triangle(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RING(0xFED); +} + +static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RING(0xFECEDC); +} + +static inline void nv04_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1triangle(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize) + ); +} + +static inline void nv04_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1quad(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize), + (nouveauVertex*)(vertptr+v4*vertsize) + ); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +static void nv04_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // erm +} + +static void nv04_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // umm +} + +static void nv04_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // yeah +} + +static void nv04_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // right +} + +static void nv04_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;i<count-5;i+=6) + nv04_2triangles(nmesa, + (nouveauVertex*)(vertptr+(i+0)*vertsize), + (nouveauVertex*)(vertptr+(i+1)*vertsize), + (nouveauVertex*)(vertptr+(i+2)*vertsize), + (nouveauVertex*)(vertptr+(i+3)*vertsize), + (nouveauVertex*)(vertptr+(i+4)*vertsize), + (nouveauVertex*)(vertptr+(i+5)*vertsize) + ); + if (i!=count) + { + nv04_1triangle(nmesa, + (nouveauVertex*)(vertptr+(i+0)*vertsize), + (nouveauVertex*)(vertptr+(i+1)*vertsize), + (nouveauVertex*)(vertptr+(i+2)*vertsize) + ); + i+=3; + } + if (i!=count) + printf("oops\n"); +} + +static void nv04_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + int i,j; + + for(i=start;i<count;i+=14) + { + int numvert=MIN2(16,count-i); + int numtri=numvert-2; + if (numvert<3) + break; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8); + for(j=0;j<numvert;j++) + OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8); + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2); + for(j=0;j<numtri/2;j++) + OUT_RING(striptbl[j]); + if (numtri%2) + OUT_RING(striptbl[numtri/2]&0xFFF); + } +} + +static void nv04_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+start*vertsize),8); + + for(i=start+1;i<count;i+=14) + { + int numvert=MIN2(15,count-i); + int numtri=numvert-1; + if (numvert<3) + break; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8); + + for(j=0;j<numvert;j++) + OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8); + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2); + for(j=0;j<numtri/2;j++) + OUT_RING(fantbl[j]); + if (numtri%2) + OUT_RING(fantbl[numtri/2]&0xFFF); + } +} + +static void nv04_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;i<count;i+=4) + nv04_1quad(nmesa, + (nouveauVertex*)(vertptr+(i+0)*vertsize), + (nouveauVertex*)(vertptr+(i+1)*vertsize), + (nouveauVertex*)(vertptr+(i+2)*vertsize), + (nouveauVertex*)(vertptr+(i+3)*vertsize) + ); +} + +static void nv04_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ +} + +static void (*nv04_render_tab_verts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + nv04_render_points_verts, + nv04_render_lines_verts, + nv04_render_line_loop_verts, + nv04_render_line_strip_verts, + nv04_render_triangles_verts, + nv04_render_tri_strip_verts, + nv04_render_tri_fan_verts, + nv04_render_quads_verts, + nv04_render_tri_strip_verts, //nv04_render_quad_strip_verts + nv04_render_tri_fan_verts, //nv04_render_poly_verts + nv04_render_noop_verts, +}; + + +static void nv04_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // erm +} + +static void nv04_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // umm +} + +static void nv04_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // yeah +} + +static void nv04_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // right +} + +static void nv04_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;i<count-5;i+=6) + nv04_2triangles(nmesa, + (nouveauVertex*)(vertptr+elt[i+0]*vertsize), + (nouveauVertex*)(vertptr+elt[i+1]*vertsize), + (nouveauVertex*)(vertptr+elt[i+2]*vertsize), + (nouveauVertex*)(vertptr+elt[i+3]*vertsize), + (nouveauVertex*)(vertptr+elt[i+4]*vertsize), + (nouveauVertex*)(vertptr+elt[i+5]*vertsize) + ); + if (i!=count) + { + nv04_1triangle(nmesa, + (nouveauVertex*)(vertptr+elt[i+0]*vertsize), + (nouveauVertex*)(vertptr+elt[i+1]*vertsize), + (nouveauVertex*)(vertptr+elt[i+2]*vertsize) + ); + i+=3; + } + if (i!=count) + printf("oops\n"); +} + +static void nv04_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + for(i=start;i<count;i+=14) + { + int numvert=MIN2(16,count-i); + int numtri=numvert-2; + if (numvert<3) + break; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8); + for(j=0;j<numvert;j++) + OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8); + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2); + for(j=0;j<numtri/2;j++) + OUT_RING(striptbl[j]); + if (numtri%2) + OUT_RING(striptbl[numtri/2]&0xFFF); + } +} + +static void nv04_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+elt[start]*vertsize),8); + + for(i=start+1;i<count;i+=14) + { + int numvert=MIN2(15,count-i); + int numtri=numvert-2; + if (numvert<3) + break; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8); + + for(j=0;j<numvert;j++) + OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8); + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2); + for(j=0;j<numtri/2;j++) + OUT_RING(fantbl[j]); + if (numtri%2) + OUT_RING(fantbl[numtri/2]&0xFFF); + } +} + +static void nv04_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;i<count;i+=4) + nv04_1quad(nmesa, + (nouveauVertex*)(vertptr+elt[i+0]*vertsize), + (nouveauVertex*)(vertptr+elt[i+1]*vertsize), + (nouveauVertex*)(vertptr+elt[i+2]*vertsize), + (nouveauVertex*)(vertptr+elt[i+3]*vertsize) + ); +} + +static void nv04_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ +} + +static void (*nv04_render_tab_elts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + nv04_render_points_elts, + nv04_render_lines_elts, + nv04_render_line_loop_elts, + nv04_render_line_strip_elts, + nv04_render_triangles_elts, + nv04_render_tri_strip_elts, + nv04_render_tri_fan_elts, + nv04_render_quads_elts, + nv04_render_tri_strip_elts, // nv04_render_quad_strip_elts, + nv04_render_tri_fan_elts, // nv04_render_poly_elts, + nv04_render_noop_elts, +}; + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = 0; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = EMIT_PAD; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].offset = (N); \ + nmesa->vertex_attr_count++; \ +} while (0) + +static void nv04_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ +} + +static void nv04_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ +} + +static void nv04ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts; + tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts; + tnl->Driver.Render.ClippedLine = nv04_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv04_render_clipped_poly; + tnl->Driver.Render.Points = nv04_render_points; + tnl->Driver.Render.Line = nv04_render_line; + tnl->Driver.Render.Triangle = nv04_render_triangle; + tnl->Driver.Render.Quad = nv04_render_quad; +} + + + +static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa) +{ + GLcontext* ctx=nmesa->glCtx; + DECLARE_RENDERINPUTS(index); + + /* + * Tell t_vertex about the vertex format + */ + RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); + + // SX SY SZ INVW + // FIXME : we use W instead of INVW, but since W=1 it doesn't matter + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_POS)) + EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_4F_VIEWPORT); + else + EMIT_PAD(4*sizeof(float)); + + // COLOR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR0)) + EMIT_ATTR(_TNL_ATTRIB_COLOR0,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // SPECULAR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR1)) + EMIT_ATTR(_TNL_ATTRIB_COLOR1,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // TEXTURE + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_TEX0)) + EMIT_ATTR(_TNL_ATTRIB_TEX0,EMIT_2F); + else + EMIT_PAD(2*sizeof(float)); + + nmesa->vertex_size=_tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + ctx->Viewport._WindowMap.m, 0 ); +} + + +static void nv04ChooseVertexState( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); + + RENDERINPUTS_COPY(index, tnl->render_inputs_bitset); + if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset)) + { + RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index); + nv04OutputVertexFormat(nmesa); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv04RenderStart(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + if (nmesa->new_render_state) { + nv04ChooseVertexState(ctx); + nv04ChooseRenderState(ctx); + nmesa->new_render_state = 0; + } +} + +static void nv04RenderFinish(GLcontext *ctx) +{ +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv04RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint hwprim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + assert (!nmesa->new_state); + + if (hwprim != nmesa->current_primitive) + { + nmesa->current_primitive=hwprim; + + } +} + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINE_STRIP+1, + GL_LINE_LOOP+1, + GL_TRIANGLES+1, + GL_TRIANGLE_STRIP+1, + GL_TRIANGLE_FAN+1, + GL_QUADS+1, + GL_QUAD_STRIP+1, + GL_POLYGON+1 +}; + +/* Callback for mesa: + */ +static void nv04RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv04RasterPrimitive( ctx, prim, hw_prim[prim] ); +} + +static void nv04ResetLineStipple( GLcontext *ctx ) +{ + /* FIXME do something here */ + WARN_ONCE("Unimplemented nv04ResetLineStipple\n"); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void nv04TriInitFunctions(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = nouveauRunPipeline; + tnl->Driver.Render.Start = nv04RenderStart; + tnl->Driver.Render.Finish = nv04RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv04RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = nv04ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 32 ); + + nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.h b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h new file mode 100644 index 00000000000..42dde5383eb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h @@ -0,0 +1,12 @@ +#ifndef __NV04_SWTCL_H__ +#define __NV04_SWTCL_H__ + +#include "mtypes.h" + +extern void nv04Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv04FinishPrimitive(struct nouveau_context *nmesa); +extern void nv04TriInitFunctions(GLcontext *ctx); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV04_SWTCL_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c new file mode 100644 index 00000000000..5f304ccab92 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -0,0 +1,798 @@ +/************************************************************************** + +Copyright 2006 Nouveau +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv10ViewportScale(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + + GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; +/* if (ctx->DrawBuffer) { + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + } else {*/ + /* Default to 24 bits range */ + max_depth *= 16777215.0; +/* }*/ + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); + OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (max_depth); + OUT_RING_CACHEf (0.0); +} + +static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); +} + +static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( modeRGB == modeA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE(modeRGB); +} + + +static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( sfactorRGB == sfactorA ); + assert( dfactorRGB == dfactorA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE(sfactorRGB); + OUT_RING_CACHE(dfactorRGB); +} + +static void nv10Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + +static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]); +} + +static void nv10ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +/* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + nmesa->clear_value = (uint32_t)(d*0x7FFF); + break; + case 24:*/ + nmesa->clear_value = ((nmesa->clear_value&0x000000FF) | + (((uint32_t)(d*0xFFFFFF))<<8)); +/* break; + }*/ +} + +static void nv10ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +/* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/ + nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)| + (s&0x000000FF)); +/* }*/ +} + +static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); +} + +static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO I need love */ +} + +static void nv10CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv10FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv10DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv10DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + GLfloat depth_scale = 16777216.0; + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) { + depth_scale = 32768.0; + } + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval * depth_scale); + OUT_RING_CACHEf(farval * depth_scale); + + nv10ViewportScale(nmesa); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DITHER: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_FOG: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=1<<(2*(cap-GL_LIGHT0)); + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (nmesa->lighting_enabled) + { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); + } + break; + } + case GL_LIGHTING: + nmesa->lighting_enabled=state; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING_CACHE(nmesa->enabled_lights); + else + OUT_RING_CACHE(0x0); + break; + case GL_LINE_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POLYGON_STIPPLE: +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(pname) + { + case GL_FOG_MODE: + //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING_CACHE (params); + break; + /* TODO: unsure about the rest.*/ + default: + break; + } + +} + +static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + /* TODO I need love (fog and line_smooth hints) */ +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +enum { + SPOTLIGHT_NO_UPDATE, + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + +static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + int spotlight_update = SPOTLIGHT_NO_UPDATE; + + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPOT_DIRECTION: + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; + break; + case GL_SPOT_EXPONENT: + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; + break; + case GL_SPOT_CUTOFF: + spotlight_update = SPOTLIGHT_UPDATE_ALL; + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + default: + break; + } + + switch(spotlight_update) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } +} + +/** Set the lighting model parameters */ +static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + /* Not for NV10 */ +} + +static void nv10LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHE(((int) (width * 8.0)) & -4); +} + +static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +static void nv10PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHE(((int) (size * 8.0)) & -4); +} + +static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv10PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + +/** Set the polygon stippling pattern */ +static void nv10PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* Not for NV10 */ +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ +} + +/** Select flat or smooth shading */ +static void nv10ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); +} + +/* Update anything that depends on the window position/size */ +static void nv10WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING_CACHE(0); + } + + nv10ViewportScale(nmesa); +} + +/* Initialise any card-specific non-GL related state */ +static GLboolean nv10InitCard(nouveauContextPtr nmesa) +{ + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2); + OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */ + OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2); + OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ + OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ + + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); + OUT_RING(0); + + /* not for nv10, only for >= nv11 */ + if ((nmesa->screen->card->id>>4) >= 0x11) { + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + } + + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + GLuint pitch, format, depth_pitch; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; + format = 0x108; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + format = 0x103; /* R5G6B5 color buffer */ + } + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + return GL_TRUE; +} + +void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv10AlphaFunc; + func->BlendColor = nv10BlendColor; + func->BlendEquationSeparate = nv10BlendEquationSeparate; + func->BlendFuncSeparate = nv10BlendFuncSeparate; + func->Clear = nv10Clear; + func->ClearColor = nv10ClearColor; + func->ClearDepth = nv10ClearDepth; + func->ClearStencil = nv10ClearStencil; + func->ClipPlane = nv10ClipPlane; + func->ColorMask = nv10ColorMask; + func->ColorMaterial = nv10ColorMaterial; + func->CullFace = nv10CullFace; + func->FrontFace = nv10FrontFace; + func->DepthFunc = nv10DepthFunc; + func->DepthMask = nv10DepthMask; + func->DepthRange = nv10DepthRange; + func->Enable = nv10Enable; + func->Fogfv = nv10Fogfv; + func->Hint = nv10Hint; + func->Lightfv = nv10Lightfv; +/* func->LightModelfv = nv10LightModelfv; */ + func->LineStipple = nv10LineStipple; /* Not for NV10 */ + func->LineWidth = nv10LineWidth; + func->LogicOpcode = nv10LogicOpcode; + func->PointParameterfv = nv10PointParameterfv; + func->PointSize = nv10PointSize; + func->PolygonMode = nv10PolygonMode; + func->PolygonOffset = nv10PolygonOffset; + func->PolygonStipple = nv10PolygonStipple; /* Not for NV10 */ +/* func->ReadBuffer = nv10ReadBuffer;*/ +/* func->RenderMode = nv10RenderMode;*/ + func->Scissor = nv10Scissor; + func->ShadeModel = nv10ShadeModel; + func->StencilFuncSeparate = nv10StencilFuncSeparate; + func->StencilMaskSeparate = nv10StencilMaskSeparate; + func->StencilOpSeparate = nv10StencilOpSeparate; +/* func->TexGen = nv10TexGen;*/ +/* func->TexParameter = nv10TexParameter;*/ + func->TextureMatrix = nv10TextureMatrix; + + nmesa->hw_func.InitCard = nv10InitCard; + nmesa->hw_func.BindBuffers = nv10BindBuffers; + nmesa->hw_func.WindowMoved = nv10WindowMoved; +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c new file mode 100644 index 00000000000..32da40661b4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -0,0 +1,647 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2006 Stephane Marchesin. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Software TCL for NV10, NV20, NV30, NV40, NV50 */ + +#include <stdio.h> +#include <math.h> + +#include "glheader.h" +#include "context.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" +#include "enums.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "nouveau_swtcl.h" +#include "nv10_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" + +static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv10ResetLineStipple( GLcontext *ctx ); + + + +static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) +{ + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); + else + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); + OUT_RING(primitive); + + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); + else + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); +} + +inline void nv10FinishPrimitive(struct nouveau_context *nmesa) +{ + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); + else + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); + OUT_RING(0x0); + FIRE_RING(); +} + + +static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) +{ + /* make sure there's enough room. if not, wait */ + if (RING_AVAILABLE()<size) + { + WAIT_RING(nmesa,size); + } +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(count-start)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword); + nv10FinishPrimitive(nmesa); +} + +static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS); +} + +static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES); +} + +static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP); +} + +static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP); +} + +static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES); +} + +static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP); +} + +static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN); +} + +static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS); +} + +static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP); +} + +static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON); +} + +static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ +} + +static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + nv10_render_points_verts, + nv10_render_lines_verts, + nv10_render_line_loop_verts, + nv10_render_line_strip_verts, + nv10_render_triangles_verts, + nv10_render_tri_strip_verts, + nv10_render_tri_fan_verts, + nv10_render_quads_verts, + nv10_render_quad_strip_verts, + nv10_render_poly_verts, + nv10_render_noop_verts, +}; + + +static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(count-start)/4; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword); + for (j=start; j<count; j++ ) { + OUT_RINGp((nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize/4); + } + nv10FinishPrimitive(nmesa); +} + +static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS); +} + +static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES); +} + +static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP); +} + +static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP); +} + +static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES); +} + +static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP); +} + +static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN); +} + +static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS); +} + +static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP); +} + +static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON); +} + +static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ +} + +static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + nv10_render_points_elts, + nv10_render_lines_elts, + nv10_render_line_loop_elts, + nv10_render_line_strip_elts, + nv10_render_triangles_elts, + nv10_render_tri_strip_elts, + nv10_render_tri_fan_elts, + nv10_render_quads_elts, + nv10_render_quad_strip_elts, + nv10_render_poly_elts, + nv10_render_noop_elts, +}; + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + +static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ + +} + +static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON ); + VB->Elts = tmp; +} + +static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(2)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_LINES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(3)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(4)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + + + +static void nv10ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; + tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; + tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; + tnl->Driver.Render.Points = nv10_render_points; + tnl->Driver.Render.Line = nv10_render_line; + tnl->Driver.Render.Triangle = nv10_render_triangle; + tnl->Driver.Render.Quad = nv10_render_quad; +} + + + +static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) +{ + GLcontext* ctx=nmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); + struct vertex_buffer *VB = &tnl->vb; + int attr_size[16]; + int default_attr_size[8]={3,3,3,4,3,1,4,4}; + int i; + int slots=0; + int total_size=0; + /* t_vertex_generic dereferences a NULL pointer if we + * pass NULL as the vp transform... + */ + const GLfloat ident_vp[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + nmesa->vertex_attr_count = 0; + RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); + + /* + * Determine attribute sizes + */ + for(i=0;i<8;i++) + { + if (RENDERINPUTS_TEST(index, i)) + attr_size[i]=default_attr_size[i]; + else + attr_size[i]=0; + } + for(i=8;i<16;i++) + { + if (RENDERINPUTS_TEST(index, i)) + attr_size[i]=VB->TexCoordPtr[i-8]->size; + else + attr_size[i]=0; + } + + /* + * Tell t_vertex about the vertex format + */ + for(i=0;i<16;i++) + { + if (RENDERINPUTS_TEST(index, i)) + { + slots=i+1; + if (i==_TNL_ATTRIB_POS) + { + /* special-case POS */ + EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT); + } + else + { + switch(attr_size[i]) + { + case 1: + EMIT_ATTR(i,EMIT_1F); + break; + case 2: + EMIT_ATTR(i,EMIT_2F); + break; + case 3: + EMIT_ATTR(i,EMIT_3F); + break; + case 4: + EMIT_ATTR(i,EMIT_4F); + break; + } + } + if (i==_TNL_ATTRIB_COLOR0) + nmesa->color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; + } + } + + nmesa->vertex_size=_tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + ident_vp, 0 ); + assert(nmesa->vertex_size==total_size*4); + + /* + * Tell the hardware about the vertex format + */ + if (nmesa->screen->card->type==NV_10) { + int size; + +#define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 + +#define NV10_SET_VERTEX_ATTRIB(i,j) \ + do { \ + size = attr_size[j] << 4; \ + size |= (attr_size[j]*4) << 8; \ + size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \ + OUT_RING_CACHE(size); \ + } while (0) + + NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); + NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); + NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); + NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); + NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); + NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); + NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); + NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1); + OUT_RING_CACHE(0); + } else if (nmesa->screen->card->type==NV_20) { + for(i=0;i<16;i++) + { + int size=attr_size[i]; + BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); + OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); + } + } else { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1); + OUT_RING(0); + BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); + for(i=0;i<slots;i++) + { + int size=attr_size[i]; + OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); + } + // FIXME this is probably not needed + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1); + OUT_RING(0); + } +} + + +static void nv10ChooseVertexState( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); + + RENDERINPUTS_COPY(index, tnl->render_inputs_bitset); + if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset)) + { + RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index); + nv10OutputVertexFormat(nmesa); + } + + if (nmesa->screen->card->type == NV_30) { + nouveauShader *fp; + + if (ctx->FragmentProgram.Enabled) { + fp = (nouveauShader *) ctx->FragmentProgram.Current; + nvsUpdateShader(ctx, fp); + } else + nvsUpdateShader(ctx, nmesa->passthrough_fp); + } + + if (nmesa->screen->card->type >= NV_40) { + /* Ensure passthrough shader is being used, and mvp matrix + * is up to date + */ + nvsUpdateShader(ctx, nmesa->passthrough_vp); + + /* Update texenv shader / user fragprog */ + nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv10RenderStart(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + if (nmesa->new_render_state) { + nv10ChooseVertexState(ctx); + nv10ChooseRenderState(ctx); + nmesa->new_render_state = 0; + } +} + +static void nv10RenderFinish(GLcontext *ctx) +{ +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv10RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint hwprim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + assert (!nmesa->new_state); + + if (hwprim != nmesa->current_primitive) + { + nmesa->current_primitive=hwprim; + + } +} + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINE_STRIP+1, + GL_LINE_LOOP+1, + GL_TRIANGLES+1, + GL_TRIANGLE_STRIP+1, + GL_TRIANGLE_FAN+1, + GL_QUADS+1, + GL_QUAD_STRIP+1, + GL_POLYGON+1 +}; + +/* Callback for mesa: + */ +static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv10RasterPrimitive( ctx, prim, hw_prim[prim] ); +} + +static void nv10ResetLineStipple( GLcontext *ctx ) +{ + /* FIXME do something here */ + WARN_ONCE("Unimplemented nv10ResetLineStipple\n"); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void nv10TriInitFunctions(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = nouveauRunPipeline; + tnl->Driver.Render.Start = nv10RenderStart; + tnl->Driver.Render.Finish = nv10RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + 64 * sizeof(GLfloat) ); + + nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h new file mode 100644 index 00000000000..7c854addd2d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h @@ -0,0 +1,40 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + + +#ifndef __NV10_SWTCL_H__ +#define __NV10_SWTCL_H__ + +#include "mtypes.h" + +extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv10FinishPrimitive(struct nouveau_context *nmesa); +extern void nv10TriInitFunctions(GLcontext *ctx); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV10_SWTCL_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nv20_shader.h b/src/mesa/drivers/dri/nouveau/nv20_shader.h new file mode 100644 index 00000000000..7d2e29db668 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_shader.h @@ -0,0 +1,121 @@ +/* NV20_TCL_PRIMITIVE_3D_0x0B00 */ +#define NV20_VP_INST_0B00 0x00000000 /* always 0? */ +#define NV20_VP_INST0_KNOWN 0 + +/* NV20_TCL_PRIMITIVE_3D_0x0B04 */ +#define NV20_VP_INST_SCA_OPCODE_SHIFT 25 +#define NV20_VP_INST_SCA_OPCODE_MASK (0x0F << 25) +#define NV20_VP_INST_OPCODE_RCP 0x2 +#define NV20_VP_INST_OPCODE_RCC 0x3 +#define NV20_VP_INST_OPCODE_RSQ 0x4 +#define NV20_VP_INST_OPCODE_EXP 0x5 +#define NV20_VP_INST_OPCODE_LOG 0x6 +#define NV20_VP_INST_OPCODE_LIT 0x7 +#define NV20_VP_INST_VEC_OPCODE_SHIFT 21 +#define NV20_VP_INST_VEC_OPCODE_MASK (0x0F << 21) +#define NV20_VP_INST_OPCODE_NOP 0x0 /* guess */ +#define NV20_VP_INST_OPCODE_MOV 0x1 +#define NV20_VP_INST_OPCODE_MUL 0x2 +#define NV20_VP_INST_OPCODE_ADD 0x3 +#define NV20_VP_INST_OPCODE_MAD 0x4 +#define NV20_VP_INST_OPCODE_DP3 0x5 +#define NV20_VP_INST_OPCODE_DPH 0x6 +#define NV20_VP_INST_OPCODE_DP4 0x7 +#define NV20_VP_INST_OPCODE_DST 0x8 +#define NV20_VP_INST_OPCODE_MIN 0x9 +#define NV20_VP_INST_OPCODE_MAX 0xA +#define NV20_VP_INST_OPCODE_SLT 0xB +#define NV20_VP_INST_OPCODE_SGE 0xC +#define NV20_VP_INST_OPCODE_ARL 0xD +#define NV20_VP_INST_CONST_SRC_SHIFT 13 +#define NV20_VP_INST_CONST_SRC_MASK (0xFF << 13) +#define NV20_VP_INST_INPUT_SRC_SHIFT 9 +#define NV20_VP_INST_INPUT_SRC_MASK (0xF << 9) /* guess */ +#define NV20_VP_INST_INPUT_SRC_POS 0 +#define NV20_VP_INST_INPUT_SRC_COL0 3 +#define NV20_VP_INST_INPUT_SRC_COL1 4 +#define NV20_VP_INST_INPUT_SRC_TC(n) (9+n) +#define NV20_VP_INST_SRC0H_SHIFT 0 +#define NV20_VP_INST_SRC0H_MASK (0x1FF << 0) +#define NV20_VP_INST1_KNOWN ( \ + NV20_VP_INST_OPCODE_MASK | \ + NV20_VP_INST_CONST_SRC_MASK | \ + NV20_VP_INST_INPUT_SRC_MASK | \ + NV20_VP_INST_SRC0H_MASK \ + ) + +/* NV20_TCL_PRIMITIVE_3D_0x0B08 */ +#define NV20_VP_INST_SRC0L_SHIFT 26 +#define NV20_VP_INST_SRC0L_MASK (0x3F <<26) +#define NV20_VP_INST_SRC1_SHIFT 11 +#define NV20_VP_INST_SRC1_MASK (0x7FFF<<11) +#define NV20_VP_INST_SRC2H_SHIFT 0 +#define NV20_VP_INST_SRC2H_MASK (0x7FF << 0) + +/* NV20_TCL_PRIMITIVE_3D_0x0B0C */ +#define NV20_VP_INST_SRC2L_SHIFT 28 +#define NV20_VP_INST_SRC2L_MASK (0x0F <<28) +#define NV20_VP_INST_VTEMP_WRITEMASK_SHIFT 24 +#define NV20_VP_INST_VTEMP_WRITEMASK_MASK (0x0F <<24) +# define NV20_VP_INST_TEMP_WRITEMASK_X (1<<27) +# define NV20_VP_INST_TEMP_WRITEMASK_Y (1<<26) +# define NV20_VP_INST_TEMP_WRITEMASK_Z (1<<25) +# define NV20_VP_INST_TEMP_WRITEMASK_W (1<<24) +#define NV20_VP_INST_DEST_TEMP_ID_SHIFT 20 +#define NV20_VP_INST_DEST_TEMP_ID_MASK (0x0F <<20) +#define NV20_VP_INST_STEMP_WRITEMASK_SHIFT 16 +#define NV20_VP_INST_STEMP_WRITEMASK_MASK (0x0F <<16) +# define NV20_VP_INST_STEMP_WRITEMASK_X (1<<19) +# define NV20_VP_INST_STEMP_WRITEMASK_Y (1<<18) +# define NV20_VP_INST_STEMP_WRITEMASK_Z (1<<17) +# define NV20_VP_INST_STEMP_WRITEMASK_W (1<<16) +#define NV20_VP_INST_DEST_WRITEMASK_SHIFT 12 +#define NV20_VP_INST_DEST_WRITEMASK_MASK (0x0F <<12) +# define NV20_VP_INST_DEST_WRITEMASK_X (1<<15) +# define NV20_VP_INST_DEST_WRITEMASK_Y (1<<14) +# define NV20_VP_INST_DEST_WRITEMASK_Z (1<<13) +# define NV20_VP_INST_DEST_WRITEMASK_W (1<<12) +#define NV20_VP_INST_DEST_SHIFT 3 +#define NV20_VP_INST_DEST_MASK (0xF << 3) /* guess */ +#define NV20_VP_INST_DEST_POS 0 +#define NV20_VP_INST_DEST_COL0 3 +#define NV20_VP_INST_DEST_COL1 4 +#define NV20_VP_INST_DEST_TC(n) (9+n) +#define NV20_VP_INST_INDEX_CONST (1<<1) +#define NV20_VP_INST3_KNOWN ( \ + NV20_VP_INST_SRC2L_MASK | \ + NV20_VP_INST_TEMP_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_TEMP_ID_MASK | \ + NV20_VP_INST_STEMP_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_MASK | \ + NV20_VP_INST_INDEX_CONST \ + ) + +/* Useful to split the source selection regs into their pieces */ +#define NV20_VP_SRC0_HIGH_SHIFT 6 +#define NV20_VP_SRC0_HIGH_MASK 0x00007FC0 +#define NV20_VP_SRC0_LOW_MASK 0x0000003F +#define NV20_VP_SRC2_HIGH_SHIFT 4 +#define NV20_VP_SRC2_HIGH_MASK 0x00007FF0 +#define NV20_VP_SRC2_LOW_MASK 0x0000000F + +#define NV20_VP_SRC_REG_NEGATE (1<<14) +#define NV20_VP_SRC_REG_SWZ_X_SHIFT 12 +#define NV20_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) +#define NV20_VP_SRC_REG_SWZ_Y_SHIFT 10 +#define NV20_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) +#define NV20_VP_SRC_REG_SWZ_Z_SHIFT 8 +#define NV20_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) +#define NV20_VP_SRC_REG_SWZ_W_SHIFT 6 +#define NV20_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) +#define NV20_VP_SRC_REG_SWZ_ALL_SHIFT 6 +#define NV20_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) +#define NV20_VP_SRC_REG_TEMP_ID_SHIFT 2 +#define NV20_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) +#define NV20_VP_SRC_REG_TYPE_SHIFT 0 +#define NV20_VP_SRC_REG_TYPE_MASK (0x03 << 0) +#define NV20_VP_SRC_REG_TYPE_TEMP 1 +#define NV20_VP_SRC_REG_TYPE_INPUT 2 +#define NV20_VP_SRC_REG_TYPE_CONST 3 /* guess */ + diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c new file mode 100644 index 00000000000..030713c0dbb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -0,0 +1,811 @@ +/************************************************************************** + +Copyright 2006 Nouveau +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); +} + +static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE((modeA<<16) | modeRGB); +} + + +static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); + OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); +} + +static void nv20Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + +static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); +} + +static void nv20ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv20ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); +} + +static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); +} + +static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv20CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv20FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv20DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv20DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DITHER: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_FOG: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (nmesa->lighting_enabled) + { + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); + } + break; + } + case GL_LIGHTING: + nmesa->lighting_enabled=state; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING_CACHE(nmesa->enabled_lights); + else + OUT_RING_CACHE(0x0); + break; + case GL_LINE_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: + case GL_SCISSOR_TEST: + /* No enable bit, nv20Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(pname) + { + case GL_FOG_MODE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING_CACHE (params); + break; + /* TODO: unsure about the rest.*/ + default: + break; + } + +} + +static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +enum { + SPOTLIGHT_NO_UPDATE, + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + +static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + int spotlight_update = SPOTLIGHT_NO_UPDATE; + + /* not sure where the fourth param value goes...*/ + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPOT_DIRECTION: + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; + break; + case GL_SPOT_EXPONENT: + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; + break; + case GL_SPOT_CUTOFF: + spotlight_update = SPOTLIGHT_UPDATE_ALL; + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + default: + break; + } + + switch(spotlight_update) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } +} + +/** Set the lighting model parameters */ +static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ +/* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 16) | factor);*/ +} + +static void nv20LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHEf(width); +} + +static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv20PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); +} + +/** Select a polygon rasterization mode */ +static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + +/** Set the polygon stippling pattern */ +static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 4095; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2); + OUT_RING_CACHE(((x+w-1) << 16) | x); + OUT_RING_CACHE(((y+h-1) << 16) | y); +} + +/** Select flat or smooth shading */ +static void nv20ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); +} + +/* Update anything that depends on the window position/size */ +static void nv20WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING_CACHE((4095 << 16) | 0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING_CACHE((4095 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + + /* TODO: recalc viewport scale coefs */ +} + +/* Initialise any card-specific non-GL related state */ +static GLboolean nv20InitCard(nouveauContextPtr nmesa) +{ + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + OUT_RING(NvDmaFB); /* 184 dma_object1 */ + OUT_RING(NvDmaFB); /* 188 dma_object2 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2); + OUT_RING(NvDmaFB); /* 194 dma_object3 */ + OUT_RING(NvDmaFB); /* 198 dma_object4 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); /* 1a8 dma_object8 */ + + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RINGf(0.0); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1); + OUT_RING(0x0db6); + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(1); + BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1); + OUT_RING(4); + + BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + OUT_RINGf(0.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(3); + + /* FIXME: More dma objects to setup ? */ + + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + GLuint pitch, format, depth_pitch; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; + format = 0x128; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + format = 0x123; /* R5G6B5 color buffer */ + } + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2); + /* TODO: use a different buffer */ + OUT_RING(depth->pitch); + OUT_RING(depth->offset); + } + + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + return GL_TRUE; +} + +void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv20AlphaFunc; + func->BlendColor = nv20BlendColor; + func->BlendEquationSeparate = nv20BlendEquationSeparate; + func->BlendFuncSeparate = nv20BlendFuncSeparate; + func->Clear = nv20Clear; + func->ClearColor = nv20ClearColor; + func->ClearDepth = nv20ClearDepth; + func->ClearStencil = nv20ClearStencil; + func->ClipPlane = nv20ClipPlane; + func->ColorMask = nv20ColorMask; + func->ColorMaterial = nv20ColorMaterial; + func->CullFace = nv20CullFace; + func->FrontFace = nv20FrontFace; + func->DepthFunc = nv20DepthFunc; + func->DepthMask = nv20DepthMask; + func->DepthRange = nv20DepthRange; + func->Enable = nv20Enable; + func->Fogfv = nv20Fogfv; + func->Hint = nv20Hint; + func->Lightfv = nv20Lightfv; +/* func->LightModelfv = nv20LightModelfv; */ + func->LineStipple = nv20LineStipple; + func->LineWidth = nv20LineWidth; + func->LogicOpcode = nv20LogicOpcode; + func->PointParameterfv = nv20PointParameterfv; + func->PointSize = nv20PointSize; + func->PolygonMode = nv20PolygonMode; + func->PolygonOffset = nv20PolygonOffset; + func->PolygonStipple = nv20PolygonStipple; +/* func->ReadBuffer = nv20ReadBuffer;*/ +/* func->RenderMode = nv20RenderMode;*/ + func->Scissor = nv20Scissor; + func->ShadeModel = nv20ShadeModel; + func->StencilFuncSeparate = nv20StencilFuncSeparate; + func->StencilMaskSeparate = nv20StencilMaskSeparate; + func->StencilOpSeparate = nv20StencilOpSeparate; +/* func->TexGen = nv20TexGen;*/ +/* func->TexParameter = nv20TexParameter;*/ + func->TextureMatrix = nv20TextureMatrix; + + nmesa->hw_func.InitCard = nv20InitCard; + nmesa->hw_func.BindBuffers = nv20BindBuffers; + nmesa->hw_func.WindowMoved = nv20WindowMoved; +} + diff --git a/src/mesa/drivers/dri/nouveau/nv20_vertprog.c b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c new file mode 100644 index 00000000000..60cfcd70561 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c @@ -0,0 +1,447 @@ +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "nouveau_shader.h" +#include "nv20_shader.h" + +unsigned int NVVP_TX_VOP_COUNT = 16; +unsigned int NVVP_TX_NVS_OP_COUNT = 16; +struct _op_xlat NVVP_TX_VOP[32]; +struct _op_xlat NVVP_TX_SOP[32]; + +nvsSwzComp NV20VP_TX_SWIZZLE[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + +/***************************************************************************** + * Support routines + */ +static void +NV20VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + /* XXX: missing a way to say what insn we're uploading from, and possible + * the program start position (if NV20 has one) */ + for (i=0; i<nvs->program_size; i+=4) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4); + OUT_RING(nvs->program[i + 0]); + OUT_RING(nvs->program[i + 1]); + OUT_RING(nvs->program[i + 2]); + OUT_RING(nvs->program[i + 3]); + } +} + +static void +NV20VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* Worth checking if the value *actually* changed? Mesa doesn't tell us this + * as far as I know.. + */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 1); + OUT_RING (id); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4); + OUT_RINGf(nvs->params[id].source_val[0]); + OUT_RINGf(nvs->params[id].source_val[1]); + OUT_RINGf(nvs->params[id].source_val[2]); + OUT_RINGf(nvs->params[id].source_val[3]); +} + +/***************************************************************************** + * Assembly routines + */ + +/***************************************************************************** + * Disassembly routines + */ +void +NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz) +{ + swz[NVS_SWZ_X] = NV20VP_TX_SWIZZLE[(hwswz & 0xC0) >> 6]; + swz[NVS_SWZ_Y] = NV20VP_TX_SWIZZLE[(hwswz & 0x30) >> 4]; + swz[NVS_SWZ_Z] = NV20VP_TX_SWIZZLE[(hwswz & 0x0C) >> 2]; + swz[NVS_SWZ_W] = NV20VP_TX_SWIZZLE[(hwswz & 0x03) >> 0]; +} + +static int +NV20VPHasMergedInst(nvsFunc * shader) +{ + if (shader->GetOpcodeHW(shader, 0) != NV20_VP_INST_OPCODE_NOP && + shader->GetOpcodeHW(shader, 1) != NV20_VP_INST_OPCODE_NOP) + printf + ("\n\n*****both opcode fields have values - PLEASE REPORT*****\n"); + return 0; +} + +static int +NV20VPIsLastInst(nvsFunc * shader) +{ + return ((shader->inst[3] & (1 << 0)) ? 1 : 0); +} + +static int +NV20VPGetOffsetNext(nvsFunc * shader) +{ + return 4; +} + +static struct _op_xlat * +NV20VPGetOPTXRec(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + int op; + + if (shader->GetOpcodeSlot(shader, merged)) { + opr = NVVP_TX_SOP; + op = shader->GetOpcodeHW(shader, 1); + if (op >= NVVP_TX_NVS_OP_COUNT) + return NULL; + } + else { + opr = NVVP_TX_VOP; + op = shader->GetOpcodeHW(shader, 0); + if (op >= NVVP_TX_VOP_COUNT) + return NULL; + } + + if (opr[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &opr[op]; +} + +static struct _op_xlat * +NV20VPGetOPTXFromSOP(nvsOpcode sop, int *id) +{ + int i; + + for (i=0;i<NVVP_TX_VOP_COUNT;i++) { + if (NVVP_TX_VOP[i].SOP == sop) { + if (id) *id = 0; + return &NVVP_TX_VOP[i]; + } + } + + for (i=0;i<NVVP_TX_NVS_OP_COUNT;i++) { + if (NVVP_TX_SOP[i].SOP == sop) { + if (id) *id = 1; + return &NVVP_TX_SOP[i]; + } + } + + return NULL; +} + +static int +NV20VPGetOpcodeSlot(nvsFunc * shader, int merged) +{ + if (shader->HasMergedInst(shader)) + return merged; + if (shader->GetOpcodeHW(shader, 0) == NV20_VP_INST_OPCODE_NOP) + return 1; + return 0; +} + +static nvsOpcode +NV20VPGetOpcode(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return NVS_OP_UNKNOWN; + + return opr->SOP; +} + +static nvsOpcode +NV20VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + if (slot) + return (shader->inst[1] & NV20_VP_INST_SCA_OPCODE_MASK) + >> NV20_VP_INST_SCA_OPCODE_SHIFT; + return (shader->inst[1] & NV20_VP_INST_VEC_OPCODE_MASK) + >> NV20_VP_INST_VEC_OPCODE_SHIFT; +} + +static nvsRegFile +NV20VPGetDestFile(nvsFunc * shader, int merged) +{ + switch (shader->GetOpcode(shader, merged)) { + case NVS_OP_ARL: + return NVS_FILE_ADDRESS; + default: + /*FIXME: This probably isn't correct.. */ + if ((shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) == 0) + return NVS_FILE_TEMP; + return NVS_FILE_RESULT; + } +} + +static unsigned int +NV20VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV20_VP_INST_DEST_MASK) + >> NV20_VP_INST_DEST_SHIFT); + switch (id) { + case NV20_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV20_VP_INST_DEST_COL0 : return NVS_FR_COL0; + case NV20_VP_INST_DEST_COL1 : return NVS_FR_COL1; + case NV20_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV20_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV20_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV20_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + default: + return -1; + } + case NVS_FILE_ADDRESS: + return 0; + case NVS_FILE_TEMP: + id = ((shader->inst[3] & NV20_VP_INST_DEST_TEMP_ID_MASK) + >> NV20_VP_INST_DEST_TEMP_ID_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV20VPGetDestMask(nvsFunc * shader, int merged) +{ + int hwmask, mask = 0; + + /* Special handling for ARL - hardware only supports a + * 1-component address reg + */ + if (shader->GetOpcode(shader, merged) == NVS_OP_ARL) + return SMASK_X; + + if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT) + hwmask = (shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) + >> NV20_VP_INST_DEST_WRITEMASK_SHIFT; + else if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV20_VP_INST_STEMP_WRITEMASK_MASK) + >> NV20_VP_INST_STEMP_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV20_VP_INST_VTEMP_WRITEMASK_MASK) + >> NV20_VP_INST_VTEMP_WRITEMASK_SHIFT; + + if (hwmask & (1 << 3)) mask |= SMASK_X; + if (hwmask & (1 << 2)) mask |= SMASK_Y; + if (hwmask & (1 << 1)) mask |= SMASK_Z; + if (hwmask & (1 << 0)) mask |= SMASK_W; + + return mask; +} + +static unsigned int +NV20VPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + unsigned int src; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return -1; + + switch (opr->srcpos[pos]) { + case 0: + src = ((shader->inst[1] & NV20_VP_INST_SRC0H_MASK) + >> NV20_VP_INST_SRC0H_SHIFT) + << NV20_VP_SRC0_HIGH_SHIFT; + src |= ((shader->inst[2] & NV20_VP_INST_SRC0L_MASK) + >> NV20_VP_INST_SRC0L_SHIFT); + break; + case 1: + src = ((shader->inst[2] & NV20_VP_INST_SRC1_MASK) + >> NV20_VP_INST_SRC1_SHIFT); + break; + case 2: + src = ((shader->inst[2] & NV20_VP_INST_SRC2H_MASK) + >> NV20_VP_INST_SRC2H_SHIFT) + << NV20_VP_SRC2_HIGH_SHIFT; + src |= ((shader->inst[3] & NV20_VP_INST_SRC2L_MASK) + >> NV20_VP_INST_SRC2L_SHIFT); + break; + default: + src = -1; + } + + return src; +} + +static nvsRegFile +NV20VPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: + return NVS_FILE_ADDRESS; + default: + src = NV20VPGetSourceHW(shader, merged, pos); + file = (src & NV20_VP_SRC_REG_TYPE_MASK) >> NV20_VP_SRC_REG_TYPE_SHIFT; + + switch (file) { + case NV20_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV20_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV20_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV20VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_TEMP: + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV20_VP_SRC_REG_TEMP_ID_MASK) >> + NV20_VP_SRC_REG_TEMP_ID_SHIFT); + case NVS_FILE_CONST: + return ((shader->inst[1] & NV20_VP_INST_CONST_SRC_MASK) + >> NV20_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_ATTRIB: + src = ((shader->inst[1] & NV20_VP_INST_INPUT_SRC_MASK) + >> NV20_VP_INST_INPUT_SRC_SHIFT); + switch (src) { + case NV20_VP_INST_INPUT_SRC_POS : return NVS_FR_POSITION; + case NV20_VP_INST_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV20_VP_INST_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV20_VP_INST_INPUT_SRC_TC(0): return NVS_FR_TEXCOORD0; + case NV20_VP_INST_INPUT_SRC_TC(1): return NVS_FR_TEXCOORD1; + case NV20_VP_INST_INPUT_SRC_TC(2): return NVS_FR_TEXCOORD2; + case NV20_VP_INST_INPUT_SRC_TC(3): return NVS_FR_TEXCOORD3; + default: + return NVS_FR_UNKNOWN; + } + default: + return -1; + } +} + +static int +NV20VPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + return ((src & NV20_VP_SRC_REG_NEGATE) ? 1 : 0); +} + +static int +NV20VPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + /* NV20 can't do ABS on sources? Appears to be emulated with + * MAX reg, reg, -reg + */ + return 0; +} + +static void +NV20VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = + (src & NV20_VP_SRC_REG_SWZ_ALL_MASK) >> NV20_VP_SRC_REG_SWZ_ALL_SHIFT; + return NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV20VPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + /* I don't think NV20 can index into attribs, at least no GL + * extension is exposed that will allow it. + */ + if (shader->GetSourceFile(shader, merged, pos) != NVS_FILE_CONST) + return 0; + if (shader->inst[3] & NV20_VP_INST_INDEX_CONST) + return 1; + return 0; +} + +static int +NV20VPGetAddressRegID(nvsFunc * shader) +{ + /* Only 1 address reg */ + return 0; +} + +static nvsSwzComp +NV20VPGetAddressRegSwizzle(nvsFunc * shader) +{ + /* Only A0.x available */ + return NVS_SWZ_X; +} + +void +NV20VPInitShaderFuncs(nvsFunc * shader) +{ + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ADD, NVS_OP_ADD, 0, 2, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DPH, NVS_OP_DPH, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DST, NVS_OP_DST, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ARL, NVS_OP_ARL, 0, -1, -1); + + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCP, NVS_OP_RCP, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCC, NVS_OP_RCC, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RSQ, NVS_OP_RSQ, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_EXP, NVS_OP_EXP, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LOG, NVS_OP_LOG, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LIT, NVS_OP_LIT, 2, -1, -1); + + shader->UploadToHW = NV20VPUploadToHW; + shader->UpdateConst = NV20VPUpdateConst; + + shader->GetOPTXRec = NV20VPGetOPTXRec; + shader->GetOPTXFromSOP = NV20VPGetOPTXFromSOP; + + shader->HasMergedInst = NV20VPHasMergedInst; + shader->IsLastInst = NV20VPIsLastInst; + shader->GetOffsetNext = NV20VPGetOffsetNext; + shader->GetOpcodeSlot = NV20VPGetOpcodeSlot; + shader->GetOpcode = NV20VPGetOpcode; + shader->GetOpcodeHW = NV20VPGetOpcodeHW; + shader->GetDestFile = NV20VPGetDestFile; + shader->GetDestID = NV20VPGetDestID; + shader->GetDestMask = NV20VPGetDestMask; + shader->GetSourceHW = NV20VPGetSourceHW; + shader->GetSourceFile = NV20VPGetSourceFile; + shader->GetSourceID = NV20VPGetSourceID; + shader->GetSourceNegate = NV20VPGetSourceNegate; + shader->GetSourceAbs = NV20VPGetSourceAbs; + shader->GetSourceSwizzle = NV20VPGetSourceSwizzle; + shader->GetSourceIndexed = NV20VPGetSourceIndexed; + shader->GetRelAddressRegID = NV20VPGetAddressRegID; + shader->GetRelAddressSwizzle = NV20VPGetAddressRegSwizzle; +} diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c new file mode 100644 index 00000000000..e32452361e8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -0,0 +1,742 @@ +#include <stdint.h> + +#include "glheader.h" +#include "macros.h" + +#include "nouveau_context.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_drm.h" +#include "nouveau_shader.h" +#include "nouveau_object.h" +#include "nouveau_msg.h" +#include "nouveau_bufferobj.h" +#include "nv30_shader.h" + +unsigned int NVFP_TX_AOP_COUNT = 64; +struct _op_xlat NVFP_TX_AOP[64]; + +/******************************************************************************* + * Support routines + */ + +static void +NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nvsCardPriv *priv = &nvs->card_priv; + uint32_t offset; + + if (!nvs->program_buffer) + nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0, + GL_ARRAY_BUFFER_ARB); + + /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */ + nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK, + nvs->program_size * sizeof(uint32_t), + (const GLvoid *)nvs->program, + GL_DYNAMIC_DRAW_ARB, + nvs->program_buffer); + + offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer); + + /* Not using state cache here, updated programs at the same address don't + * seem to take effect unless the ACTIVE_PROGRAM method is called again. + * HW caches the program somewhere? + */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); + OUT_RING (offset | 1); + if (nmesa->screen->card->type == NV_30) { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7)); + BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); + OUT_RING (priv->NV30FP.num_regs << 16); + } else { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); + } +} + +static void +NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + uint32_t *new = nvs->params[id].source_val ? + (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val; + uint32_t *current; + int i; + + for (i=0; i<nvs->params[id].hw_index_cnt; i++) { + current = nvs->program + nvs->params[id].hw_index[i]; + COPY_4V(current, new); + } + nvs->on_hardware = 0; +} + +/******************************************************************************* + * Assembly helpers + */ +static struct _op_xlat * +NV30FPGetOPTXFromSOP(nvsOpcode op, int *id) +{ + int i; + + for (i=0; i<NVFP_TX_AOP_COUNT; i++) { + if (NVFP_TX_AOP[i].SOP == op) { + if (id) *id = 0; + return &NVFP_TX_AOP[i]; + } + } + + return NULL; +} + +static int +NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op) +{ + if (shader->GetOPTXFromSOP(op, NULL)) + return 1; + return 0; +} + +static void +NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) +{ + if (opcode == NV30_FP_OP_OPCODE_KIL) + shader->card_priv->NV30FP.uses_kil = GL_TRUE; + shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; + shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); +} + +static void +NV30FPSetCCUpdate(nvsFunc *shader) +{ + shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE; +} + +static void +NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, + nvsSwzComp *swz) +{ + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + unsigned int hwcond; + + /* cond masking is always enabled */ + if (!on) { + cond = NVS_COND_TR; + reg = 0; + swz = default_swz; + } + + switch (cond) { + case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break; + case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break; + case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break; + case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break; + case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break; + case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break; + case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break; + case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break; + default: + WARN_ONCE("unknown fp condmask=%d\n", cond); + hwcond = NV30_FP_OP_COND_TR; + break; + } + + shader->inst[1] &= ~NV30_FP_OP_COND_MASK; + shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT); + + shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK; + shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT); +} + +static void +NV30FPSetHighReg(nvsFunc *shader, int id) +{ + if (shader->card_priv->NV30FP.num_regs < (id+1)) { + if (id == 0) + id = 1; /* necessary? */ + shader->card_priv->NV30FP.num_regs = (id+1); + } +} + +static void +NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) +{ + unsigned int hwreg; + + if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X; + if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y; + if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z; + if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W; + + if (reg->file == NVS_FILE_RESULT) { + hwreg = 0; /* FIXME: this is only fragment.color */ + /* This is *not* correct, I have no idea what it is either */ + shader->inst[0] |= NV30_FP_OP_UNK0_7; + } else { + shader->inst[0] &= ~NV30_FP_OP_UNK0_7; + hwreg = reg->index; + } + NV30FPSetHighReg(shader, hwreg); + shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; + shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); +} + +static void +NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) +{ + unsigned int hwsrc = 0; + + switch (reg->file) { + case NVS_FILE_TEMP: + hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); + hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); + NV30FPSetHighReg(shader, reg->index); + break; + case NVS_FILE_ATTRIB: + { + unsigned int hwin; + + switch (reg->index) { + case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break; + case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break; + case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break; + case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break; + case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break; + case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break; + case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break; + case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break; + case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break; + case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break; + case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break; + case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break; + default: + WARN_ONCE("unknown fp input %d\n", reg->index); + hwin = NV30_FP_OP_INPUT_SRC_COL0; + break; + } + shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK; + shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT); + hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT); + } + hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT); + break; + case NVS_FILE_CONST: + /* consts are inlined after the inst */ + hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT); + break; + default: + assert(0); + break; + } + + if (reg->negate) + hwsrc |= NV30_FP_REG_NEGATE; + if (reg->abs) + shader->inst[1] |= (1 << (29+pos)); + hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT); + + shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK; + shader->inst[pos+1] |= hwsrc; +} + +static void +NV30FPSetTexImageUnit(nvsFunc *shader, int unit) +{ + shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT; + shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT); +} + +static void +NV30FPSetSaturate(nvsFunc *shader) +{ + shader->inst[0] |= NV30_FP_OP_OUT_SAT; +} + +static void +NV30FPInitInstruction(nvsFunc *shader) +{ + unsigned int hwsrc; + + shader->inst[0] = 0; + + hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT); + shader->inst[1] = hwsrc; + shader->inst[2] = hwsrc; + shader->inst[3] = hwsrc; +} + +static void +NV30FPSetLastInst(nvsFunc *shader) +{ + shader->inst[0] |= 1; +} + +/******************************************************************************* + * Disassembly helpers + */ +static struct _op_xlat * +NV30FPGetOPTXRec(nvsFunc * shader, int merged) +{ + int op; + + op = shader->GetOpcodeHW(shader, 0); + if (op > NVFP_TX_AOP_COUNT) + return NULL; + if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &NVFP_TX_AOP[op]; +} + +static int +NV30FPHasMergedInst(nvsFunc * shader) +{ + return 0; +} + +static int +NV30FPIsLastInst(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0); +} + +static int +NV30FPGetOffsetNext(nvsFunc * shader) +{ + int i; + + for (i = 0; i < 3; i++) + if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST) + return 8; + return 4; +} + +static nvsOpcode +NV30FPGetOpcode(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return NVS_OP_UNKNOWN; + + return opr->SOP; +} + +static unsigned int +NV30FPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT; + + return op; +} + +static nvsRegFile +NV30FPGetDestFile(nvsFunc * shader, int merged) +{ + /* Result regs overlap temporary regs */ + return NVS_FILE_TEMP; +} + +static unsigned int +NV30FPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_TEMP: + id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK) + >> NV30_FP_OP_OUT_REG_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV30FPGetDestMask(nvsFunc * shader, int merged) +{ + unsigned int mask = 0; + + if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X; + if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y; + if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z; + if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W; + + return mask; +} + +static unsigned int +NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + return shader->inst[opr->srcpos[pos] + 1]; +} + +static nvsRegFile +NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return NVS_FILE_UNKNOWN; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: return NVS_FILE_ADDRESS; + default: + src = shader->GetSourceHW(shader, merged, pos); + file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT; + + switch (file) { + case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV30FPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK) + >> NV30_FP_OP_INPUT_SRC_SHIFT) { + case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION; + case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD; + case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0; + case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1; + case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2; + case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3; + case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4; + case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5; + case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6; + case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7; + default: + return -1; + } + break; + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT); + } + case NVS_FILE_CONST: /* inlined into fragprog */ + default: + return -1; + } +} + +static int +NV30FPGetTexImageUnit(nvsFunc *shader) +{ + return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK) + >> NV30_FP_OP_TEX_UNIT_SHIFT); +} + +static int +NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + if (src == -1) + return -1; + return ((src & NV30_FP_REG_NEGATE) ? 1 : 0); +} + +static int +NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + static unsigned int abspos[3] = { + NV30_FP_OP_OUT_ABS, + (1 << 30), /* guess */ + (1 << 31) /* guess */ + }; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0); +} + +nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + +static void +NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz) +{ + swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6]; + swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4]; + swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2]; + swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0]; +} + +static void +NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT; + NV30FPTXSwizzle(swzbits, swz); +} + +static int +NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0); + default: + return 0; + } +} + +static void +NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val) +{ + val[0] = *(float *) &(shader->inst[4]); + val[1] = *(float *) &(shader->inst[5]); + val[2] = *(float *) &(shader->inst[6]); + val[3] = *(float *) &(shader->inst[7]); +} + +static int +NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos) +{ +/*FIXME: is this per-source, only for a specific source, or all sources??*/ + return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK) + >> NV30_FP_OP_SRC_SCALE_SHIFT)); +} + +static int +NV30FPGetAddressRegID(nvsFunc * shader) +{ + return 0; +} + +static nvsSwzComp +NV30FPGetAddressRegSwizzle(nvsFunc * shader) +{ + return NVS_SWZ_X; +} + +static int +NV30FPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV30FPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0); +} + +static int +NV30FPGetConditionTest(nvsFunc * shader) +{ + /*FIXME: always? */ + return 1; +} + +static nvsCond +NV30FPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK) + >> NV30_FP_OP_COND_SHIFT); + + switch (cond) { + case NV30_FP_OP_COND_FL: return NVS_COND_FL; + case NV30_FP_OP_COND_LT: return NVS_COND_LT; + case NV30_FP_OP_COND_EQ: return NVS_COND_EQ; + case NV30_FP_OP_COND_LE: return NVS_COND_LE; + case NV30_FP_OP_COND_GT: return NVS_COND_GT; + case NV30_FP_OP_COND_NE: return NVS_COND_NE; + case NV30_FP_OP_COND_GE: return NVS_COND_GE; + case NV30_FP_OP_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK) + >> NV30_FP_OP_COND_SWZ_ALL_SHIFT; + NV30FPTXSwizzle(swzbits, swz); +} + +static int +NV30FPGetCondRegID(nvsFunc * shader) +{ + return 0; +} + +static nvsPrecision +NV30FPGetPrecision(nvsFunc * shader) +{ + int p; + + p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK) + >> NV30_FP_OP_PRECISION_SHIFT; + + switch (p) { + case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32; + case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16; + case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12; + default: + return NVS_PREC_UNKNOWN; + } +} + +static int +NV30FPGetSaturate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0); +} + +/******************************************************************************* + * Init + */ +void +NV30FPInitShaderFuncs(nvsFunc * shader) +{ + /* These are probably bogus, I made them up... */ + shader->MaxInst = 1024; + shader->MaxAttrib = 16; + shader->MaxTemp = 32; + shader->MaxAddress = 1; + shader->MaxConst = 256; + shader->caps = SCAP_SRC_ABS; + + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1); + /*FIXME: Haven't confirmed the source positions for the below opcodes */ + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1); + + shader->GetOPTXRec = NV30FPGetOPTXRec; + shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP; + + shader->UploadToHW = NV30FPUploadToHW; + shader->UpdateConst = NV30FPUpdateConst; + + shader->InitInstruction = NV30FPInitInstruction; + shader->SupportsOpcode = NV30FPSupportsOpcode; + shader->SetOpcode = NV30FPSetOpcode; + shader->SetCCUpdate = NV30FPSetCCUpdate; + shader->SetCondition = NV30FPSetCondition; + shader->SetResult = NV30FPSetResult; + shader->SetSource = NV30FPSetSource; + shader->SetTexImageUnit = NV30FPSetTexImageUnit; + shader->SetSaturate = NV30FPSetSaturate; + shader->SetLastInst = NV30FPSetLastInst; + + shader->HasMergedInst = NV30FPHasMergedInst; + shader->IsLastInst = NV30FPIsLastInst; + shader->GetOffsetNext = NV30FPGetOffsetNext; + shader->GetOpcode = NV30FPGetOpcode; + shader->GetOpcodeHW = NV30FPGetOpcodeHW; + shader->GetDestFile = NV30FPGetDestFile; + shader->GetDestID = NV30FPGetDestID; + shader->GetDestMask = NV30FPGetDestMask; + shader->GetSourceHW = NV30FPGetSourceHW; + shader->GetSourceFile = NV30FPGetSourceFile; + shader->GetSourceID = NV30FPGetSourceID; + shader->GetTexImageUnit = NV30FPGetTexImageUnit; + shader->GetSourceNegate = NV30FPGetSourceNegate; + shader->GetSourceAbs = NV30FPGetSourceAbs; + shader->GetSourceSwizzle = NV30FPGetSourceSwizzle; + shader->GetSourceIndexed = NV30FPGetSourceIndexed; + shader->GetSourceConstVal = NV30FPGetSourceConstVal; + shader->GetSourceScale = NV30FPGetSourceScale; + shader->GetRelAddressRegID = NV30FPGetAddressRegID; + shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle; + shader->GetPrecision = NV30FPGetPrecision; + shader->GetSaturate = NV30FPGetSaturate; + shader->SupportsConditional = NV30FPSupportsConditional; + shader->GetConditionUpdate = NV30FPGetConditionUpdate; + shader->GetConditionTest = NV30FPGetConditionTest; + shader->GetCondition = NV30FPGetCondition; + shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle; + shader->GetCondRegID = NV30FPGetCondRegID; +} diff --git a/src/mesa/drivers/dri/nouveau/nv30_shader.h b/src/mesa/drivers/dri/nouveau/nv30_shader.h new file mode 100644 index 00000000000..7a027dd4273 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_shader.h @@ -0,0 +1,379 @@ +#ifndef __NV30_SHADER_H__ +#define __NV30_SHADER_H__ + +/* Vertex programs instruction set + * + * 128bit opcodes, split into 4 32-bit ones for ease of use. + * + * Non-native instructions + * ABS - MOV + NV40_VP_INST0_DEST_ABS + * POW - EX2 + MUL + LG2 + * SUB - ADD, second source negated + * SWZ - MOV + * XPD - + * + * Register access + * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) + * - Only one CONST can be accessed per-instruction (move extras into TEMPs) + * + * Relative Addressing + * According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB + * there are only two address registers available. The destination in the ARL + * instruction is set to TEMP <n> (The temp isn't actually written). + * + * When using vanilla ARB_v_p, the proprietary driver will squish both the available + * ADDRESS regs into the first hardware reg in the X and Y components. + * + * To use an address reg as an index into consts, the CONST_SRC is set to + * (const_base + offset) and INDEX_CONST is set. + * + * To access the second address reg use ADDR_REG_SELECT_1. A particular component + * of the address regs is selected with ADDR_SWZ. + * + * Only one address register can be accessed per instruction. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and + * selecting the condition which will allow the test to pass with COND_{FL,LT,...}. + * It is possible to swizzle the values in the condition register, which allows for + * testing against an individual component. + * + * Branching + * The BRA/CAL instructions seem to follow a slightly different opcode layout. The + * destination instruction ID (IADDR) overlaps a source field. Instruction ID's seem to + * be numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically + * on each UPLOAD_INST FIFO command. + * + * Conditional branching is achieved by using the condition tests described above. + * There doesn't appear to be dedicated looping instructions, but this can be done + * using a temp reg + conditional branching. + * + * Subroutines may be uploaded before the main program itself, but the first executed + * instruction is determined by the PROGRAM_START_ID FIFO command. + * + */ + +/* DWORD 0 */ +#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */ +#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */ +#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */ +#define NV30_VP_INST_OUT_RESULT (1 << 20) +#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16 +#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16) +#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15) +#define NV30_VP_INST_COND_TEST_ENABLE (1<<14) +#define NV30_VP_INST_COND_SHIFT 11 +#define NV30_VP_INST_COND_MASK (0x07 << 11) +# define NV30_VP_INST_COND_FL 0 /* guess */ +# define NV30_VP_INST_COND_LT 1 +# define NV30_VP_INST_COND_EQ 2 +# define NV30_VP_INST_COND_LE 3 +# define NV30_VP_INST_COND_GT 4 +# define NV30_VP_INST_COND_NE 5 +# define NV30_VP_INST_COND_GE 6 +# define NV30_VP_INST_COND_TR 7 /* guess */ +#define NV30_VP_INST_COND_SWZ_X_SHIFT 9 +#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9) +#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7 +#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7) +#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5 +#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5) +#define NV30_VP_INST_COND_SWZ_W_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3) +#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3) +#define NV30_VP_INST_ADDR_SWZ_SHIFT 1 +#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1) +#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0 +#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0) + +/* DWORD 1 */ +#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28 +#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28) +# define NV30_VP_INST_OP_NOP 0x00 +# define NV30_VP_INST_OP_RCP 0x02 +# define NV30_VP_INST_OP_RCC 0x03 +# define NV30_VP_INST_OP_RSQ 0x04 +# define NV30_VP_INST_OP_EXP 0x05 +# define NV30_VP_INST_OP_LOG 0x06 +# define NV30_VP_INST_OP_LIT 0x07 +# define NV30_VP_INST_OP_BRA 0x09 +# define NV30_VP_INST_OP_CAL 0x0B +# define NV30_VP_INST_OP_RET 0x0C +# define NV30_VP_INST_OP_LG2 0x0D +# define NV30_VP_INST_OP_EX2 0x0E +# define NV30_VP_INST_OP_SIN 0x0F +# define NV30_VP_INST_OP_COS 0x10 +#define NV30_VP_INST_VEC_OPCODE_SHIFT 23 +#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23) +# define NV30_VP_INST_OP_NOPV 0x00 +# define NV30_VP_INST_OP_MOV 0x01 +# define NV30_VP_INST_OP_MUL 0x02 +# define NV30_VP_INST_OP_ADD 0x03 +# define NV30_VP_INST_OP_MAD 0x04 +# define NV30_VP_INST_OP_DP3 0x05 +# define NV30_VP_INST_OP_DP4 0x07 +# define NV30_VP_INST_OP_DPH 0x06 +# define NV30_VP_INST_OP_DST 0x08 +# define NV30_VP_INST_OP_MIN 0x09 +# define NV30_VP_INST_OP_MAX 0x0A +# define NV30_VP_INST_OP_SLT 0x0B +# define NV30_VP_INST_OP_SGE 0x0C +# define NV30_VP_INST_OP_ARL 0x0D +# define NV30_VP_INST_OP_FRC 0x0E +# define NV30_VP_INST_OP_FLR 0x0F +# define NV30_VP_INST_OP_SEQ 0x10 +# define NV30_VP_INST_OP_SFL 0x11 +# define NV30_VP_INST_OP_SGT 0x12 +# define NV30_VP_INST_OP_SLE 0x13 +# define NV30_VP_INST_OP_SNE 0x14 +# define NV30_VP_INST_OP_STR 0x15 +# define NV30_VP_INST_OP_SSG 0x16 +# define NV30_VP_INST_OP_ARR 0x17 +# define NV30_VP_INST_OP_ARA 0x18 +#define NV30_VP_INST_CONST_SRC_SHIFT 14 +#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14) +#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/ +#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/ +# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */ +# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */ +# define NV30_VP_INST_IN_NORMAL 2 +# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */ +# define NV30_VP_INST_IN_COL1 4 +# define NV30_VP_INST_IN_FOGC 5 +# define NV30_VP_INST_IN_TC0 8 +# define NV30_VP_INST_IN_TC(n) (8+n) +#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/ + +/* DWORD 2 */ +#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/ +#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /*NV20*/ +#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/ +#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/ +#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /*NV20*/ +#define NV30_VP_INST_IADDR_SHIFT 2 +#define NV30_VP_INST_IADDR_MASK (0xFF << 2) /* guess */ + +/* DWORD 3 */ +#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/ +#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/ +#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24 +#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24) +#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20 +#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20) +#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16 +#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16) +#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/ +#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/ +#define NV30_VP_INST_DEST_ID_SHIFT 2 +#define NV30_VP_INST_DEST_ID_MASK (0x0F << 2) +# define NV30_VP_INST_DEST_POS 0 +# define NV30_VP_INST_DEST_COL0 3 +# define NV30_VP_INST_DEST_COL1 4 +# define NV30_VP_INST_DEST_TC(n) (8+n) + +/* Source-register definition - matches NV20 exactly */ +#define NV30_VP_SRC_REG_NEGATE (1<<14) +#define NV30_VP_SRC_REG_SWZ_X_SHIFT 12 +#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) +#define NV30_VP_SRC_REG_SWZ_Y_SHIFT 10 +#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) +#define NV30_VP_SRC_REG_SWZ_Z_SHIFT 8 +#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) +#define NV30_VP_SRC_REG_SWZ_W_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) +#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) +#define NV30_VP_SRC_REG_TEMP_ID_SHIFT 2 +#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) +#define NV30_VP_SRC_REG_TYPE_SHIFT 0 +#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0) +#define NV30_VP_SRC_REG_TYPE_TEMP 1 +#define NV30_VP_SRC_REG_TYPE_INPUT 2 +#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */ + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0 + * otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO + * is implemented simply by not writing to the relevant components of the destination. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + */ + +//== Opcode / Destination selection == +#define NV30_FP_OP_PROGRAM_END (1 << 0) +#define NV30_FP_OP_OUT_REG_SHIFT 1 +#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */ +/* Needs to be set when writing outputs to get expected result.. */ +#define NV30_FP_OP_UNK0_7 (1 << 7) +#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV30_FP_OP_OUTMASK_SHIFT 9 +#define NV30_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV30_FP_OP_OUT_X (1<<9) +# define NV30_FP_OP_OUT_Y (1<<10) +# define NV30_FP_OP_OUT_Z (1<<11) +# define NV30_FP_OP_OUT_W (1<<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV30_FP_OP_INPUT_SRC_SHIFT 13 +#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV30_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV30_FP_OP_INPUT_SRC_COL0 0x1 +# define NV30_FP_OP_INPUT_SRC_COL1 0x2 +# define NV30_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV30_FP_OP_INPUT_SRC_TC0 0x4 +# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +#define NV30_FP_OP_TEX_UNIT_SHIFT 17 +#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */ +#define NV30_FP_OP_PRECISION_SHIFT 22 +#define NV30_FP_OP_PRECISION_MASK (3 << 22) +# define NV30_FP_PRECISION_FP32 0 +# define NV30_FP_PRECISION_FP16 1 +# define NV30_FP_PRECISION_FX12 2 +#define NV30_FP_OP_OPCODE_SHIFT 24 +#define NV30_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV30_FP_OP_OPCODE_NOP 0x00 +# define NV30_FP_OP_OPCODE_MOV 0x01 +# define NV30_FP_OP_OPCODE_MUL 0x02 +# define NV30_FP_OP_OPCODE_ADD 0x03 +# define NV30_FP_OP_OPCODE_MAD 0x04 +# define NV30_FP_OP_OPCODE_DP3 0x05 +# define NV30_FP_OP_OPCODE_DP4 0x06 +# define NV30_FP_OP_OPCODE_DST 0x07 +# define NV30_FP_OP_OPCODE_MIN 0x08 +# define NV30_FP_OP_OPCODE_MAX 0x09 +# define NV30_FP_OP_OPCODE_SLT 0x0A +# define NV30_FP_OP_OPCODE_SGE 0x0B +# define NV30_FP_OP_OPCODE_SLE 0x0C +# define NV30_FP_OP_OPCODE_SGT 0x0D +# define NV30_FP_OP_OPCODE_SNE 0x0E +# define NV30_FP_OP_OPCODE_SEQ 0x0F +# define NV30_FP_OP_OPCODE_FRC 0x10 +# define NV30_FP_OP_OPCODE_FLR 0x11 +# define NV30_FP_OP_OPCODE_KIL 0x12 +# define NV30_FP_OP_OPCODE_PK4B 0x13 +# define NV30_FP_OP_OPCODE_UP4B 0x14 +# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */ +# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */ +# define NV30_FP_OP_OPCODE_TEX 0x17 +# define NV30_FP_OP_OPCODE_TXP 0x18 +# define NV30_FP_OP_OPCODE_TXD 0x19 +# define NV30_FP_OP_OPCODE_RCP 0x1A +# define NV30_FP_OP_OPCODE_RSQ 0x1B +# define NV30_FP_OP_OPCODE_EX2 0x1C +# define NV30_FP_OP_OPCODE_LG2 0x1D +# define NV30_FP_OP_OPCODE_LIT 0x1E +# define NV30_FP_OP_OPCODE_LRP 0x1F +# define NV30_FP_OP_OPCODE_COS 0x22 +# define NV30_FP_OP_OPCODE_SIN 0x23 +# define NV30_FP_OP_OPCODE_PK2H 0x24 +# define NV30_FP_OP_OPCODE_UP2H 0x25 +# define NV30_FP_OP_OPCODE_POW 0x26 +# define NV30_FP_OP_OPCODE_PK4UB 0x27 +# define NV30_FP_OP_OPCODE_UP4UB 0x28 +# define NV30_FP_OP_OPCODE_PK2US 0x29 +# define NV30_FP_OP_OPCODE_UP2US 0x2A +# define NV30_FP_OP_OPCODE_DP2A 0x2E +# define NV30_FP_OP_OPCODE_TXB 0x31 +# define NV30_FP_OP_OPCODE_RFL 0x36 +#define NV30_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV30_FP_OP_OUT_ABS (1 << 29) +#define NV30_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV30_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV30_FP_OP_COND_SHIFT 18 +#define NV30_FP_OP_COND_MASK (0x07 << 18) +# define NV30_FP_OP_COND_FL 0 +# define NV30_FP_OP_COND_LT 1 +# define NV30_FP_OP_COND_EQ 2 +# define NV30_FP_OP_COND_LE 3 +# define NV30_FP_OP_COND_GT 4 +# define NV30_FP_OP_COND_NE 5 +# define NV30_FP_OP_COND_GE 6 +# define NV30_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV30_FP_OP_SRC_SCALE_SHIFT 28 +#define NV30_FP_OP_SRC_SCALE_MASK (3 << 28) + +/* high order bits of SRC2 */ +#define NV30_FP_OP_INDEX_INPUT (1 << 30) + +//== Register selection == +#define NV30_FP_REG_ALL_MASK (0x1FFFF<<0) +#define NV30_FP_REG_TYPE_SHIFT 0 +#define NV30_FP_REG_TYPE_MASK (3 << 0) +# define NV30_FP_REG_TYPE_TEMP 0 +# define NV30_FP_REG_TYPE_INPUT 1 +# define NV30_FP_REG_TYPE_CONST 2 +#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */ +#define NV30_FP_REG_SRC_MASK (31 << 2) +#define NV30_FP_REG_UNK_0 (1 << 8) +#define NV30_FP_REG_SWZ_ALL_SHIFT 9 +#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV30_FP_REG_SWZ_X_SHIFT 9 +#define NV30_FP_REG_SWZ_X_MASK (3 << 9) +#define NV30_FP_REG_SWZ_Y_SHIFT 11 +#define NV30_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV30_FP_REG_SWZ_Z_SHIFT 13 +#define NV30_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV30_FP_REG_SWZ_W_SHIFT 15 +#define NV30_FP_REG_SWZ_W_MASK (3 << 15) +# define NV30_FP_SWIZZLE_X 0 +# define NV30_FP_SWIZZLE_Y 1 +# define NV30_FP_SWIZZLE_Z 2 +# define NV30_FP_SWIZZLE_W 3 +#define NV30_FP_REG_NEGATE (1 << 17) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c new file mode 100644 index 00000000000..ad21fa27302 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -0,0 +1,980 @@ +/************************************************************************** + +Copyright 2006 Nouveau +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_state.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +#define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40) + +static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING_CACHE(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ + OUT_RING_CACHE(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ +} + +static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE((modeA<<16) | modeRGB); +} + + +static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); + OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); +} + +static void nv30Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint hw_bufs = 0; + + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) + hw_bufs |= 0xf0; + if (mask & (BUFFER_BIT_DEPTH)) + hw_bufs |= 0x03; + + if (hw_bufs) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1); + OUT_RING(hw_bufs); + } +} + +static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); +} + +static void nv30ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv30ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); +} + +static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + plane -= GL_CLIP_PLANE0; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); +} + +static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv30CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv30FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv30DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv30DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + if (NOUVEAU_CARD_USING_SHADERS) { + nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current; + if (nvs) + nvs->translated = GL_FALSE; + } else { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + } + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DITHER: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_FOG: + if (NOUVEAU_CARD_USING_SHADERS) + break; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); + + if (NOUVEAU_CARD_USING_SHADERS) + break; + + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (nmesa->lighting_enabled) + { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); + } + break; + } + case GL_LIGHTING: + if (NOUVEAU_CARD_USING_SHADERS) + break; + + nmesa->lighting_enabled=state; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING_CACHE(nmesa->enabled_lights); + else + OUT_RING_CACHE(0x0); + break; +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + if (nmesa->screen->card->type != NV_44) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); + } + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: + case GL_SCISSOR_TEST: + /* No enable bit, nv30Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + OUT_RING_CACHE(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + switch(pname) + { + case GL_FOG_MODE: + { + int mode = 0; + /* The modes are different in GL and the card. */ + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + mode = 0x804; + break; + case GL_EXP: + mode = 0x802; + break; + case GL_EXP2: + mode = 0x803; + break; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + OUT_RING_CACHE (mode); + break; + } + case GL_FOG_COLOR: + { + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1); + /* nvidia ignores the alpha channel */ + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); + break; + } + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + { + GLfloat f=0., c=0.; + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + f = -1.0/(ctx->Fog.End - ctx->Fog.Start); + c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953; + break; + case GL_EXP: + f = -0.090168*ctx->Fog.Density; + c = 1.5; + case GL_EXP2: + f = -0.212330*ctx->Fog.Density; + c = 1.5; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1); + OUT_RING_CACHE(f); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1); + OUT_RING_CACHE(c); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1); + OUT_RING_CACHE(0); /* Is this always the same? */ + break; + } +// case GL_FOG_COORD_SRC: + default: + break; + } +} + +static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +enum { + SPOTLIGHT_NO_UPDATE, + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + +static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + int spotlight_update = SPOTLIGHT_NO_UPDATE; + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + /* not sure where the fourth param value goes...*/ + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); + break; + case GL_SPOT_DIRECTION: + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; + break; + case GL_SPOT_EXPONENT: + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; + break; + case GL_SPOT_CUTOFF: + spotlight_update = SPOTLIGHT_UPDATE_ALL; + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); + OUT_RING_CACHEf(*params); + break; + default: + break; + } + + switch(spotlight_update) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 16) | factor); +} + +static void nv30LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubWidth; + + ubWidth = (GLubyte)(width * 8.0) & 0xFF; + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); + OUT_RING_CACHE(ubWidth); +} + +static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv30PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); +} + +/** Select a polygon rasterization mode */ +static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + + /* Looks like we always multiply units by 2.0... according to the dumps.*/ + OUT_RING_CACHEf(units * 2.0); +} + +/** Set the polygon stippling pattern */ +static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 4095; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING_CACHE(((w) << 16) | x); + OUT_RING_CACHE(((h) << 16) | y); +} + +/** Select flat or smooth shading */ +static void nv30ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (!NOUVEAU_CARD_USING_SHADERS) { + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); + } +} + +static void nv30WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2); + OUT_RING_CACHE(((w+x) << 16) | x); + OUT_RING_CACHE(((h+y) << 16) | y); + /* viewport transform */ + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8); + OUT_RING_CACHEf (v[MAT_TX]); + OUT_RING_CACHEf (v[MAT_TY]); + OUT_RING_CACHEf (v[MAT_TZ]); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (v[MAT_SX]); + OUT_RING_CACHEf (v[MAT_SY]); + OUT_RING_CACHEf (v[MAT_SZ]); + OUT_RING_CACHEf (0.0); + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +static GLboolean nv30InitCard(nouveauContextPtr nmesa) +{ + int i; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaAGP); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/ + OUT_RING(NvDmaFB); + + for(i = 0x2c8; i <= 0x2fc; i += 4) + { + BEGIN_RING_SIZE(NvSub3D, i, 1); + OUT_RING(0x0); + } + + BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1); + OUT_RING(0x00100000); + BEGIN_RING_SIZE(NvSub3D, 0x1454, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(3); + + /* NEW */ + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x3f800000); + BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0x0000ffff); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); +/* + BEGIN_RING_SIZE(NvSub3D, 0x100, 2); + OUT_RING(0); + OUT_RING(0); +*/ + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(0x00001200); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1); + OUT_RING (0); + + return GL_TRUE; +} + +static GLboolean nv40InitCard(nouveauContextPtr nmesa) +{ + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3); + OUT_RING(0x00000010); + OUT_RING(0x01000100); + OUT_RING(0xff800006); + BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1); + OUT_RING(0x06144321); + BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2); + OUT_RING(0xedcba987); + OUT_RING(0x00000021); + BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1); + OUT_RING(0x00171615); + BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1); + OUT_RING(0x001b1a19); + + BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1); + OUT_RING(0x0020ffff); + BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1); + OUT_RING(0x00d30000); + BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1); + OUT_RING(0x00000001); + + return GL_TRUE; +} + +static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); + OUT_RING (((w+x)<<16)|x); + OUT_RING (((h+y)<<16)|y); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING (0x148); + else + OUT_RING (0x143); + if (nmesa->screen->card->type >= NV_40) + OUT_RING (color[0]->pitch); + else + OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0)); + OUT_RING (color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); + OUT_RING (depth->offset); + if (nmesa->screen->card->type >= NV_40) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING (depth->pitch); + } + } + + return GL_TRUE; +} + +void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv30AlphaFunc; + func->BlendColor = nv30BlendColor; + func->BlendEquationSeparate = nv30BlendEquationSeparate; + func->BlendFuncSeparate = nv30BlendFuncSeparate; + func->Clear = nv30Clear; + func->ClearColor = nv30ClearColor; + func->ClearDepth = nv30ClearDepth; + func->ClearStencil = nv30ClearStencil; + func->ClipPlane = nv30ClipPlane; + func->ColorMask = nv30ColorMask; + func->ColorMaterial = nv30ColorMaterial; + func->CullFace = nv30CullFace; + func->FrontFace = nv30FrontFace; + func->DepthFunc = nv30DepthFunc; + func->DepthMask = nv30DepthMask; + func->DepthRange = nv30DepthRange; + func->Enable = nv30Enable; + func->Fogfv = nv30Fogfv; + func->Hint = nv30Hint; + func->Lightfv = nv30Lightfv; +/* func->LightModelfv = nv30LightModelfv; */ + func->LineStipple = nv30LineStipple; + func->LineWidth = nv30LineWidth; + func->LogicOpcode = nv30LogicOpcode; + func->PointParameterfv = nv30PointParameterfv; + func->PointSize = nv30PointSize; + func->PolygonMode = nv30PolygonMode; + func->PolygonOffset = nv30PolygonOffset; + func->PolygonStipple = nv30PolygonStipple; +#if 0 + func->ReadBuffer = nv30ReadBuffer; + func->RenderMode = nv30RenderMode; +#endif + func->Scissor = nv30Scissor; + func->ShadeModel = nv30ShadeModel; + func->StencilFuncSeparate = nv30StencilFuncSeparate; + func->StencilMaskSeparate = nv30StencilMaskSeparate; + func->StencilOpSeparate = nv30StencilOpSeparate; +#if 0 + func->TexGen = nv30TexGen; + func->TexParameter = nv30TexParameter; +#endif + func->TextureMatrix = nv30TextureMatrix; + + + if (nmesa->screen->card->type >= NV_40) + nmesa->hw_func.InitCard = nv40InitCard; + else + nmesa->hw_func.InitCard = nv30InitCard; + nmesa->hw_func.BindBuffers = nv30BindBuffers; + nmesa->hw_func.WindowMoved = nv30WindowMoved; +} + diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c new file mode 100644 index 00000000000..d023e8439e3 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -0,0 +1,367 @@ +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "nouveau_shader.h" +#include "nv30_shader.h" + +/***************************************************************************** + * Support routines + */ +static void +NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + /* We can do better here and keep more than one VP on the hardware, and + * switch between them with PROGRAM_START_ID.. + */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1); + OUT_RING(0); + for (i=0; i<nvs->program_size; i+=4) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4); + OUT_RING(nvs->program[i + 0]); + OUT_RING(nvs->program[i + 1]); + OUT_RING(nvs->program[i + 2]); + OUT_RING(nvs->program[i + 3]); + } + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); + OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); + OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); + OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1); + OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables); +} + +static void +NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLfloat *val; + + val = nvs->params[id].source_val ? + nvs->params[id].source_val : nvs->params[id].val; + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5); + OUT_RING (id); + OUT_RINGp(val, 4); +} + +/***************************************************************************** + * Assembly routines + */ +static void +NV30VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK; + shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT); +} + +/***************************************************************************** + * Disassembly routines + */ +static unsigned int +NV30VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + if (slot) { + op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK) + >> NV30_VP_INST_SCA_OPCODEL_SHIFT; + op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK) + >> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4; + } + else { + op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK) + >> NV30_VP_INST_VEC_OPCODE_SHIFT; + } + + return op; +} + +static nvsRegFile +NV30VPGetDestFile(nvsFunc * shader, int merged) +{ + switch (shader->GetOpcode(shader, merged)) { + case NVS_OP_ARL: + case NVS_OP_ARR: + case NVS_OP_ARA: + return NVS_FILE_ADDRESS; + default: + /*FIXME: This probably isn't correct.. */ + if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0) + return NVS_FILE_RESULT; + if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0) + return NVS_FILE_RESULT; + return NVS_FILE_TEMP; + } +} + +static unsigned int +NV30VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK) + >> NV30_VP_INST_DEST_ID_SHIFT); + switch (id) { + case NV30_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0; + case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1; + case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4; + case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5; + case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6; + case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + case NVS_FILE_ADDRESS: + case NVS_FILE_TEMP: + return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK) + >> NV30_VP_INST_DEST_TEMP_ID_SHIFT; + default: + return -1; + } +} + +static unsigned int +NV30VPGetDestMask(nvsFunc * shader, int merged) +{ + int hwmask, mask = 0; + + if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT) + if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) + >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) + >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT; + else if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK) + >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK) + >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT; + + if (hwmask & (1 << 3)) mask |= SMASK_X; + if (hwmask & (1 << 2)) mask |= SMASK_Y; + if (hwmask & (1 << 1)) mask |= SMASK_Z; + if (hwmask & (1 << 0)) mask |= SMASK_W; + + return mask; +} + +static int +NV30VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_TEMP: + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >> + NV30_VP_SRC_REG_TEMP_ID_SHIFT); + case NVS_FILE_CONST: + return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK) + >> NV30_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_ATTRIB: + src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK) + >> NV30_VP_INST_INPUT_SRC_SHIFT); + switch (src) { + case NV30_VP_INST_IN_POS : return NVS_FR_POSITION; + case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0; + case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1; + case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0; + case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1; + case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2; + case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3; + case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4; + case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5; + case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6; + case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7; + default: + return NVS_FR_UNKNOWN; + } + default: + return -1; + } +} + +static int +NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + static unsigned int abspos[3] = { + NV30_VP_INST_SRC0_ABS, + NV30_VP_INST_SRC1_ABS, + NV30_VP_INST_SRC2_ABS, + }; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2) + return 0; + + return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0); +} + +static int +NV30VPGetRelAddressRegID(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0); +} + +static nvsSwzComp +NV30VPGetRelAddressSwizzle(nvsFunc * shader) +{ + nvsSwzComp swz; + + swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK) + >> NV30_VP_INST_ADDR_SWZ_SHIFT]; + return swz; +} + +static int +NV30VPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV30VPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0); +} + +static int +NV30VPGetConditionTest(nvsFunc * shader) +{ + int op; + + /* The condition test is unconditionally enabled on some + * instructions. ie: the condition test bit does *NOT* have + * to be set. + * + * FIXME: check other relevant ops for this situation. + */ + op = shader->GetOpcodeHW(shader, 1); + switch (op) { + case NV30_VP_INST_OP_BRA: + return 1; + default: + return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0); + } +} + +static nvsCond +NV30VPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK) + >> NV30_VP_INST_COND_SHIFT); + + switch (cond) { + case NV30_VP_INST_COND_FL: return NVS_COND_FL; + case NV30_VP_INST_COND_LT: return NVS_COND_LT; + case NV30_VP_INST_COND_EQ: return NVS_COND_EQ; + case NV30_VP_INST_COND_LE: return NVS_COND_LE; + case NV30_VP_INST_COND_GT: return NVS_COND_GT; + case NV30_VP_INST_COND_NE: return NVS_COND_NE; + case NV30_VP_INST_COND_GE: return NVS_COND_GE; + case NV30_VP_INST_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK) + >> NV30_VP_INST_COND_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV30VPGetCondRegID(nvsFunc * shader) +{ + return 0; +} + + +static int +NV30VPGetBranch(nvsFunc * shader) +{ + return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK) + >> NV30_VP_INST_IADDR_SHIFT); +} + +void +NV30VPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV20 code, a lot of it is the same */ + NV20VPInitShaderFuncs(shader); + + /* Increase max valid opcode ID, and add new instructions */ + NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32; + + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA, 3, -1, -1); + + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS, 2, -1, -1); + + shader->UploadToHW = NV30VPUploadToHW; + shader->UpdateConst = NV30VPUpdateConst; + + shader->GetOpcodeHW = NV30VPGetOpcodeHW; + + shader->GetDestFile = NV30VPGetDestFile; + shader->GetDestID = NV30VPGetDestID; + shader->GetDestMask = NV30VPGetDestMask; + + shader->GetSourceID = NV30VPGetSourceID; + shader->GetSourceAbs = NV30VPGetSourceAbs; + + shader->GetRelAddressRegID = NV30VPGetRelAddressRegID; + shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle; + + shader->SupportsConditional = NV30VPSupportsConditional; + shader->GetConditionUpdate = NV30VPGetConditionUpdate; + shader->GetConditionTest = NV30VPGetConditionTest; + shader->GetCondition = NV30VPGetCondition; + shader->GetCondRegSwizzle = NV30VPGetCondRegSwizzle; + shader->GetCondRegID = NV30VPGetCondRegID; + + shader->GetBranch = NV30VPGetBranch; + shader->SetBranchTarget = NV30VPSetBranchTarget; +} + diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c new file mode 100644 index 00000000000..3e4ae0496e4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -0,0 +1,224 @@ +#include "nouveau_shader.h" +#include "nv40_shader.h" + +/* branching ops */ +unsigned int NVFP_TX_BOP_COUNT = 5; +struct _op_xlat NVFP_TX_BOP[64]; + + +/***************************************************************************** + * Assembly routines + * - These extend the NV30 routines, which are almost identical. NV40 + * just has branching hacked into the instruction set. + */ +static int +NV40FPSupportsResultScale(nvsFunc *shader, nvsScale scale) +{ + switch (scale) { + case NVS_SCALE_1X: + case NVS_SCALE_2X: + case NVS_SCALE_4X: + case NVS_SCALE_8X: + case NVS_SCALE_INV_2X: + case NVS_SCALE_INV_4X: + case NVS_SCALE_INV_8X: + return 1; + default: + return 0; + } +} + +static void +NV40FPSetResultScale(nvsFunc *shader, nvsScale scale) +{ + shader->inst[2] &= ~NV40_FP_OP_DST_SCALE_MASK; + shader->inst[2] |= ((unsigned int)scale << NV40_FP_OP_DST_SCALE_SHIFT); +} + +static void +NV40FPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT); +} + +static void +NV40FPSetBranchElse(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT); +} + +static void +NV40FPSetBranchEnd(nvsFunc *shader, int addr) +{ + shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK; + shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT); +} + +static void +NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment) +{ + shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK | + NV40_FP_OP_LOOP_INDEX_MASK | + NV40_FP_OP_LOOP_INCR_MASK); + shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) | + (initial << NV40_FP_OP_LOOP_INDEX_SHIFT) | + (increment << NV40_FP_OP_LOOP_INCR_SHIFT)); +} + +/***************************************************************************** + * Disassembly routines + */ +static struct _op_xlat * +NV40FPGetOPTXRec(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + int op; + + op = shader->GetOpcodeHW(shader, 0); + if (shader->inst[2] & NV40_FP_OP_OPCODE_IS_BRANCH) { + opr = NVFP_TX_BOP; + op &= ~NV40_FP_OP_OPCODE_IS_BRANCH; + if (op > NVFP_TX_BOP_COUNT) + return NULL; + } + else { + opr = NVFP_TX_AOP; + if (op > NVFP_TX_AOP_COUNT) + return NULL; + } + + if (opr[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &opr[op]; +} + +static int +NV40FPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[0] & NV40_FP_OP_INPUT_SRC_MASK) + >> NV40_FP_OP_INPUT_SRC_SHIFT) { + case NV40_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION; + case NV40_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV40_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV40_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD; + case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0; + case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1; + case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2; + case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3; + case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4; + case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5; + case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6; + case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7; + case NV40_FP_OP_INPUT_SRC_FACING : return NVS_FR_FACING; + default: + return -1; + } + break; + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV40_FP_REG_SRC_MASK) >> NV40_FP_REG_SRC_SHIFT); + } + case NVS_FILE_CONST: /* inlined into fragprog */ + default: + return -1; + } +} + +static int +NV40FPGetBranch(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_IADDR_MASK) + >> NV40_FP_OP_IADDR_SHIFT);; +} + +static int +NV40FPGetBranchElse(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_ELSE_ID_MASK) + >> NV40_FP_OP_ELSE_ID_SHIFT); +} + +static int +NV40FPGetBranchEnd(nvsFunc * shader) +{ + return ((shader->inst[3] & NV40_FP_OP_END_ID_MASK) + >> NV40_FP_OP_END_ID_SHIFT); +} + +static int +NV40FPGetLoopCount(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_COUNT_MASK) + >> NV40_FP_OP_LOOP_COUNT_SHIFT); +} + +static int +NV40FPGetLoopInitial(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_INDEX_MASK) + >> NV40_FP_OP_LOOP_INDEX_SHIFT); +} + +static int +NV40FPGetLoopIncrement(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_INCR_MASK) + >> NV40_FP_OP_LOOP_INCR_SHIFT); +} + +void +NV40FPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV30 FP code, it's mostly the same */ + NV30FPInitShaderFuncs(shader); + + /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find + * out if these actually work or not. + * + * update: either LIT/RSQ don't work on nv40, or I generate bad code for + * them. haven't tested the others yet + */ + MOD_OPCODE(NVFP_TX_AOP, 0x1B, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RSQ */ + MOD_OPCODE(NVFP_TX_AOP, 0x1E, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LIT */ + MOD_OPCODE(NVFP_TX_AOP, 0x1F, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LRP */ + MOD_OPCODE(NVFP_TX_AOP, 0x26, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 POW */ + MOD_OPCODE(NVFP_TX_AOP, 0x36, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RFL */ + + /* Extra opcodes supported on NV40 */ + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DIV , NVS_OP_DIV , 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DP2A , NVS_OP_DP2A, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_TXL , NVS_OP_TXL , 0, -1, -1); + + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_BRK , NVS_OP_BRK , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_CAL , NVS_OP_CAL , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_IF , NVS_OP_IF , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_LOOP, NVS_OP_LOOP, -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1); + + shader->SupportsResultScale = NV40FPSupportsResultScale; + shader->SetResultScale = NV40FPSetResultScale; + + /* fragment.facing */ + shader->GetSourceID = NV40FPGetSourceID; + + /* branching */ + shader->GetOPTXRec = NV40FPGetOPTXRec; + shader->GetBranch = NV40FPGetBranch; + shader->GetBranchElse = NV40FPGetBranchElse; + shader->GetBranchEnd = NV40FPGetBranchEnd; + shader->GetLoopCount = NV40FPGetLoopCount; + shader->GetLoopInitial = NV40FPGetLoopInitial; + shader->GetLoopIncrement = NV40FPGetLoopIncrement; + shader->SetBranchTarget = NV40FPSetBranchTarget; + shader->SetBranchElse = NV40FPSetBranchElse; + shader->SetBranchEnd = NV40FPSetBranchEnd; + shader->SetLoopParams = NV40FPSetLoopParams; +} diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h new file mode 100644 index 00000000000..584f4c23e08 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_shader.h @@ -0,0 +1,467 @@ +#ifndef __NV40_SHADER_H__ +#define __NV40_SHADER_H__ + +/* Vertex programs instruction set + * + * The NV40 instruction set is very similar to NV30. Most fields are in + * a slightly different position in the instruction however. + * + * Merged instructions + * In some cases it is possible to put two instructions into one opcode + * slot. The rules for when this is OK is not entirely clear to me yet. + * + * There are separate writemasks and dest temp register fields for each + * grouping of instructions. There is however only one field with the + * ID of a result register. Writing to temp/result regs is selected by + * setting VEC_RESULT/SCA_RESULT. + * + * Temporary registers + * The source/dest temp register fields have been extended by 1 bit, to + * give a total of 32 temporary registers. + * + * Relative Addressing + * NV40 can use an address register to index into vertex attribute regs. + * This is done by putting the offset value into INPUT_SRC and setting + * the INDEX_INPUT flag. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * There is a second condition code register on NV40, it's use is enabled + * by setting the COND_REG_SELECT_1 flag. + * + * Texture lookup + * TODO + */ + +/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ +#define NV40_VP_INST_VEC_RESULT (1 << 30) +/* uncertain.. */ +#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) +/* use address reg as index into attribs */ +#define NV40_VP_INST_INDEX_INPUT (1 << 27) +#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) +#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV40_VP_INST_SRC2_ABS (1 << 23) +#define NV40_VP_INST_SRC1_ABS (1 << 22) +#define NV40_VP_INST_SRC0_ABS (1 << 21) +#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15 +#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15) +#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) +#define NV40_VP_INST_COND_SHIFT 10 +#define NV40_VP_INST_COND_MASK (0x7 << 10) +# define NV40_VP_INST_COND_FL 0 +# define NV40_VP_INST_COND_LT 1 +# define NV40_VP_INST_COND_EQ 2 +# define NV40_VP_INST_COND_LE 3 +# define NV40_VP_INST_COND_GT 4 +# define NV40_VP_INST_COND_NE 5 +# define NV40_VP_INST_COND_GE 6 +# define NV40_VP_INST_COND_TR 7 +#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 +#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) +#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 +#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) +#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 +#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) +#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) +#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) +#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 +#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) +#define NV40_VP_INST0_KNOWN ( \ + NV40_VP_INST_INDEX_INPUT | \ + NV40_VP_INST_COND_REG_SELECT_1 | \ + NV40_VP_INST_ADDR_REG_SELECT_1 | \ + NV40_VP_INST_SRC2_ABS | \ + NV40_VP_INST_SRC1_ABS | \ + NV40_VP_INST_SRC0_ABS | \ + NV40_VP_INST_VEC_DEST_TEMP_MASK | \ + NV40_VP_INST_COND_TEST_ENABLE | \ + NV40_VP_INST_COND_MASK | \ + NV40_VP_INST_COND_SWZ_ALL_MASK | \ + NV40_VP_INST_ADDR_SWZ_MASK) + +/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ +#define NV40_VP_INST_VEC_OPCODE_SHIFT 22 +#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_MUL 0x02 +# define NV40_VP_INST_OP_ADD 0x03 +# define NV40_VP_INST_OP_MAD 0x04 +# define NV40_VP_INST_OP_DP3 0x05 +# define NV40_VP_INST_OP_DP4 0x07 +# define NV40_VP_INST_OP_DPH 0x06 +# define NV40_VP_INST_OP_DST 0x08 +# define NV40_VP_INST_OP_MIN 0x09 +# define NV40_VP_INST_OP_MAX 0x0A +# define NV40_VP_INST_OP_SLT 0x0B +# define NV40_VP_INST_OP_SGE 0x0C +# define NV40_VP_INST_OP_ARL 0x0D +# define NV40_VP_INST_OP_FRC 0x0E +# define NV40_VP_INST_OP_FLR 0x0F +# define NV40_VP_INST_OP_SEQ 0x10 +# define NV40_VP_INST_OP_SFL 0x11 +# define NV40_VP_INST_OP_SGT 0x12 +# define NV40_VP_INST_OP_SLE 0x13 +# define NV40_VP_INST_OP_SNE 0x14 +# define NV40_VP_INST_OP_STR 0x15 +# define NV40_VP_INST_OP_SSG 0x16 +# define NV40_VP_INST_OP_ARR 0x17 +# define NV40_VP_INST_OP_ARA 0x18 +# define NV40_VP_INST_OP_TXWHAT 0x19 +#define NV40_VP_INST_SCA_OPCODE_SHIFT 27 +#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27) +# define NV40_VP_INST_OP_RCP 0x02 +# define NV40_VP_INST_OP_RCC 0x03 +# define NV40_VP_INST_OP_RSQ 0x04 +# define NV40_VP_INST_OP_EXP 0x05 +# define NV40_VP_INST_OP_LOG 0x06 +# define NV40_VP_INST_OP_LIT 0x07 +# define NV40_VP_INST_OP_BRA 0x09 +# define NV40_VP_INST_OP_CAL 0x0B +# define NV40_VP_INST_OP_RET 0x0C +# define NV40_VP_INST_OP_LG2 0x0D +# define NV40_VP_INST_OP_EX2 0x0E +# define NV40_VP_INST_OP_SIN 0x0F +# define NV40_VP_INST_OP_COS 0x10 +# define NV40_VP_INST_OP_PUSHA 0x13 +# define NV40_VP_INST_OP_POPA 0x14 +#define NV40_VP_INST_CONST_SRC_SHIFT 12 +#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) +#define NV40_VP_INST_INPUT_SRC_SHIFT 8 +#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) +# define NV40_VP_INST_IN_POS 0 +# define NV40_VP_INST_IN_WEIGHT 1 +# define NV40_VP_INST_IN_NORMAL 2 +# define NV40_VP_INST_IN_COL0 3 +# define NV40_VP_INST_IN_COL1 4 +# define NV40_VP_INST_IN_FOGC 5 +# define NV40_VP_INST_IN_TC0 8 +# define NV40_VP_INST_IN_TC(n) (8+n) +#define NV40_VP_INST_SRC0H_SHIFT 0 +#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) +#define NV40_VP_INST1_KNOWN ( \ + NV40_VP_INST_VEC_OPCODE_MASK | \ + NV40_VP_INST_SCA_OPCODE_MASK | \ + NV40_VP_INST_CONST_SRC_MASK | \ + NV40_VP_INST_INPUT_SRC_MASK | \ + NV40_VP_INST_SRC0H_MASK \ + ) + +/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ +#define NV40_VP_INST_SRC0L_SHIFT 23 +#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) +#define NV40_VP_INST_SRC1_SHIFT 6 +#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) +#define NV40_VP_INST_SRC2H_SHIFT 0 +#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) +#define NV40_VP_INST_IADDRH_SHIFT 0 +#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) + +/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ +#define NV40_VP_INST_IADDRL_SHIFT 29 +#define NV40_VP_INST_IADDRL_MASK (7 << 29) +#define NV40_VP_INST_SRC2L_SHIFT 21 +#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) +#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17 +#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17) +# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20) +# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19) +# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18) +# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17) +#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13 +#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13) +# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16) +# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15) +# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14) +# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13) +#define NV40_VP_INST_SCA_RESULT (1 << 12) +#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7 +#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7) +#define NV40_VP_INST_DEST_SHIFT 2 +#define NV40_VP_INST_DEST_MASK (31 << 2) +# define NV40_VP_INST_DEST_POS 0 +# define NV40_VP_INST_DEST_COL0 1 +# define NV40_VP_INST_DEST_COL1 2 +# define NV40_VP_INST_DEST_BFC0 3 +# define NV40_VP_INST_DEST_BFC1 4 +# define NV40_VP_INST_DEST_FOGC 5 +# define NV40_VP_INST_DEST_PSZ 6 +# define NV40_VP_INST_DEST_TC0 7 +# define NV40_VP_INST_DEST_TC(n) (7+n) +# define NV40_VP_INST_DEST_TEMP 0x1F +#define NV40_VP_INST_INDEX_CONST (1 << 1) +#define NV40_VP_INST_LAST (1 << 0) +#define NV40_VP_INST3_KNOWN ( \ + NV40_VP_INST_SRC2L_MASK |\ + NV40_VP_INST_SCA_WRITEMASK_MASK |\ + NV40_VP_INST_VEC_WRITEMASK_MASK |\ + NV40_VP_INST_SCA_DEST_TEMP_MASK |\ + NV40_VP_INST_DEST_MASK |\ + NV40_VP_INST_INDEX_CONST) + +/* Useful to split the source selection regs into their pieces */ +#define NV40_VP_SRC0_HIGH_SHIFT 9 +#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 +#define NV40_VP_SRC0_LOW_MASK 0x000001FF +#define NV40_VP_SRC2_HIGH_SHIFT 11 +#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 +#define NV40_VP_SRC2_LOW_MASK 0x000007FF + +/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ +#define NV40_VP_SRC_NEGATE (1 << 16) +#define NV40_VP_SRC_SWZ_X_SHIFT 14 +#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) +#define NV40_VP_SRC_SWZ_Y_SHIFT 12 +#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) +#define NV40_VP_SRC_SWZ_Z_SHIFT 10 +#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) +#define NV40_VP_SRC_SWZ_W_SHIFT 8 +#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) +#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 +#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) +#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2) +#define NV40_VP_SRC_REG_TYPE_SHIFT 0 +#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) +# define NV40_VP_SRC_REG_TYPE_UNK0 0 +# define NV40_VP_SRC_REG_TYPE_TEMP 1 +# define NV40_VP_SRC_REG_TYPE_INPUT 2 +# define NV40_VP_SRC_REG_TYPE_CONST 3 + + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, + * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and + * SWIZZLE_ONE. + * + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as + * SWIZZLE_ZERO is implemented simply by not writing to the relevant components + * of the destination. + * + * Looping + * Loops appear to be fairly expensive on NV40 at least, the proprietary + * driver goes to a lot of effort to avoid using the native looping + * instructions. If the total number of *executed* instructions between + * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop. + * The maximum loop count is 255. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + * DP2 - MUL + ADD + * NRM + */ + +//== Opcode / Destination selection == +#define NV40_FP_OP_PROGRAM_END (1 << 0) +#define NV40_FP_OP_OUT_REG_SHIFT 1 +#define NV40_FP_OP_OUT_REG_MASK (31 << 1) +/* Needs to be set when writing outputs to get expected result.. */ +#define NV40_FP_OP_UNK0_7 (1 << 7) +#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV40_FP_OP_OUTMASK_SHIFT 9 +#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV40_FP_OP_OUT_X (1 << 9) +# define NV40_FP_OP_OUT_Y (1 <<10) +# define NV40_FP_OP_OUT_Z (1 <<11) +# define NV40_FP_OP_OUT_W (1 <<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV40_FP_OP_INPUT_SRC_SHIFT 13 +#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV40_FP_OP_INPUT_SRC_COL0 0x1 +# define NV40_FP_OP_INPUT_SRC_COL1 0x2 +# define NV40_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV40_FP_OP_INPUT_SRC_TC0 0x4 +# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +# define NV40_FP_OP_INPUT_SRC_FACING 0xE +#define NV40_FP_OP_TEX_UNIT_SHIFT 17 +#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) +#define NV40_FP_OP_PRECISION_SHIFT 22 +#define NV40_FP_OP_PRECISION_MASK (3 << 22) +# define NV40_FP_PRECISION_FP32 0 +# define NV40_FP_PRECISION_FP16 1 +# define NV40_FP_PRECISION_FX12 2 +#define NV40_FP_OP_OPCODE_SHIFT 24 +#define NV40_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV40_FP_OP_OPCODE_NOP 0x00 +# define NV40_FP_OP_OPCODE_MOV 0x01 +# define NV40_FP_OP_OPCODE_MUL 0x02 +# define NV40_FP_OP_OPCODE_ADD 0x03 +# define NV40_FP_OP_OPCODE_MAD 0x04 +# define NV40_FP_OP_OPCODE_DP3 0x05 +# define NV40_FP_OP_OPCODE_DP4 0x06 +# define NV40_FP_OP_OPCODE_DST 0x07 +# define NV40_FP_OP_OPCODE_MIN 0x08 +# define NV40_FP_OP_OPCODE_MAX 0x09 +# define NV40_FP_OP_OPCODE_SLT 0x0A +# define NV40_FP_OP_OPCODE_SGE 0x0B +# define NV40_FP_OP_OPCODE_SLE 0x0C +# define NV40_FP_OP_OPCODE_SGT 0x0D +# define NV40_FP_OP_OPCODE_SNE 0x0E +# define NV40_FP_OP_OPCODE_SEQ 0x0F +# define NV40_FP_OP_OPCODE_FRC 0x10 +# define NV40_FP_OP_OPCODE_FLR 0x11 +# define NV40_FP_OP_OPCODE_KIL 0x12 +# define NV40_FP_OP_OPCODE_PK4B 0x13 +# define NV40_FP_OP_OPCODE_UP4B 0x14 +/* DDX/DDY can only write to XY */ +# define NV40_FP_OP_OPCODE_DDX 0x15 +# define NV40_FP_OP_OPCODE_DDY 0x16 +# define NV40_FP_OP_OPCODE_TEX 0x17 +# define NV40_FP_OP_OPCODE_TXP 0x18 +# define NV40_FP_OP_OPCODE_TXD 0x19 +# define NV40_FP_OP_OPCODE_RCP 0x1A +# define NV40_FP_OP_OPCODE_EX2 0x1C +# define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_COS 0x22 +# define NV40_FP_OP_OPCODE_SIN 0x23 +# define NV40_FP_OP_OPCODE_PK2H 0x24 +# define NV40_FP_OP_OPCODE_UP2H 0x25 +# define NV40_FP_OP_OPCODE_PK4UB 0x27 +# define NV40_FP_OP_OPCODE_UP4UB 0x28 +# define NV40_FP_OP_OPCODE_PK2US 0x29 +# define NV40_FP_OP_OPCODE_UP2US 0x2A +# define NV40_FP_OP_OPCODE_DP2A 0x2E +# define NV40_FP_OP_OPCODE_TXL 0x2F +# define NV40_FP_OP_OPCODE_TXB 0x31 +# define NV40_FP_OP_OPCODE_DIV 0x3A +/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/ +# define NV40_FP_OP_BRA_OPCODE_BRK 0x0 +# define NV40_FP_OP_BRA_OPCODE_CAL 0x1 +# define NV40_FP_OP_BRA_OPCODE_IF 0x2 +# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3 +# define NV40_FP_OP_BRA_OPCODE_REP 0x4 +# define NV40_FP_OP_BRA_OPCODE_RET 0x5 +#define NV40_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV40_FP_OP_OUT_ABS (1 << 29) +#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV40_FP_OP_COND_SHIFT 18 +#define NV40_FP_OP_COND_MASK (0x07 << 18) +# define NV40_FP_OP_COND_FL 0 +# define NV40_FP_OP_COND_LT 1 +# define NV40_FP_OP_COND_EQ 2 +# define NV40_FP_OP_COND_LE 3 +# define NV40_FP_OP_COND_GT 4 +# define NV40_FP_OP_COND_NE 5 +# define NV40_FP_OP_COND_GE 6 +# define NV40_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) +#define NV40_FP_OP_DST_SCALE_SHIFT 28 +#define NV40_FP_OP_DST_SCALE_MASK (3 << 28) + +/* SRC1 LOOP */ +#define NV40_FP_OP_LOOP_INCR_SHIFT 19 +#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19) +#define NV40_FP_OP_LOOP_INDEX_SHIFT 10 +#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10) +#define NV40_FP_OP_LOOP_COUNT_SHIFT 2 +#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2) + +/* SRC1 IF */ +#define NV40_FP_OP_ELSE_ID_SHIFT 2 +#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2) + +/* SRC1 CAL */ +#define NV40_FP_OP_IADDR_SHIFT 2 +#define NV40_FP_OP_IADDR_MASK (0xFF << 2) + +/* SRC1 REP + * I have no idea why there are 3 count values here.. but they + * have always been filled with the same value in my tests so + * far.. + */ +#define NV40_FP_OP_REP_COUNT1_SHIFT 2 +#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2) +#define NV40_FP_OP_REP_COUNT2_SHIFT 10 +#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10) +#define NV40_FP_OP_REP_COUNT3_SHIFT 19 +#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19) + +/* SRC2 REP/IF */ +#define NV40_FP_OP_END_ID_SHIFT 2 +#define NV40_FP_OP_END_ID_MASK (0xFF << 2) + +// SRC2 high-order +#define NV40_FP_OP_INDEX_INPUT (1 << 30) +#define NV40_FP_OP_ADDR_INDEX_SHIFT 19 +#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19) + +//== Register selection == +#define NV40_FP_REG_TYPE_SHIFT 0 +#define NV40_FP_REG_TYPE_MASK (3 << 0) +# define NV40_FP_REG_TYPE_TEMP 0 +# define NV40_FP_REG_TYPE_INPUT 1 +# define NV40_FP_REG_TYPE_CONST 2 +#define NV40_FP_REG_SRC_SHIFT 2 +#define NV40_FP_REG_SRC_MASK (31 << 2) +#define NV40_FP_REG_UNK_0 (1 << 8) +#define NV40_FP_REG_SWZ_ALL_SHIFT 9 +#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV40_FP_REG_SWZ_X_SHIFT 9 +#define NV40_FP_REG_SWZ_X_MASK (3 << 9) +#define NV40_FP_REG_SWZ_Y_SHIFT 11 +#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV40_FP_REG_SWZ_Z_SHIFT 13 +#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV40_FP_REG_SWZ_W_SHIFT 15 +#define NV40_FP_REG_SWZ_W_MASK (3 << 15) +# define NV40_FP_SWIZZLE_X 0 +# define NV40_FP_SWIZZLE_Y 1 +# define NV40_FP_SWIZZLE_Z 2 +# define NV40_FP_SWIZZLE_W 3 +#define NV40_FP_REG_NEGATE (1 << 17) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c new file mode 100644 index 00000000000..d054140bcd0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -0,0 +1,778 @@ +#include "nouveau_shader.h" +#include "nouveau_msg.h" +#include "nv40_shader.h" + +/***************************************************************************** + * Assembly routines + */ +static int +NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op) +{ + if (shader->GetOPTXFromSOP(op, NULL)) + return 1; + return 0; +} + +static void +NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) +{ + if (slot) { + shader->inst[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK; + shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT); + } else { + shader->inst[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK; + shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT); + } +} + +static void +NV40VPSetCCUpdate(nvsFunc *shader) +{ + shader->inst[0] |= NV40_VP_INST_COND_UPDATE_ENABLE; +} + +static void +NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, + nvsSwzComp *swizzle) +{ + unsigned int hwcond; + + if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE; + else shader->inst[0] &= ~NV40_VP_INST_COND_TEST_ENABLE; + if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1; + else shader->inst[0] &= ~NV40_VP_INST_COND_REG_SELECT_1; + + switch (cond) { + case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break; + case NVS_COND_FL: hwcond = NV40_VP_INST_COND_FL; break; + case NVS_COND_LT: hwcond = NV40_VP_INST_COND_LT; break; + case NVS_COND_GT: hwcond = NV40_VP_INST_COND_GT; break; + case NVS_COND_NE: hwcond = NV40_VP_INST_COND_NE; break; + case NVS_COND_EQ: hwcond = NV40_VP_INST_COND_EQ; break; + case NVS_COND_GE: hwcond = NV40_VP_INST_COND_GE; break; + case NVS_COND_LE: hwcond = NV40_VP_INST_COND_LE; break; + default: + WARN_ONCE("unknown vp cond %d\n", cond); + hwcond = NV40_VP_INST_COND_TR; + break; + } + shader->inst[0] &= ~NV40_VP_INST_COND_MASK; + shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT); + + shader->inst[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK; + shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT); +} + +/* these just exist here until nouveau_reg.h has them. */ +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14) + +static unsigned int +NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, + unsigned int *mask_ret) +{ + unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables; + + *mask_ret = 0xf; + + switch (result) { + case NVS_FR_POSITION: + /* out_reg POS implied */ + return NV40_VP_INST_DEST_POS; + case NVS_FR_COL0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0; + return NV40_VP_INST_DEST_COL0; + case NVS_FR_COL1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1; + return NV40_VP_INST_DEST_COL1; + case NVS_FR_BFC0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0; + return NV40_VP_INST_DEST_BFC0; + case NVS_FR_BFC1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1; + return NV40_VP_INST_DEST_BFC1; + case NVS_FR_FOGCOORD: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + (*clip_en) |= 0x00000002; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + (*clip_en) |= 0x00000020; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP2: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + (*clip_en) |= 0x00000200; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_POINTSZ: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP3: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + (*clip_en) |= 0x00002000; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP4: + (*clip_en) |= 0x00020000; + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP5: + (*clip_en) |= 0x00200000; + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_TEXCOORD0: + case NVS_FR_TEXCOORD1: + case NVS_FR_TEXCOORD2: + case NVS_FR_TEXCOORD3: + case NVS_FR_TEXCOORD4: + case NVS_FR_TEXCOORD5: + case NVS_FR_TEXCOORD6: + case NVS_FR_TEXCOORD7: + { + int unit = result - NVS_FR_TEXCOORD0; + (*out_reg) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 << unit); + return NV40_VP_INST_DEST_TC(unit); + } + default: + WARN_ONCE("unknown vp output %d\n", result); + return NV40_VP_INST_DEST_POS; + } +} + +static void +NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, + int slot) +{ + unsigned int hwmask = 0; + + if (mask & SMASK_X) hwmask |= (1 << 3); + if (mask & SMASK_Y) hwmask |= (1 << 2); + if (mask & SMASK_Z) hwmask |= (1 << 1); + if (mask & SMASK_W) hwmask |= (1 << 0); + + if (dest->file == NVS_FILE_RESULT) { + unsigned int valid_mask; + int hwidx; + + hwidx = NV40VPTranslateResultReg(shader, dest->index, &valid_mask); + if (hwmask & ~valid_mask) + WARN_ONCE("writing invalid components of result reg\n"); + hwmask &= valid_mask; + + shader->inst[3] &= ~NV40_VP_INST_DEST_MASK; + shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT); + + if (slot) shader->inst[3] |= NV40_VP_INST_SCA_RESULT; + else shader->inst[0] |= NV40_VP_INST_VEC_RESULT; + } else { + /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */ + if (slot) { + shader->inst[3] &= ~NV40_VP_INST_SCA_RESULT; + shader->inst[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK; + shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + } else { + shader->inst[0] &= ~NV40_VP_INST_VEC_RESULT; + shader->inst[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20)); + shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + } + } + + if (slot) { + shader->inst[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK; + shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); + } else { + shader->inst[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK; + shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); + } +} + +static void +NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos) +{ + switch (pos) { + case 0: + shader->inst[1] &= ~NV40_VP_INST_SRC0H_MASK; + shader->inst[2] &= ~NV40_VP_INST_SRC0L_MASK; + shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >> + NV40_VP_SRC0_HIGH_SHIFT) + << NV40_VP_INST_SRC0H_SHIFT; + shader->inst[2] |= (hw & NV40_VP_SRC0_LOW_MASK) + << NV40_VP_INST_SRC0L_SHIFT; + break; + case 1: + shader->inst[2] &= ~NV40_VP_INST_SRC1_MASK; + shader->inst[2] |= hw + << NV40_VP_INST_SRC1_SHIFT; + break; + case 2: + shader->inst[2] &= ~NV40_VP_INST_SRC2H_MASK; + shader->inst[3] &= ~NV40_VP_INST_SRC2L_MASK; + shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >> + NV40_VP_SRC2_HIGH_SHIFT) + << NV40_VP_INST_SRC2H_SHIFT; + shader->inst[3] |= (hw & NV40_VP_SRC2_LOW_MASK) + << NV40_VP_INST_SRC2L_SHIFT; + break; + default: + assert(0); + break; + } +} + +static void +NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) +{ + unsigned int hw = 0; + + switch (src->file) { + case NVS_FILE_ADDRESS: + break; + case NVS_FILE_ATTRIB: + hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + + shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK; + shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT); + shader->card_priv->NV30VP.vp_in_reg |= (1 << src->index); + if (src->indexed) { + shader->inst[0] |= NV40_VP_INST_INDEX_INPUT; + if (src->addr_reg) + shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + else + shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT; + shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); + } else + shader->inst[0] &= ~NV40_VP_INST_INDEX_INPUT; + break; + case NVS_FILE_CONST: + hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); + + shader->inst[1] &= ~NV40_VP_INST_CONST_SRC_MASK; + shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT); + if (src->indexed) { + shader->inst[3] |= NV40_VP_INST_INDEX_CONST; + if (src->addr_reg) + shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + else + shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK; + shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); + } else + shader->inst[3] &= ~NV40_VP_INST_INDEX_CONST; + break; + case NVS_FILE_TEMP: + hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT); + hw |= (src->index << NV40_VP_SRC_TEMP_SRC_SHIFT); + break; + default: + fprintf(stderr, "unknown source file %d\n", src->file); + assert(0); + break; + } + + if (src->file != NVS_FILE_ADDRESS) { + if (src->negate) + hw |= NV40_VP_SRC_NEGATE; + if (src->abs) + shader->inst[0] |= (1 << (21 + pos)); + else + shader->inst[0] &= ~(1 << (21 + pos)); + hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT); + hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT); + hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT); + hw |= (src->swizzle[3] << NV40_VP_SRC_SWZ_W_SHIFT); + + NV40VPInsertSource(shader, hw, pos); + } +} + +static void +NV40VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK; + shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT; + shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK; + shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT); +} + +static void +NV40VPInitInstruction(nvsFunc *shader) +{ + unsigned int hwsrc = 0; + + shader->inst[0] = /*NV40_VP_INST_VEC_RESULT | */ + NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + shader->inst[1] = 0; + shader->inst[2] = 0; + shader->inst[3] = NV40_VP_INST_SCA_RESULT | + NV40_VP_INST_SCA_DEST_TEMP_MASK | + NV40_VP_INST_DEST_MASK; + + hwsrc = (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT); + NV40VPInsertSource(shader, hwsrc, 0); + NV40VPInsertSource(shader, hwsrc, 1); + NV40VPInsertSource(shader, hwsrc, 2); +} + +static void +NV40VPSetLastInst(nvsFunc *shader) +{ + shader->inst[3] |= 1; +} + +/***************************************************************************** + * Disassembly routines + */ +static int +NV40VPHasMergedInst(nvsFunc * shader) +{ + if (shader->GetOpcodeHW(shader, 0) != NV40_VP_INST_OP_NOP && + shader->GetOpcodeHW(shader, 1) != NV40_VP_INST_OP_NOP) + return 1; + return 0; +} + +static unsigned int +NV40VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + if (slot) + op = (shader->inst[1] & NV40_VP_INST_SCA_OPCODE_MASK) + >> NV40_VP_INST_SCA_OPCODE_SHIFT; + else + op = (shader->inst[1] & NV40_VP_INST_VEC_OPCODE_MASK) + >> NV40_VP_INST_VEC_OPCODE_SHIFT; + + return op; +} + +static nvsRegFile +NV40VPGetDestFile(nvsFunc * shader, int merged) +{ + nvsOpcode op; + + op = shader->GetOpcode(shader, merged); + switch (op) { + case NVS_OP_ARL: + case NVS_OP_ARR: + case NVS_OP_ARA: + case NVS_OP_POPA: + return NVS_FILE_ADDRESS; + default: + if (shader->GetOpcodeSlot(shader, merged)) { + if (shader->inst[3] & NV40_VP_INST_SCA_RESULT) + return NVS_FILE_RESULT; + } + else { + if (shader->inst[0] & NV40_VP_INST_VEC_RESULT) + return NVS_FILE_RESULT; + } + return NVS_FILE_TEMP; + } + +} + +static unsigned int +NV40VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV40_VP_INST_DEST_MASK) + >> NV40_VP_INST_DEST_SHIFT); + switch (id) { + case NV40_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV40_VP_INST_DEST_COL0: return NVS_FR_COL0; + case NV40_VP_INST_DEST_COL1: return NVS_FR_COL1; + case NV40_VP_INST_DEST_BFC0: return NVS_FR_BFC0; + case NV40_VP_INST_DEST_BFC1: return NVS_FR_BFC1; + case NV40_VP_INST_DEST_FOGC: { + int mask = shader->GetDestMask(shader, merged); + switch (mask) { + case SMASK_X: return NVS_FR_FOGCOORD; + case SMASK_Y: return NVS_FR_CLIP0; + case SMASK_Z: return NVS_FR_CLIP1; + case SMASK_W: return NVS_FR_CLIP2; + default: + printf("more than 1 mask component set in FOGC writemask!\n"); + return NVS_FR_UNKNOWN; + } + } + case NV40_VP_INST_DEST_PSZ: + { + int mask = shader->GetDestMask(shader, merged); + switch (mask) { + case SMASK_X: return NVS_FR_POINTSZ; + case SMASK_Y: return NVS_FR_CLIP3; + case SMASK_Z: return NVS_FR_CLIP4; + case SMASK_W: return NVS_FR_CLIP5; + default: + printf("more than 1 mask component set in PSZ writemask!\n"); + return NVS_FR_UNKNOWN; + } + } + case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4; + case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5; + case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6; + case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + case NVS_FILE_ADDRESS: + /* Instructions that write address regs are encoded as if + * they would write temps. + */ + case NVS_FILE_TEMP: + if (shader->GetOpcodeSlot(shader, merged)) + id = ((shader->inst[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK) + >> NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + else + id = ((shader->inst[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK) + >> NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV40VPGetDestMask(nvsFunc * shader, int merged) +{ + unsigned int mask = 0; + + if (shader->GetOpcodeSlot(shader, merged)) { + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_X) mask |= SMASK_X; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Y) mask |= SMASK_Y; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Z) mask |= SMASK_Z; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_W) mask |= SMASK_W; + } else { + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_X) mask |= SMASK_X; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Y) mask |= SMASK_Y; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Z) mask |= SMASK_Z; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_W) mask |= SMASK_W; + } + + return mask; +} + +static unsigned int +NV40VPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + unsigned int src; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return -1; + + switch (opr->srcpos[pos]) { + case 0: + src = ((shader->inst[1] & NV40_VP_INST_SRC0H_MASK) + >> NV40_VP_INST_SRC0H_SHIFT) + << NV40_VP_SRC0_HIGH_SHIFT; + src |= ((shader->inst[2] & NV40_VP_INST_SRC0L_MASK) + >> NV40_VP_INST_SRC0L_SHIFT); + break; + case 1: + src = ((shader->inst[2] & NV40_VP_INST_SRC1_MASK) + >> NV40_VP_INST_SRC1_SHIFT); + break; + case 2: + src = ((shader->inst[2] & NV40_VP_INST_SRC2H_MASK) + >> NV40_VP_INST_SRC2H_SHIFT) + << NV40_VP_SRC2_HIGH_SHIFT; + src |= ((shader->inst[3] & NV40_VP_INST_SRC2L_MASK) + >> NV40_VP_INST_SRC2L_SHIFT); + break; + default: + src = -1; + } + + return src; +} + +static nvsRegFile +NV40VPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: return NVS_FILE_ADDRESS; + default: + src = shader->GetSourceHW(shader, merged, pos); + file = (src & NV40_VP_SRC_REG_TYPE_MASK) >> NV40_VP_SRC_REG_TYPE_SHIFT; + + switch (file) { + case NV40_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV40_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV40_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV40VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[1] & NV40_VP_INST_INPUT_SRC_MASK) + >> NV40_VP_INST_INPUT_SRC_SHIFT) { + case NV40_VP_INST_IN_POS: return NVS_FR_POSITION; + case NV40_VP_INST_IN_WEIGHT: return NVS_FR_WEIGHT; + case NV40_VP_INST_IN_NORMAL: return NVS_FR_NORMAL; + case NV40_VP_INST_IN_COL0: return NVS_FR_COL0; + case NV40_VP_INST_IN_COL1: return NVS_FR_COL1; + case NV40_VP_INST_IN_FOGC: return NVS_FR_FOGCOORD; + case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0; + case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1; + case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2; + case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3; + case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4; + case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5; + case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6; + case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + break; + case NVS_FILE_CONST: + return ((shader->inst[1] & NV40_VP_INST_CONST_SRC_MASK) + >> NV40_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV40_VP_SRC_TEMP_SRC_MASK) >> + NV40_VP_SRC_TEMP_SRC_SHIFT); + } + default: + return -1; + } +} + +static int +NV40VPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + if (src == -1) + return -1; + return ((src & NV40_VP_SRC_NEGATE) ? 1 : 0); +} + +static void +NV40VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = (src & NV40_VP_SRC_SWZ_ALL_MASK) >> NV40_VP_SRC_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV40VPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + return ((shader->inst[0] & NV40_VP_INST_INDEX_INPUT) ? 1 : 0); + case NVS_FILE_CONST: + return ((shader->inst[3] & NV40_VP_INST_INDEX_CONST) ? 1 : 0); + default: + return 0; + } +} + +static nvsSwzComp +NV40VPGetAddressRegSwizzle(nvsFunc * shader) +{ + nvsSwzComp swz; + + swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV40_VP_INST_ADDR_SWZ_MASK) + >> NV40_VP_INST_ADDR_SWZ_SHIFT]; + return swz; +} + +static int +NV40VPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV40VPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV40_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0); +} + +static int +NV40VPGetConditionTest(nvsFunc * shader) +{ + int op; + + /* The condition test is unconditionally enabled on some + * instructions. ie: the condition test bit does *NOT* have + * to be set. + * + * FIXME: check other relevant ops for this situation. + */ + op = shader->GetOpcodeHW(shader, 1); + switch (op) { + case NV40_VP_INST_OP_BRA: + return 1; + default: + return ((shader->inst[0] & NV40_VP_INST_COND_TEST_ENABLE) ? 1 : 0); + } +} + +static nvsCond +NV40VPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[0] & NV40_VP_INST_COND_MASK) + >> NV40_VP_INST_COND_SHIFT); + + switch (cond) { + case NV40_VP_INST_COND_FL: return NVS_COND_FL; + case NV40_VP_INST_COND_LT: return NVS_COND_LT; + case NV40_VP_INST_COND_EQ: return NVS_COND_EQ; + case NV40_VP_INST_COND_LE: return NVS_COND_LE; + case NV40_VP_INST_COND_GT: return NVS_COND_GT; + case NV40_VP_INST_COND_NE: return NVS_COND_NE; + case NV40_VP_INST_COND_GE: return NVS_COND_GE; + case NV40_VP_INST_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV40VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[0] & NV40_VP_INST_COND_SWZ_ALL_MASK) + >> NV40_VP_INST_COND_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV40VPGetCondRegID(nvsFunc * shader) +{ + return ((shader->inst[0] & NV40_VP_INST_COND_REG_SELECT_1) ? 1 : 0); +} + +static int +NV40VPGetBranch(nvsFunc * shader) +{ + int addr; + + addr = ((shader->inst[2] & NV40_VP_INST_IADDRH_MASK) + >> NV40_VP_INST_IADDRH_SHIFT) << 3; + addr |= ((shader->inst[3] & NV40_VP_INST_IADDRL_MASK) + >> NV40_VP_INST_IADDRL_SHIFT); + return addr; +} + +void +NV40VPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV30 VP code, we share some of it */ + NV30VPInitShaderFuncs(shader); + + /* Limits */ + shader->MaxInst = 4096; + shader->MaxAttrib = 16; + shader->MaxTemp = 32; + shader->MaxAddress = 2; + shader->MaxConst = 256; + shader->caps = SCAP_SRC_ABS; + + /* Add extra opcodes for NV40+ */ +// MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1); + MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1); + + shader->InitInstruction = NV40VPInitInstruction; + shader->SupportsOpcode = NV40VPSupportsOpcode; + shader->SetOpcode = NV40VPSetOpcode; + shader->SetCCUpdate = NV40VPSetCCUpdate; + shader->SetCondition = NV40VPSetCondition; + shader->SetResult = NV40VPSetResult; + shader->SetSource = NV40VPSetSource; + shader->SetLastInst = NV40VPSetLastInst; + shader->SetBranchTarget = NV40VPSetBranchTarget; + + shader->HasMergedInst = NV40VPHasMergedInst; + shader->GetOpcodeHW = NV40VPGetOpcodeHW; + + shader->GetDestFile = NV40VPGetDestFile; + shader->GetDestID = NV40VPGetDestID; + shader->GetDestMask = NV40VPGetDestMask; + + shader->GetSourceHW = NV40VPGetSourceHW; + shader->GetSourceFile = NV40VPGetSourceFile; + shader->GetSourceID = NV40VPGetSourceID; + shader->GetSourceNegate = NV40VPGetSourceNegate; + shader->GetSourceSwizzle = NV40VPGetSourceSwizzle; + shader->GetSourceIndexed = NV40VPGetSourceIndexed; + + shader->GetRelAddressSwizzle = NV40VPGetAddressRegSwizzle; + + shader->SupportsConditional = NV40VPSupportsConditional; + shader->GetConditionUpdate = NV40VPGetConditionUpdate; + shader->GetConditionTest = NV40VPGetConditionTest; + shader->GetCondition = NV40VPGetCondition; + shader->GetCondRegSwizzle = NV40VPGetCondRegSwizzle; + shader->GetCondRegID = NV40VPGetCondRegID; + + shader->GetBranch = NV40VPGetBranch; +} diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c new file mode 100644 index 00000000000..818e268615c --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -0,0 +1,641 @@ +/************************************************************************** + +Copyright 2006 Nouveau +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_state.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv50AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF, 2); + OUT_RING_CACHE(ubRef); + OUT_RING_CACHE(func); +} + +static void nv50BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB, 1); + OUT_RING_CACHE(modeRGB); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA, 1); + OUT_RING_CACHE(modeA); +} + + +static void nv50BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB, 2); + OUT_RING_CACHE(sfactorRGB); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorRGB); /* FIXME, sometimes has |0x4000 */ + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA, 2); + OUT_RING_CACHE(sfactorA); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorA); /* FIXME, sometimes has |0x4000 */ +} + +static void nv50Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint hw_bufs = 0; + + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) + hw_bufs |= 0x3c; + if (mask & (BUFFER_BIT_STENCIL)) + hw_bufs |= 0x02; + if (mask & (BUFFER_BIT_DEPTH)) + hw_bufs |= 0x01; + + if (hw_bufs) { + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS, 1); + OUT_RING(hw_bufs); + } +} + +static void nv50ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH, 1); + OUT_RING_CACHEf(d); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv50ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL, 1); + OUT_RING_CACHE(s); +} + +static void nv50ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* Only using shaders */ +} + +static void nv50ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_COLOR_MASK(0), 8); + for (i=0; i<8; i++) { + OUT_RING_CACHE(((amask && 0x01) << 12) | ((bmask && 0x01) << 8) | ((gmask && 0x01)<< 4) | ((rmask && 0x01) << 0)); + } +} + +static void nv50ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv50CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv50DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv50DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: +// case GL_BLEND: +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_DITHER: +// case GL_FOG: +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: + case GL_LINE_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_LINE_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: + case GL_SCISSOR_TEST: + /* No enable bit, nv50Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + OUT_RING_CACHE(state); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv50Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* Only using shaders */ +} + +static void nv50Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +static void nv50Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + /* Only with shaders */ +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv50LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 8) | factor); +} + +static void nv50LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHEf(width); +} + +static void nv50LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv50PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv50PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); +} + +/** Select a polygon rasterization mode */ +static void nv50PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv50PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 1); + OUT_RING_CACHEf(factor); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS, 1); + OUT_RING_CACHEf(units); +} + +/** Set the polygon stippling pattern */ +static void nv50PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 8191; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING_CACHE(((w) << 16) | x); + OUT_RING_CACHE(((h) << 16) | y); +} + +/** Select flat or smooth shading */ +static void nv50ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv50StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 1); + OUT_RING_CACHE(func); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF, 1); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 2); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv50StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv50StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + /* Only with shaders */ +} + +static void nv50WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE((8191 << 16) | 0); + OUT_RING_CACHE((8191 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + OUT_RING_CACHE(0); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +static GLboolean nv50InitCard(nouveauContextPtr nmesa) +{ + int i,j; + + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, 0x1558, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1(0), 8); + for (i=0; i<8; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0(0), 12); + for (i=0; i<12; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, 0x121c, 1); + OUT_RING(1); + + for (i=0; i<8; i++) { + BEGIN_RING_SIZE(NvSub3D, 0x0200 + (i*0x20), 5); + for (j=0; j<5; j++) { + OUT_RING(0); + } + } + + BEGIN_RING_SIZE(NvSub3D, 0x0fe0, 5); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x16); + OUT_RING(0); + OUT_RING(0); + + return GL_FALSE; +} + +static GLboolean nv50BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_FALSE; +} + +void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv50AlphaFunc; + func->BlendColor = nv50BlendColor; + func->BlendEquationSeparate = nv50BlendEquationSeparate; + func->BlendFuncSeparate = nv50BlendFuncSeparate; + func->Clear = nv50Clear; + func->ClearColor = nv50ClearColor; + func->ClearDepth = nv50ClearDepth; + func->ClearStencil = nv50ClearStencil; + func->ClipPlane = nv50ClipPlane; + func->ColorMask = nv50ColorMask; + func->ColorMaterial = nv50ColorMaterial; + func->CullFace = nv50CullFace; + func->FrontFace = nv50FrontFace; + func->DepthFunc = nv50DepthFunc; + func->DepthMask = nv50DepthMask; + func->DepthRange = nv50DepthRange; + func->Enable = nv50Enable; + func->Fogfv = nv50Fogfv; + func->Hint = nv50Hint; + func->Lightfv = nv50Lightfv; +/* func->LightModelfv = nv50LightModelfv; */ + func->LineStipple = nv50LineStipple; + func->LineWidth = nv50LineWidth; + func->LogicOpcode = nv50LogicOpcode; + func->PointParameterfv = nv50PointParameterfv; + func->PointSize = nv50PointSize; + func->PolygonMode = nv50PolygonMode; + func->PolygonOffset = nv50PolygonOffset; + func->PolygonStipple = nv50PolygonStipple; +/* func->ReadBuffer = nv50ReadBuffer; */ +/* func->RenderMode = nv50RenderMode; */ + func->Scissor = nv50Scissor; + func->ShadeModel = nv50ShadeModel; + func->StencilFuncSeparate = nv50StencilFuncSeparate; + func->StencilMaskSeparate = nv50StencilMaskSeparate; + func->StencilOpSeparate = nv50StencilOpSeparate; +/* func->TexGen = nv50TexGen; */ +/* func->TexParameter = nv50TexParameter; */ + func->TextureMatrix = nv50TextureMatrix; + + nmesa->hw_func.InitCard = nv50InitCard; + nmesa->hw_func.BindBuffers = nv50BindBuffers; + nmesa->hw_func.WindowMoved = nv50WindowMoved; +} diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index 8ec027542ad..89ddafa02a5 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -235,7 +235,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -293,7 +293,7 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); if ( release_texture_heaps ) { diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 1bfd3709377..e476afa5d82 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1250,7 +1250,7 @@ static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); R128_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 75c09ff867e..e9144ac75ce 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -26,10 +26,6 @@ DRIVER_SOURCES = r200_context.c \ r200_span.c \ r200_maos.c \ r200_sanity.c \ - r200_vtxfmt.c \ - r200_vtxfmt_c.c \ - r200_vtxfmt_sse.c \ - r200_vtxfmt_x86.c \ r200_fragshader.c \ r200_vertprog.c \ radeon_screen.c \ @@ -37,7 +33,7 @@ DRIVER_SOURCES = r200_context.c \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -X86_SOURCES = r200_vtxtmp_x86.S +X86_SOURCES = DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200 diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index bb7a16c9327..fc6eb93daa8 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -45,7 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" #include "r200_swtcl.h" #include "r200_tcl.h" -#include "r200_vtxfmt.h" #include "r200_maos.h" #include "r200_vertprog.h" @@ -415,7 +414,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -424,11 +423,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, r200_pipeline ); - ctx->Driver.FlushVertices = r200FlushVertices; /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and TNL to match hardware characteristics: @@ -533,12 +531,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); } - if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); - } return GL_TRUE; } @@ -568,7 +560,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); r200DestroySwtcl( rmesa->glCtx ); @@ -579,12 +571,6 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) r200FlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtDestroy( rmesa->glCtx ); - } - if (rmesa->state.scissor.pClipRects) { FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = NULL; @@ -700,9 +686,6 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - r200VtxfmtMakeCurrent( newCtx->glCtx ); - _mesa_update_state( newCtx->glCtx ); r200ValidateState( newCtx->glCtx ); @@ -727,6 +710,5 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv ) if (R200_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx); - r200VtxfmtUnbindContext( rmesa->glCtx ); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index fa38a78e263..e840a502c0b 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -107,8 +107,7 @@ struct r200_vertex_program { VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6]; int pos_end; int inputs[VERT_ATTRIB_MAX]; - int rev_inputs[16]; - int gen_inputs_mapped; + GLubyte inputmap_rev[16]; int native; int fogpidx; int fogmode; @@ -724,8 +723,6 @@ struct r200_store { /* r200_tcl.c */ struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* hw can handle 12 components max */ @@ -735,13 +732,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; - struct r200_dma_region generic[16]; + struct r200_dma_region vertex_data[15]; }; @@ -811,87 +802,6 @@ struct r200_ioctl { #define R200_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; - struct dynfn FogCoordfEXT; - struct dynfn FogCoordfvEXT; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, const int * ); - struct dynfn *(*Vertex2fv)( GLcontext *, const int * ); - struct dynfn *(*Vertex3f)( GLcontext *, const int * ); - struct dynfn *(*Vertex3fv)( GLcontext *, const int * ); - struct dynfn *(*Color4ub)( GLcontext *, const int * ); - struct dynfn *(*Color4ubv)( GLcontext *, const int * ); - struct dynfn *(*Color3ub)( GLcontext *, const int * ); - struct dynfn *(*Color3ubv)( GLcontext *, const int * ); - struct dynfn *(*Color4f)( GLcontext *, const int * ); - struct dynfn *(*Color4fv)( GLcontext *, const int * ); - struct dynfn *(*Color3f)( GLcontext *, const int * ); - struct dynfn *(*Color3fv)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * ); - struct dynfn *(*Normal3f)( GLcontext *, const int * ); - struct dynfn *(*Normal3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1fv)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfEXT)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfvEXT)( GLcontext *, const int * ); -}; - - struct r200_prim { GLuint start; @@ -912,43 +822,6 @@ struct r200_prim { #define R200_MAX_VERTEX_SIZE ((3*6)+11) -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; r200_color_t color; } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - GLfloat *fogptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - struct r200_context { GLcontext *glCtx; /* Mesa context */ @@ -1040,10 +913,6 @@ struct r200_context { */ struct r200_swtcl_info swtcl; - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; - /* Mirrors of some DRI state */ struct r200_dri_mirror dri; diff --git a/src/mesa/drivers/dri/r200/r200_maos.h b/src/mesa/drivers/dri/r200/r200_maos.h index b9e4d3c2392..4998f67445c 100644 --- a/src/mesa/drivers/dri/r200/r200_maos.h +++ b/src/mesa/drivers/dri/r200/r200_maos.h @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" -extern void r200EmitArrays( GLcontext *ctx, GLuint inputs ); +extern void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ); extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); #endif diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 39c1f68911f..6a6c30a2b0d 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -376,7 +376,7 @@ static void emit_vector( GLcontext *ctx, /* Emit any changed arrays to new GART memory, re-emit a packet to * update the arrays. */ -void r200EmitArrays( GLcontext *ctx, GLuint inputs ) +void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; @@ -384,318 +384,130 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint nr = 0; GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; - GLuint i; - GLuint generic_in_mapped = 0; - struct r200_vertex_program *vp = NULL; - - /* this looks way more complicated than necessary... */ - if (ctx->VertexProgram._Enabled) { - vp = rmesa->curr_vp_hw; - generic_in_mapped = vp->gen_inputs_mapped; - } - - if (inputs & VERT_BIT_POS) { - if (!rmesa->tcl.obj.buf) - emit_vector( ctx, - &rmesa->tcl.obj, - (char *)VB->ObjPtr->data, - VB->ObjPtr->size, - VB->ObjPtr->stride, - count); - - switch( VB->ObjPtr->size ) { - case 4: vfmt0 |= R200_VTX_W0; - case 3: vfmt0 |= R200_VTX_Z0; - case 2: - default: - break; - } - component[nr++] = &rmesa->tcl.obj; - } - else if (generic_in_mapped & (1 << 0)) { - int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - } - - if (inputs & VERT_BIT_NORMAL) { - if (!rmesa->tcl.norm.buf) - emit_vector( ctx, - &(rmesa->tcl.norm), - (char *)VB->NormalPtr->data, - 3, - VB->NormalPtr->stride, - count); - - vfmt0 |= R200_VTX_N0; - component[nr++] = &rmesa->tcl.norm; - } - - if (inputs & VERT_BIT_FOG) { - if (!rmesa->tcl.fog.buf) { - if (ctx->VertexProgram._Enabled) - emit_vector( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, + GLuint i, emitsize; + + for ( i = 0; i < 15; i++ ) { + GLubyte attrib = vimap_rev[i]; + if (attrib != 255) { + switch (i) { + case 0: + emitsize = (VB->AttribPtr[attrib]->size); + switch (emitsize) { + case 4: + vfmt0 |= R200_VTX_W0; + /* fallthrough */ + case 3: + vfmt0 |= R200_VTX_Z0; + break; + case 2: + break; + default: assert(0); + } + break; + case 1: + assert(attrib == VERT_ATTRIB_WEIGHT); + emitsize = (VB->AttribPtr[attrib]->size); + vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT; + break; + case 2: + assert(attrib == VERT_ATTRIB_NORMAL); + emitsize = 3; + vfmt0 |= R200_VTX_N0; + break; + case 3: + /* special handling to fix up fog. Will get us into trouble with vbos...*/ + assert(attrib == VERT_ATTRIB_FOG); + if (!rmesa->tcl.vertex_data[i].buf) { + if (ctx->VertexProgram._Enabled) + emit_vector( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, 1, - VB->FogCoordPtr->stride, + VB->AttribPtr[attrib]->stride, count); - else - emit_vecfog( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, - VB->FogCoordPtr->stride, + else + emit_vecfog( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, + VB->AttribPtr[attrib]->stride, count); - } - - vfmt0 |= R200_VTX_DISCRETE_FOG; - component[nr++] = &rmesa->tcl.fog; - } - - if (inputs & VERT_BIT_COLOR0) { - int emitsize; - - if (VB->ColorPtr[0]->size == 4 && - (VB->ColorPtr[0]->stride != 0 || - VB->ColorPtr[0]->data[0][3] != 1.0)) { - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - emitsize = 4; - } - else { - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; - emitsize = 3; - } - - if (!rmesa->tcl.rgba.buf) - emit_vector( ctx, - &(rmesa->tcl.rgba), - (char *)VB->ColorPtr[0]->data, - emitsize, - VB->ColorPtr[0]->stride, - count); - - component[nr++] = &rmesa->tcl.rgba; - } -/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - emit_ubyte_rgba( ctx, &rmesa->tcl.rgba, - (char *)VB->ColorPtr[0]->data, 4, - VB->ColorPtr[0]->stride, count);*/ - else if (generic_in_mapped & (1 << 2)) { - int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - } - - - if (inputs & VERT_BIT_COLOR1) { - if (!rmesa->tcl.spec.buf) { - emit_vector( ctx, - &rmesa->tcl.spec, - (char *)VB->SecondaryColorPtr[0]->data, - 3, - VB->SecondaryColorPtr[0]->stride, - count); - } - - /* How does this work? - */ - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT; - component[nr++] = &rmesa->tcl.spec; - } - else if (generic_in_mapped & (1 << 3)) { - int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT; - } - - if (generic_in_mapped & (1 << 4)) { - int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT; - } - - if (generic_in_mapped & (1 << 5)) { - int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT; - } - - for ( i = 0 ; i < 6 ; i++ ) { - if (inputs & (VERT_BIT_TEX0 << i)) { - if (!rmesa->tcl.tex[i].buf) - emit_vector( ctx, - &(rmesa->tcl.tex[i]), - (char *)VB->TexCoordPtr[i]->data, - VB->TexCoordPtr[i]->size, - VB->TexCoordPtr[i]->stride, - count ); - - vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3); - component[nr++] = &rmesa->tcl.tex[i]; - } - else if (generic_in_mapped & (1 << (i + 6))) { - int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3)); - } - } - - if (generic_in_mapped & (1 << 13)) { - int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - } - -/* doesn't work. Wrong order with mixed generic & conventional! */ -/* - if (ctx->VertexProgram._Enabled) { - int *vp_inputs = rmesa->curr_vp_hw->inputs; - for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) { - if (inputs & (1 << i)) { - int geninput = i - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[i]->data, - 4, - VB->AttribPtr[i]->stride, - count ); } - component[nr++] = &rmesa->tcl.generic[geninput]; - switch (vp_inputs[i]) { - case 0: - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - break; + vfmt0 |= R200_VTX_DISCRETE_FOG; + goto after_emit; + break; + case 4: + case 5: + case 6: + case 7: + if (VB->AttribPtr[attrib]->size == 4 && + (VB->AttribPtr[attrib]->stride != 0 || + VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4; + else emitsize = 3; + if (emitsize == 4) + vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + else { + vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + } + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + emitsize = VB->AttribPtr[attrib]->size; + vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3); + break; + case 14: + emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2; + switch (emitsize) { case 2: + vfmt0 |= R200_VTX_XY1; + /* fallthrough */ case 3: + vfmt0 |= R200_VTX_Z1; + /* fallthrough */ case 4: - case 5: - vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2); - break; - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3); - break; - case 13: - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - break; - case 1: - case 12: - default: - assert(0); + vfmt0 |= R200_VTX_W1; + break; } + default: + assert(0); + } + if (!rmesa->tcl.vertex_data[i].buf) { + emit_vector( ctx, + &(rmesa->tcl.vertex_data[i]), + (char *)VB->AttribPtr[attrib]->data, + emitsize, + VB->AttribPtr[attrib]->stride, + count ); } +after_emit: + assert(nr < 12); + component[nr++] = &rmesa->tcl.vertex_data[i]; } } -*/ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); + vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { + R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0; rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; - } + } rmesa->tcl.nr_aos_components = nr; - rmesa->tcl.vertex_format = vfmt0; } void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) { - GLuint unit; r200ContextPtr rmesa = R200_CONTEXT( ctx ); -/* if (R200_DEBUG & DEBUG_VERTS) */ -/* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */ - - if (newinputs & VERT_BIT_POS) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); - - if (newinputs & VERT_BIT_NORMAL) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); - - if (newinputs & VERT_BIT_FOG) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR0) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR1) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (newinputs & VERT_BIT_TEX(unit)) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ ); - } - - if (ctx->VertexProgram._Enabled) { - int i; - for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { - if (newinputs & (1 << i)) - r200ReleaseDmaRegion( rmesa, - &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ ); - } + /* only do it for changed inputs ? */ + int i; + for (i = 0; i < 15; i++) { + if (newinputs & (1 << i)) + r200ReleaseDmaRegion( rmesa, + &rmesa->tcl.vertex_data[i], __FUNCTION__ ); } - } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index dc1fbef72ee..bdb487f2b93 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "framebuffer.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -54,7 +54,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "r200_vertprog.h" #include "drirenderbuffer.h" @@ -2536,23 +2535,24 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); R200_CONTEXT(ctx)->NewGLState |= new_state; - r200VtxfmtInvalidate( ctx ); } /* A hack. The r200 can actually cope just fine with materials - * between begin/ends, so fix this. But how ? + * between begin/ends, so fix this. + * Should map to inputs just like the generic vertex arrays for vertex progs. + * In theory there could still be too many and we'd still need a fallback. */ static GLboolean check_material( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLint i; - for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; - i < _TNL_ATTRIB_MAT_BACK_INDEXES; + for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; + i < _TNL_ATTRIB_MAT_BACK_INDEXES; i++) if (tnl->vb.AttribPtr[i] && tnl->vb.AttribPtr[i]->stride) @@ -2560,7 +2560,7 @@ static GLboolean check_material( GLcontext *ctx ) return GL_FALSE; } - + static void r200WrapRunPipeline( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -2574,7 +2574,7 @@ static void r200WrapRunPipeline( GLcontext *ctx ) if (rmesa->NewGLState) r200ValidateState( ctx ); - has_material = (ctx->Light.Enabled && check_material( ctx )); + has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx ); if (has_material) { TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE ); diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index d95a80c7bbc..b40d0bdcb7c 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -50,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index c14a275f7a3..25d229d8ed6 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -48,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" #include "r200_context.h" #include "r200_ioctl.h" @@ -936,13 +935,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, } -void r200FlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - R200_NEWPRIM( R200_CONTEXT( ctx ) ); -} /**********************************************************************/ /* Initialization. */ diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.h b/src/mesa/drivers/dri/r200/r200_swtcl.h index ce2b6b5f06b..ccf817988c5 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.h +++ b/src/mesa/drivers/dri/r200/r200_swtcl.h @@ -42,7 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void r200InitSwtcl( GLcontext *ctx ); extern void r200DestroySwtcl( GLcontext *ctx ); -extern void r200FlushVertices( GLcontext *ctx, GLuint flags ); extern void r200ChooseRenderState( GLcontext *ctx ); extern void r200ChooseVertexState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 86edf7132ce..e0c32b26d92 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "colormac.h" #include "light.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -384,8 +384,14 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint inputs = 0; GLuint i; + GLubyte *vimap_rev; +/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3, + color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use + more than 12 of those at the same time. */ + GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255}; + /* TODO: separate this from the swtnl pipeline */ @@ -404,30 +410,40 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ValidateState( ctx ); if (!ctx->VertexProgram._Enabled) { - inputs = VERT_BIT_POS | VERT_BIT_COLOR0; /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ + map_rev_fixed[0] = VERT_ATTRIB_POS; + /* technically there is no reason we always need VA_COLOR0. In theory + could disable it depending on lighting, color materials, texturing... */ + map_rev_fixed[4] = VERT_ATTRIB_COLOR0; + if (ctx->Light.Enabled) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } + /* this also enables VA_COLOR1 when using separate specular + lighting model, which is unnecessary. + FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses + the secondary color (if lighting is disabled). The chip seems + misconfigured for that though elsewhere (tcl output, might lock up) */ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - inputs |= VERT_BIT_COLOR1; + map_rev_fixed[5] = VERT_ATTRIB_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { - inputs |= VERT_BIT_FOG; + map_rev_fixed[3] = VERT_ATTRIB_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } - inputs |= VERT_BIT_TEX(i); + map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i; } } + vimap_rev = &map_rev_fixed[0]; } else { /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment @@ -437,14 +453,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, We only need to change compsel. */ GLuint out_compsel = 0; GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten; -#if 0 - /* can't handle other inputs, generic attribs etc. currently - should never arrive here */ - assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead & - ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 | - VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 | - VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0); -#endif - inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead; + + vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0]; assert(vp_out & (1 << VERT_RESULT_HPOS)); out_compsel = R200_OUTPUT_XYZW; if (vp_out & (1 << VERT_RESULT_COL0)) { @@ -473,7 +483,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, /* Do the actual work: */ r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); - r200EmitArrays( ctx, inputs ); + r200EmitArrays( ctx, vimap_rev ); rmesa->tcl.Elts = VB->Elts; diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 899e84caa0f..4960d481d5d 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -405,7 +405,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte int dofogfix = 0; int fog_temp_i = 0; int free_inputs; - int free_inputs_conv; int array_count = 0; vp->native = GL_FALSE; @@ -461,7 +460,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with base e isn't directly available neither. */ - if (mesa_vp->Base.OutputsWritten & VERT_RESULT_FOGC && !vp->fogpidx) { + if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) { struct gl_program_parameter_list *paramList; GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 }; paramList = mesa_vp->Base.Parameters; @@ -477,6 +476,8 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte for(i = 0; i < VERT_ATTRIB_MAX; i++) vp->inputs[i] = -1; + for(i = 0; i < 15; i++) + vp->inputmap_rev[i] = 255; free_inputs = 0x2ffd; /* fglrx uses fixed inputs as follows for conventional attribs. @@ -499,39 +500,45 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* may look different when using idx buf / input_route instead of se_vtx_fmt? */ if (mesa_vp->Base.InputsRead & VERT_BIT_POS) { vp->inputs[VERT_ATTRIB_POS] = 0; + vp->inputmap_rev[0] = VERT_ATTRIB_POS; free_inputs &= ~(1 << 0); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { - /* we don't actually handle that later. Then again, we don't have to... */ vp->inputs[VERT_ATTRIB_WEIGHT] = 12; + vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) { vp->inputs[VERT_ATTRIB_NORMAL] = 1; + vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) { vp->inputs[VERT_ATTRIB_COLOR0] = 2; + vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0; free_inputs &= ~(1 << 2); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) { vp->inputs[VERT_ATTRIB_COLOR1] = 3; + vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1; free_inputs &= ~(1 << 3); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) { vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++; + vp->inputmap_rev[3] = VERT_ATTRIB_FOG; + array_count++; } for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) { if (mesa_vp->Base.InputsRead & (1 << i)) { vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6; + vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i; free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6)); array_count++; } } - free_inputs_conv = free_inputs; /* using VERT_ATTRIB_TEX6/7 would be illegal */ /* completely ignore aliasing? */ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { @@ -550,13 +557,14 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte if (free_inputs & (1 << j)) { free_inputs &= ~(1 << j); vp->inputs[i] = j; - vp->rev_inputs[j] = i; + if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */ + else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */ + else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */ break; } } } } - vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv; if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { if (R200_DEBUG & DEBUG_FALLBACKS) { diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c deleted file mode 100644 index d73fbbafd5f..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c +++ /dev/null @@ -1,1234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.4 2003/05/06 23:52:08 daenzer Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "r200_context.h" -#include "r200_state.h" -#include "r200_ioctl.h" -#include "r200_tex.h" -#include "r200_tcl.h" -#include "r200_swtcl.h" -#include "r200_vtxfmt.h" - -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "dispatch.h" - -static void r200VtxFmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( r200ContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord3f", &rmesa->vb.dfn_cache.TexCoord3f ); - count_func( "TexCoord3fv", &rmesa->vb.dfn_cache.TexCoord3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord3fARB", &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - count_func( "MultiTexCoord3fvARB", &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT ); - count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - -static void r200NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - -void r200_copy_to_current( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - unsigned i; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) { - ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0]; - } - - switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) { - case R200_VTX_PK_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - break; - - case R200_VTX_FP_RGB: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - break; - - case R200_VTX_FP_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - break; - - default: - break; - } - - if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i ); - GLfloat * const src = rmesa->vb.texcoordptr[i]; - - if ( count != 0 ) { - switch( count ) { - case 3: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2]; - break; - case 2: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - case 1: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - } - - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( r200ContextPtr rmesa ) -{ - int i,j; - struct r200_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * - rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); - rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0; - rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1; - } - - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (R200_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end) - r200EmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( r200ContextPtr rmesa, GLuint mode ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = - rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( r200ContextPtr rmesa, GLuint flags ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = - rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == R200_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( r200ContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[R200_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2( nr, 2 ); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - r200VtxFmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList = _tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -/** - * \todo - * An interesting optimization of this function would be to have 3 element - * table with the dispatch offsets of the TexCoord?fv functions, use count - * to look-up the table, and a specialized version of GL_CALL that used the - * offset number instead of the name. - */ -static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) -{ - switch( count ) { - case 3: - CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 2: - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 1: - CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - default: - assert( count == 0 ); - break; - } -} - -void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind0 = rmesa->vb.vtxfmt_0; - GLuint ind1 = rmesa->vb.vtxfmt_1; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint count; - GLuint unit; - - if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - - if (ind0 & R200_VTX_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp[i][offset])); - offset++; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ubv(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, &tmp[i][offset] ); - offset += count; - } - - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind0 & R200_VTX_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa->vb.fogptr)); - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, - rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, - rmesa->vb.colorptr->alpha)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) { - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - } - else { - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] ); - } -} - - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - r200RefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (R200_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, - (void *)rmesa->vb.dmaptr); - if (R200_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - -/** - * Determines the hardware vertex format based on the current state vector. - * - * \returns - * If the hardware TCL unit is capable of handling the current state vector, - * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. - * - * \todo - * Make this color format selection data driven. If we receive only ubytes, - * send color as ubytes. Also check if converting (with free checking for - * overflow) is cheaper than sending floats directly. - * - * \todo - * When intializing texture coordinates, it might be faster to just copy the - * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that - * some of the data (i.e., the last texture coordinate components) get copied - * over, but that still may be faster than the conditional branching. If - * nothing else, the code will be smaller and easier to follow. - */ -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint ind0 = R200_VTX_Z0; - GLuint ind1 = 0; - GLuint i; - GLuint count[R200_MAX_TEXTURE_UNITS]; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)) || - /* TODO: set tcl out fmt/compsel and reenable vtxfmt code */ - ctx->VertexProgram._Enabled) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind0 |= R200_VTX_N0; - - if (ctx->Light.ColorMaterialEnabled) - ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - else - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - } - else { - /* TODO: make this data driven? - */ - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind0 |= R200_VTX_DISCRETE_FOG; - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - count[i] = 0; - - if (ctx->Texture.Unit[i]._ReallyEnabled) { - if (rmesa->TexGenNeedNormals[i]) { - ind0 |= R200_VTX_N0; - } - else { - switch( ctx->Texture.Unit[i]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - count[i] = 3; - break; - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - count[i] = 2; - break; - case TEXTURE_1D_BIT: - count[i] = 1; - break; - } - - ind1 |= count[i] << (3 * i); - } - } - } - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); - - R200_NEWPRIM(rmesa); - rmesa->vb.vtxfmt_0 = ind0; - rmesa->vb.vtxfmt_1 = ind1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.vertex_size = 3; - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3]; - rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4]; - rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5]; - rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind0 & R200_VTX_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 1; - rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 4; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - } - - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - if ( count[i] != 0 ) { - float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i]; - unsigned j; - - rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - - for ( j = 0 ; j < count[i] ; j++ ) { - rmesa->vb.texcoordptr[i][j] = attr[j]; - } - - rmesa->vb.vertex_size += count[i]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; - } - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - - -void r200VtxfmtInvalidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void r200VtxfmtValidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = r200VtxFmtFlushVertices; - ctx->Driver.NewList = r200NewList; - rmesa->vb.installed = GL_TRUE; - } - else if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void r200_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - r200UpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void r200_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - R200_NEWPRIM( rmesa ); - r200RefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void r200_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (R200_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) r200_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean r200NotifyBegin( GLcontext *ctx, GLenum p ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - r200_Begin( p ); - return GL_TRUE; -} - -static void r200VtxFmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - r200_copy_to_current( ctx ); - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( rmesa ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -/** - * Called once during context creation. - */ -void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - r200VtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = r200_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = r200_Begin; - vfmt->End = r200_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = r200_fallback_DrawArrays; - vfmt->DrawElements = r200_fallback_DrawElements; - vfmt->DrawRangeElements = r200_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = r200_fallback_CallList; - vfmt->CallLists = r200_fallback_CallLists; - vfmt->EvalCoord1f = r200_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = r200_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = r200_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = r200_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = r200_fallback_EvalMesh1; - vfmt->EvalMesh2 = r200_fallback_EvalMesh2; - vfmt->EvalPoint1 = r200_fallback_EvalPoint1; - vfmt->EvalPoint2 = r200_fallback_EvalPoint2; - vfmt->TexCoord4f = r200_fallback_TexCoord4f; - vfmt->TexCoord4fv = r200_fallback_TexCoord4fv; - vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = r200_fallback_Vertex4f; - vfmt->Vertex4fv = r200_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = r200_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = r200_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = r200_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = r200_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = r200_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = r200_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = r200_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = r200_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = r200_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = r200_fallback_FogCoordfvEXT; - - (void)r200_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT ); - make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ - - r200InitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - -void r200VtxfmtUnbindContext( GLcontext *ctx ) -{ -} - - -void r200VtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void r200VtxfmtDestroy( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT ); - free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.h b/src/mesa/drivers/dri/r200/r200_vtxfmt.h deleted file mode 100644 index 46999191e04..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.h +++ /dev/null @@ -1,123 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __R200_VTXFMT_H__ -#define __R200_VTXFMT_H__ - -#include "r200_context.h" - - - -extern void r200VtxfmtUpdate( GLcontext *ctx ); -extern void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void r200VtxfmtInvalidate( GLcontext *ctx ); -extern void r200VtxfmtDestroy( GLcontext *ctx ); -extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); -extern void r200VtxfmtUnbindContext( GLcontext *ctx ); - -extern void r200_copy_to_current( GLcontext *ctx ); -extern void VFMT_FALLBACK( const char *caller ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key[0] = key[0]; \ - dfn->key[1] = key[1]; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - /*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \ - /* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/ \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void r200InitX86Codegen( struct dfn_generators *gen ); -void r200InitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in r200_vtxfmt_x86.c - */ -struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * ); - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c deleted file mode 100644 index 1db5950c8ff..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "r200_vtxfmt.h" -#include "r200_tcl.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - - -/* Color for ubyte (packed) color formats: - */ -#if 0 -static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void r200_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void r200_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void r200_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void r200_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void r200_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void r200_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - - -/* Normal - */ -static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void r200_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* FogCoord - */ -static void r200_FogCoordfEXT( GLfloat f ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, f ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = f;*/ -} - -static void r200_FogCoordfvEXT( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, v[0] ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = v[0];*/ -} - - -/* TexCoord - */ - -/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ -static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_1D_BIT: - dest[0] = s; - } -} - -static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord2fARB(GET_DISPATCH(), (target, s, t)); - return; - } -} - -static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = r; - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord3fARB(GET_DISPATCH(), (target, s, t, r)); - return; - } -} - -static void r200_TexCoord1f(GLfloat s) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, s); -} - -static void r200_TexCoord2f(GLfloat s, GLfloat t) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t); -} - -static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r); -} - -static void r200_TexCoord1fv(const GLfloat *v) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]); -} - -static void r200_TexCoord2fv(const GLfloat *v) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]); -} - -static void r200_TexCoord3fv(const GLfloat *v) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]); -} - -static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord1fARB(target, v[0]); -} - -static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord2fARB(target, v[0], v[1]); -} - -static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]); -} - - -static struct dynfn *lookup( struct dynfn *l, const int *key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key[0] == key[0] && f->key[1] == key[1]) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, r200_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \ - SET_ ## FN (ctx->Exec, r200_##FN##_ub); \ - } \ - else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - r200_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, r200_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, r200_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \ - ? r200_##FN##_ub : r200_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - - - -/* VTXFMT_0 - */ -#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0) -#define MASK_NORM (MASK_XYZW|R200_VTX_N0) -#define MASK_FOG (MASK_NORM |R200_VTX_DISCRETE_FOG) -#define MASK_COLOR (MASK_FOG |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT)) -#define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT)) - -/* VTXFMT_1 - */ -#define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT) -/* FIXME: maybe something like in the radeon driver is needed here? */ - - -typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); -typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); -typedef void (*p2f)( GLfloat, GLfloat ); -typedef void (*p1f)( GLfloat ); -typedef void (*pe3f)( GLenum, GLfloat, GLfloat, GLfloat ); -typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); -typedef void (*pe1f)( GLenum, GLfloat ); -typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); -typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); -typedef void (*pfv)( const GLfloat * ); -typedef void (*pefv)( GLenum, const GLfloat * ); -typedef void (*pubv)( const GLubyte * ); - - -CHOOSE(Normal3f, p3f, MASK_NORM, 0, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Normal3fv, pfv, MASK_NORM, 0, - (const GLfloat *v), (v)) - -#if 0 -CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0, - (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) -CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0, - (const GLubyte *v), (v)) -CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0, - (const GLubyte *v), (v)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0, - (const GLubyte *v), (v)) -#endif - -CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0, - (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) -CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0, - (const GLfloat *v), (v)) -CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0, - (const GLfloat *v), (v)) - - -CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0, - (const GLfloat *v), (v)) - -CHOOSE(TexCoord3f, p3f, ~0, MASK_ST0, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(TexCoord3fv, pfv, ~0, MASK_ST0, - (const GLfloat *v), (v)) -CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0, - (const GLfloat *v), (v)) -CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0, - (GLfloat a), (a)) -CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0, - (const GLfloat *v), (v)) - -CHOOSE(MultiTexCoord3fARB, pe3f, ~0, ~0, - (GLenum u,GLfloat a,GLfloat b,GLfloat c), (u,a,b,c)) -CHOOSE(MultiTexCoord3fvARB, pefv, ~0, ~0, - (GLenum u,const GLfloat *v), (u,v)) -CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0, - (GLenum u,GLfloat a,GLfloat b), (u,a,b)) -CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0, - (GLenum u,const GLfloat *v), (u,v)) -CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0, - (GLenum u,GLfloat a), (u,a)) -CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0, - (GLenum u,const GLfloat *v), (u,v)) - -CHOOSE(Vertex3f, p3f, ~0, ~0, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Vertex3fv, pfv, ~0, ~0, - (const GLfloat *v), (v)) -CHOOSE(Vertex2f, p2f, ~0, ~0, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(Vertex2fv, pfv, ~0, ~0, - (const GLfloat *v), (v)) - -CHOOSE(FogCoordfEXT, p1f, MASK_FOG, ~0, - (GLfloat f), (f)) -CHOOSE(FogCoordfvEXT, pfv, MASK_FOG, ~0, - (const GLfloat *f), (f)) - - - - -void r200VtxfmtInitChoosers( GLvertexformat *vfmt ) -{ - vfmt->Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->TexCoord3f = choose_TexCoord3f; - vfmt->TexCoord3fv = choose_TexCoord3fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; -/* vfmt->FogCoordfEXT = choose_FogCoordfEXT; - vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;*/ - - /* TODO: restore ubyte colors to vtxfmt. - */ -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, const int *key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - - gen->TexCoord3f = codegen_noop; - gen->TexCoord3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - - gen->MultiTexCoord3fARB = codegen_noop; - gen->MultiTexCoord3fvARB = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; -/* gen->FogCoordfEXT = codegen_noop; - gen->FogCoordfvEXT = codegen_noop;*/ - - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - r200InitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - r200InitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c deleted file mode 100644 index 5901730494a..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c +++ /dev/null @@ -1,234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) r200_makeSSENormal3fv; - gen->Normal3f = (void *) r200_makeSSENormal3f; - gen->Color3fv = (void *) r200_makeSSEColor3fv; - gen->Color3f = (void *) r200_makeSSEColor3f; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) r200_makeSSETexCoord2f; - gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c deleted file mode 100644 index b78a55c31f6..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -r200_makeX86Attribute3fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute3f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) -{ - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, - const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = r200_makeX86Vertex3f; - gen->Vertex3fv = r200_makeX86Vertex3fv; - gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = r200_makeX86Normal3f; - gen->Normal3fv = r200_makeX86Normal3fv; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2f = r200_makeX86TexCoord2f; - gen->TexCoord2fv = r200_makeX86TexCoord2fv; - gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = r200_makeX86Color3f; - gen->Color3fv = r200_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = r200_makeX86Vertex2f; */ -/* gen->Vertex2fv = r200_makeX86Vertex2fv; */ -/* gen->Color3ub = r200_makeX86Color3ub; */ -/* gen->Color3ubv = r200_makeX86Color3ubv; */ -/* gen->Color4f = r200_makeX86Color4f; */ -/* gen->Color4fv = r200_makeX86Color4fv; */ -/* gen->TexCoord1f = r200_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S deleted file mode 100644 index 5e33c7bdeea..00000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S +++ /dev/null @@ -1,499 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.2 2002/11/07 18:31:59 tsi Exp $ */ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* \todo: change the "and $7, %eax" to something like "target & 4 ? target & 5 : target & 3)" */ -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $7, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $7,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $7, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $7,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 5abb91d9876..2ee23289341 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -90,9 +90,11 @@ COMMON_SYMLINKS = \ include ../Makefile.template -$(SYMLINKS): +server: mkdir -p server - for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done + +$(SYMLINKS): server + @[ -e $@ ] || ln -sf ../../radeon/$@ server/ $(COMMON_SYMLINKS): @[ -e $@ ] || ln -sf ../radeon/$@ ./ diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h deleted file mode 100644 index a06d7152d78..00000000000 --- a/src/mesa/drivers/dri/r300/r200_context.h +++ /dev/null @@ -1,822 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __R200_CONTEXT_H__ -#define __R200_CONTEXT_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "tnl/t_vertex.h" -#include "drm.h" -#include "radeon_drm.h" -#include "dri_util.h" -#include "texmem.h" - -#include "macros.h" -#include "mtypes.h" -#include "colormac.h" -#include "r200_reg.h" -#include "radeon_context.h" - -#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */ - -struct r200_context; -typedef struct r200_context r200ContextRec; -typedef struct r200_context *r200ContextPtr; - -#include "mm.h" - -/* The blit width for texture uploads - */ -#define BLIT_WIDTH_BYTES 1024 - -/* Use the templated vertex format: - */ -#define COLOR_IS_RGBA -#define TAG(x) r200##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -typedef void (*r200_tri_func) (r200ContextPtr, - r200Vertex *, r200Vertex *, r200Vertex *); - -typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *); - -typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *); - -struct r200_depthbuffer_state { - GLfloat scale; -}; - -struct r200_stencilbuffer_state { - GLboolean hwBuffer; - GLuint clear; /* rb3d_stencilrefmask value */ -}; - -struct r200_stipple_state { - GLuint mask[32]; -}; - -typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; - -/* Texture object in locally shared texture space. - */ -struct r200_tex_obj { - driTextureObject base; - - GLuint bufAddr; /* Offset to start of locally - shared texture block */ - - GLuint dirty_state; /* Flags (1 per texunit) for - whether or not this texobj - has dirty hardware state - (pp_*) that needs to be - brought into the - texunit. */ - - drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; - /* Six, for the cube faces */ - - GLuint pp_txfilter; /* hardware register values */ - GLuint pp_txformat; - GLuint pp_txformat_x; - GLuint pp_txoffset; /* Image location in texmem. - All cube faces follow. */ - GLuint pp_txsize; /* npot only */ - GLuint pp_txpitch; /* npot only */ - GLuint pp_border_color; - GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ - - GLboolean border_fallback; -}; - -struct r200_texture_env_state { - r200TexObjPtr texobj; - GLenum format; - GLenum envMode; -}; - -#define R200_MAX_TEXTURE_UNITS 6 - -struct r200_texture_state { - struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS]; -}; - -struct r200_state_atom { - struct r200_state_atom *next, *prev; - const char *name; /* for debug */ - int cmd_size; /* size in bytes */ - GLuint idx; - int *cmd; /* one or more cmd's */ - int *lastcmd; /* one or more cmd's */ - int *savedcmd; /* one or more cmd's */ - GLboolean dirty; - GLboolean(*check) (GLcontext *, int); /* is this state active? */ -}; - -/* Trying to keep these relatively short as the variables are becoming - * extravagently long. Drop the driver name prefix off the front of - * everything - I think we know which driver we're in by now, and keep the - * prefix to 3 letters unless absolutely impossible. - */ - -#define CTX_CMD_0 0 -#define CTX_PP_MISC 1 -#define CTX_PP_FOG_COLOR 2 -#define CTX_RE_SOLID_COLOR 3 -#define CTX_RB3D_BLENDCNTL 4 -#define CTX_RB3D_DEPTHOFFSET 5 -#define CTX_RB3D_DEPTHPITCH 6 -#define CTX_RB3D_ZSTENCILCNTL 7 -#define CTX_CMD_1 8 -#define CTX_PP_CNTL 9 -#define CTX_RB3D_CNTL 10 -#define CTX_RB3D_COLOROFFSET 11 -#define CTX_CMD_2 12 /* why */ -#define CTX_RB3D_COLORPITCH 13 /* why */ -#define CTX_STATE_SIZE_OLDDRM 14 -#define CTX_CMD_3 14 -#define CTX_RB3D_BLENDCOLOR 15 -#define CTX_RB3D_ABLENDCNTL 16 -#define CTX_RB3D_CBLENDCNTL 17 -#define CTX_STATE_SIZE_NEWDRM 18 - -#define SET_CMD_0 0 -#define SET_SE_CNTL 1 -#define SET_RE_CNTL 2 /* replace se_coord_fmt */ -#define SET_STATE_SIZE 3 - -#define VTE_CMD_0 0 -#define VTE_SE_VTE_CNTL 1 -#define VTE_STATE_SIZE 2 - -#define LIN_CMD_0 0 -#define LIN_RE_LINE_PATTERN 1 -#define LIN_RE_LINE_STATE 2 -#define LIN_CMD_1 3 -#define LIN_SE_LINE_WIDTH 4 -#define LIN_STATE_SIZE 5 - -#define MSK_CMD_0 0 -#define MSK_RB3D_STENCILREFMASK 1 -#define MSK_RB3D_ROPCNTL 2 -#define MSK_RB3D_PLANEMASK 3 -#define MSK_STATE_SIZE 4 - -#define VPT_CMD_0 0 -#define VPT_SE_VPORT_XSCALE 1 -#define VPT_SE_VPORT_XOFFSET 2 -#define VPT_SE_VPORT_YSCALE 3 -#define VPT_SE_VPORT_YOFFSET 4 -#define VPT_SE_VPORT_ZSCALE 5 -#define VPT_SE_VPORT_ZOFFSET 6 -#define VPT_STATE_SIZE 7 - -#define ZBS_CMD_0 0 -#define ZBS_SE_ZBIAS_FACTOR 1 -#define ZBS_SE_ZBIAS_CONSTANT 2 -#define ZBS_STATE_SIZE 3 - -#define MSC_CMD_0 0 -#define MSC_RE_MISC 1 -#define MSC_STATE_SIZE 2 - -#define TAM_CMD_0 0 -#define TAM_DEBUG3 1 -#define TAM_STATE_SIZE 2 - -#define TEX_CMD_0 0 -#define TEX_PP_TXFILTER 1 /*2c00 */ -#define TEX_PP_TXFORMAT 2 /*2c04 */ -#define TEX_PP_TXFORMAT_X 3 /*2c08 */ -#define TEX_PP_TXSIZE 4 /*2c0c */ -#define TEX_PP_TXPITCH 5 /*2c10 */ -#define TEX_PP_BORDER_COLOR 6 /*2c14 */ -#define TEX_CMD_1 7 -#define TEX_PP_TXOFFSET 8 /*2d00 */ -#define TEX_STATE_SIZE 9 - -#define CUBE_CMD_0 0 /* 1 register follows */ -#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */ -#define CUBE_CMD_1 2 /* 5 registers follow */ -#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */ -#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */ -#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */ -#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */ -#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */ -#define CUBE_STATE_SIZE 8 - -#define PIX_CMD_0 0 -#define PIX_PP_TXCBLEND 1 -#define PIX_PP_TXCBLEND2 2 -#define PIX_PP_TXABLEND 3 -#define PIX_PP_TXABLEND2 4 -#define PIX_STATE_SIZE 5 - -#define TF_CMD_0 0 -#define TF_TFACTOR_0 1 -#define TF_TFACTOR_1 2 -#define TF_TFACTOR_2 3 -#define TF_TFACTOR_3 4 -#define TF_TFACTOR_4 5 -#define TF_TFACTOR_5 6 -#define TF_STATE_SIZE 7 - -#define TCL_CMD_0 0 -#define TCL_LIGHT_MODEL_CTL_0 1 -#define TCL_LIGHT_MODEL_CTL_1 2 -#define TCL_PER_LIGHT_CTL_0 3 -#define TCL_PER_LIGHT_CTL_1 4 -#define TCL_PER_LIGHT_CTL_2 5 -#define TCL_PER_LIGHT_CTL_3 6 -#define TCL_CMD_1 7 -#define TCL_UCP_VERT_BLEND_CTL 8 -#define TCL_STATE_SIZE 9 - -#define MSL_CMD_0 0 -#define MSL_MATRIX_SELECT_0 1 -#define MSL_MATRIX_SELECT_1 2 -#define MSL_MATRIX_SELECT_2 3 -#define MSL_MATRIX_SELECT_3 4 -#define MSL_MATRIX_SELECT_4 5 -#define MSL_STATE_SIZE 6 - -#define TCG_CMD_0 0 -#define TCG_TEX_PROC_CTL_2 1 -#define TCG_TEX_PROC_CTL_3 2 -#define TCG_TEX_PROC_CTL_0 3 -#define TCG_TEX_PROC_CTL_1 4 -#define TCG_TEX_CYL_WRAP_CTL 5 -#define TCG_STATE_SIZE 6 - -#define MTL_CMD_0 0 -#define MTL_EMMISSIVE_RED 1 -#define MTL_EMMISSIVE_GREEN 2 -#define MTL_EMMISSIVE_BLUE 3 -#define MTL_EMMISSIVE_ALPHA 4 -#define MTL_AMBIENT_RED 5 -#define MTL_AMBIENT_GREEN 6 -#define MTL_AMBIENT_BLUE 7 -#define MTL_AMBIENT_ALPHA 8 -#define MTL_DIFFUSE_RED 9 -#define MTL_DIFFUSE_GREEN 10 -#define MTL_DIFFUSE_BLUE 11 -#define MTL_DIFFUSE_ALPHA 12 -#define MTL_SPECULAR_RED 13 -#define MTL_SPECULAR_GREEN 14 -#define MTL_SPECULAR_BLUE 15 -#define MTL_SPECULAR_ALPHA 16 -#define MTL_CMD_1 17 -#define MTL_SHININESS 18 -#define MTL_STATE_SIZE 19 - -#define VAP_CMD_0 0 -#define VAP_SE_VAP_CNTL 1 -#define VAP_STATE_SIZE 2 - -/* Replaces a lot of packet info from radeon - */ -#define VTX_CMD_0 0 -#define VTX_VTXFMT_0 1 -#define VTX_VTXFMT_1 2 -#define VTX_TCL_OUTPUT_VTXFMT_0 3 -#define VTX_TCL_OUTPUT_VTXFMT_1 4 -#define VTX_CMD_1 5 -#define VTX_TCL_OUTPUT_COMPSEL 6 -#define VTX_CMD_2 7 -#define VTX_STATE_CNTL 8 -#define VTX_STATE_SIZE 9 - -#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\ - R200_VTX_COLOR_MASK) - -/** - * Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine - * how many components are in texture coordinate \c n. - */ -#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07) - -#define MAT_CMD_0 0 -#define MAT_ELT_0 1 -#define MAT_STATE_SIZE 17 - -#define GRD_CMD_0 0 -#define GRD_VERT_GUARD_CLIP_ADJ 1 -#define GRD_VERT_GUARD_DISCARD_ADJ 2 -#define GRD_HORZ_GUARD_CLIP_ADJ 3 -#define GRD_HORZ_GUARD_DISCARD_ADJ 4 -#define GRD_STATE_SIZE 5 - -/* position changes frequently when lighting in modelpos - separate - * out to new state item? - */ -#define LIT_CMD_0 0 -#define LIT_AMBIENT_RED 1 -#define LIT_AMBIENT_GREEN 2 -#define LIT_AMBIENT_BLUE 3 -#define LIT_AMBIENT_ALPHA 4 -#define LIT_DIFFUSE_RED 5 -#define LIT_DIFFUSE_GREEN 6 -#define LIT_DIFFUSE_BLUE 7 -#define LIT_DIFFUSE_ALPHA 8 -#define LIT_SPECULAR_RED 9 -#define LIT_SPECULAR_GREEN 10 -#define LIT_SPECULAR_BLUE 11 -#define LIT_SPECULAR_ALPHA 12 -#define LIT_POSITION_X 13 -#define LIT_POSITION_Y 14 -#define LIT_POSITION_Z 15 -#define LIT_POSITION_W 16 -#define LIT_DIRECTION_X 17 -#define LIT_DIRECTION_Y 18 -#define LIT_DIRECTION_Z 19 -#define LIT_DIRECTION_W 20 -#define LIT_ATTEN_QUADRATIC 21 -#define LIT_ATTEN_LINEAR 22 -#define LIT_ATTEN_CONST 23 -#define LIT_ATTEN_XXX 24 -#define LIT_CMD_1 25 -#define LIT_SPOT_DCD 26 -#define LIT_SPOT_DCM 27 -#define LIT_SPOT_EXPONENT 28 -#define LIT_SPOT_CUTOFF 29 -#define LIT_SPECULAR_THRESH 30 -#define LIT_RANGE_CUTOFF 31 /* ? */ -#define LIT_ATTEN_CONST_INV 32 -#define LIT_STATE_SIZE 33 - -/* Fog - */ -#define FOG_CMD_0 0 -#define FOG_R 1 -#define FOG_C 2 -#define FOG_D 3 -#define FOG_PAD 4 -#define FOG_STATE_SIZE 5 - -/* UCP - */ -#define UCP_CMD_0 0 -#define UCP_X 1 -#define UCP_Y 2 -#define UCP_Z 3 -#define UCP_W 4 -#define UCP_STATE_SIZE 5 - -/* GLT - Global ambient - */ -#define GLT_CMD_0 0 -#define GLT_RED 1 -#define GLT_GREEN 2 -#define GLT_BLUE 3 -#define GLT_ALPHA 4 -#define GLT_STATE_SIZE 5 - -/* EYE - */ -#define EYE_CMD_0 0 -#define EYE_X 1 -#define EYE_Y 2 -#define EYE_Z 3 -#define EYE_RESCALE_FACTOR 4 -#define EYE_STATE_SIZE 5 - -/* CST - constant state - */ -#define CST_CMD_0 0 -#define CST_PP_CNTL_X 1 -#define CST_CMD_1 2 -#define CST_RB3D_DEPTHXY_OFFSET 3 -#define CST_CMD_2 4 -#define CST_RE_AUX_SCISSOR_CNTL 5 -#define CST_CMD_3 6 -#define CST_RE_SCISSOR_TL_0 7 -#define CST_RE_SCISSOR_BR_0 8 -#define CST_CMD_4 9 -#define CST_SE_VAP_CNTL_STATUS 10 -#define CST_CMD_5 11 -#define CST_RE_POINTSIZE 12 -#define CST_CMD_6 13 -#define CST_SE_TCL_INPUT_VTX_0 14 -#define CST_SE_TCL_INPUT_VTX_1 15 -#define CST_SE_TCL_INPUT_VTX_2 16 -#define CST_SE_TCL_INPUT_VTX_3 17 -#define CST_STATE_SIZE 18 - -struct r200_hw_state { - /* Head of the linked list of state atoms. */ - struct r200_state_atom atomlist; - - /* Hardware state, stored as cmdbuf commands: - * -- Need to doublebuffer for - * - reviving state after loss of context - * - eliding noop statechange loops? (except line stipple count) - */ - struct r200_state_atom ctx; - struct r200_state_atom set; - struct r200_state_atom vte; - struct r200_state_atom lin; - struct r200_state_atom msk; - struct r200_state_atom vpt; - struct r200_state_atom vap; - struct r200_state_atom vtx; - struct r200_state_atom tcl; - struct r200_state_atom msl; - struct r200_state_atom tcg; - struct r200_state_atom msc; - struct r200_state_atom cst; - struct r200_state_atom tam; - struct r200_state_atom tf; - struct r200_state_atom tex[6]; - struct r200_state_atom cube[6]; - struct r200_state_atom zbs; - struct r200_state_atom mtl[2]; - struct r200_state_atom mat[9]; - struct r200_state_atom lit[8]; /* includes vec, scl commands */ - struct r200_state_atom ucp[6]; - struct r200_state_atom pix[6]; /* pixshader stages */ - struct r200_state_atom eye; /* eye pos */ - struct r200_state_atom grd; /* guard band clipping */ - struct r200_state_atom fog; - struct r200_state_atom glt; - - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; -}; - -struct r200_colorbuffer_state { - int roundEnable; -}; - -struct r200_state { - /* Derived state for internal purposes: - */ - struct r200_colorbuffer_state color; - struct r200_depthbuffer_state depth; - struct r200_stencilbuffer_state stencil; - struct r200_stipple_state stipple; - struct r200_texture_state texture; -}; - -/* Need refcounting on dma buffers: - */ -struct r200_dma_buffer { - int refcount; /* the number of retained regions in buf */ - drmBufPtr buf; -}; - -#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \ - (rvb)->address - rmesa->dma.buf0_address + \ - (rvb)->start) - -/* A retained region, eg vertices for indexed vertices. - */ -struct r200_dma_region { - struct r200_dma_buffer *buf; - char *address; /* == buf->address */ - int start, end, ptr; /* offsets from start of buf */ - int aos_start; - int aos_stride; - int aos_size; -}; - -struct r200_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct r200_dma_region current; - - void (*flush) (r200ContextPtr); - - char *buf0_address; /* start of buf[0], for index calcs */ - GLuint nr_released_bufs; /* flush after so many buffers released */ -}; - -#define R200_CMD_BUF_SZ (8*1024) - -struct r200_store { - GLuint statenr; - GLuint primnr; - char cmd_buf[R200_CMD_BUF_SZ]; - int cmd_used; - int elts_start; -}; - -/* r200_tcl.c - */ -struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; - GLuint hw_primitive; - - struct r200_dma_region *aos_components[8]; - GLuint nr_aos_components; - - GLuint *Elts; - - struct r200_dma_region indexed_verts; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; -}; - -/* r200_swtcl.c - */ -struct r200_swtcl_info { - GLuint RenderIndex; - - /** - * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is - * installed in the Mesa state vector. - */ - GLuint vertex_size; - - /** - * Attributes instructing the Mesa TCL pipeline where / how to put vertex - * data in the hardware buffer. - */ - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - - /** - * Number of elements of \c ::vertex_attrs that are actually used. - */ - GLuint vertex_attr_count; - - /** - * Cached pointer to the buffer where Mesa will store vertex data. - */ - GLubyte *verts; - - /* Fallback rasterization functions - */ - r200_point_func draw_point; - r200_line_func draw_line; - r200_tri_func draw_tri; - - GLuint hw_primitive; - GLenum render_primitive; - GLuint numverts; - - /** - * Offset of the 4UB color data within a hardware (swtcl) vertex. - */ - GLuint coloroffset; - - /** - * Offset of the 3UB specular color data within a hardware (swtcl) vertex. - */ - GLuint specoffset; - - /** - * Should Mesa project vertex data or will the hardware do it? - */ - GLboolean needproj; - - struct r200_dma_region indexed_verts; -}; - -struct r200_ioctl { - GLuint vertex_offset; - GLuint vertex_size; -}; - -#define R200_MAX_PRIMS 64 - -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f) (GLcontext *, const int *); - struct dynfn *(*Vertex2fv) (GLcontext *, const int *); - struct dynfn *(*Vertex3f) (GLcontext *, const int *); - struct dynfn *(*Vertex3fv) (GLcontext *, const int *); - struct dynfn *(*Color4ub) (GLcontext *, const int *); - struct dynfn *(*Color4ubv) (GLcontext *, const int *); - struct dynfn *(*Color3ub) (GLcontext *, const int *); - struct dynfn *(*Color3ubv) (GLcontext *, const int *); - struct dynfn *(*Color4f) (GLcontext *, const int *); - struct dynfn *(*Color4fv) (GLcontext *, const int *); - struct dynfn *(*Color3f) (GLcontext *, const int *); - struct dynfn *(*Color3fv) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *); - struct dynfn *(*Normal3f) (GLcontext *, const int *); - struct dynfn *(*Normal3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord3f) (GLcontext *, const int *); - struct dynfn *(*TexCoord3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord2f) (GLcontext *, const int *); - struct dynfn *(*TexCoord2fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord1f) (GLcontext *, const int *); - struct dynfn *(*TexCoord1fv) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *); -}; - -struct r200_prim { - GLuint start; - GLuint end; - GLuint prim; -}; - - /* A maximum total of 29 elements per vertex: 3 floats for position, 3 - * floats for normal, 4 floats for color, 4 bytes for secondary color, - * 3 floats for each texture unit (18 floats total). - * - * we maybe need add. 4 to prevent segfault if someone specifies - * GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: ) - * - * The position data is never actually stored here, so 3 elements could be - * trimmed out of the buffer. - */ - -#define R200_MAX_VERTEX_SIZE ((3*6)+11) - -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify) (void); - GLint vertex_size; - - union { - float f; - int i; - r200_color_t color; - } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - -/** - * R200 context structure. - */ -struct r200_context { - struct radeon_context radeon; /* parent class, must be first */ - - /* Driver and hardware state management - */ - struct r200_hw_state hw; - struct r200_state state; - - /* Texture object bookkeeping - */ - unsigned nr_heaps; - driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS]; - driTextureObject swapped; - int texture_depth; - float initialMaxAnisotropy; - - /* Rasterization and vertex state: - */ - GLuint NewGLState; - - /* Vertex buffers - */ - struct r200_ioctl ioctl; - struct r200_dma dma; - struct r200_store store; - GLboolean save_on_next_unlock; - - /* Clientdata textures; - */ - GLuint prefer_gart_client_texturing; - - /* TCL stuff - */ - GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; - GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS]; - GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS]; - GLuint TexMatEnabled; - GLuint TexMatCompSel; - GLuint TexGenEnabled; - GLuint TexGenInputs; - GLuint TexGenCompSel; - GLmatrix tmpmat; - - /* r200_tcl.c - */ - struct r200_tcl_info tcl; - - /* r200_swtcl.c - */ - struct r200_swtcl_info swtcl; - - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; -}; - -#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) - -extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv); -extern GLboolean r200CreateContext(const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -#endif -#endif /* __R200_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_ioctl.h b/src/mesa/drivers/dri/r300/r200_ioctl.h deleted file mode 100644 index db7bd7697f1..00000000000 --- a/src/mesa/drivers/dri/r300/r200_ioctl.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __R200_IOCTL_H__ -#define __R200_IOCTL_H__ - -#include "simple_list.h" -#include "radeon_dri.h" -#include "radeon_lock.h" - -#include "xf86drm.h" -#include "drm.h" -#include "r200_context.h" -#include "radeon_drm.h" - -extern void r200EmitState(r200ContextPtr rmesa); -extern void r200EmitVertexAOS(r200ContextPtr rmesa, - GLuint vertex_size, GLuint offset); - -extern void r200EmitVbufPrim(r200ContextPtr rmesa, - GLuint primitive, GLuint vertex_nr); - -extern void r200FlushElts(r200ContextPtr rmesa); - -extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa, - GLuint primitive, GLuint min_nr); - -extern void r200EmitAOS(r200ContextPtr rmesa, - struct r200_dma_region **regions, - GLuint n, GLuint offset); - -extern void r200EmitBlit(r200ContextPtr rmesa, - GLuint color_fmt, - GLuint src_pitch, - GLuint src_offset, - GLuint dst_pitch, - GLuint dst_offset, - GLint srcx, GLint srcy, - GLint dstx, GLint dsty, GLuint w, GLuint h); - -extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags); - -extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *); -extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller); -extern void r200Flush(GLcontext * ctx); - -extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa); - -extern void r200AllocDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - int bytes, int alignment); - -extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa, - struct r200_dma_region *region, - int numverts, int vertsize, int alignment); - -extern void r200ReleaseDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - const char *caller); - -extern void r200WaitForVBlank(r200ContextPtr rmesa); -extern void r200InitIoctlFuncs(struct dd_function_table *functions); - -extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLsizei size, GLfloat readfreq, - GLfloat writefreq, GLfloat priority); -extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLvoid * pointer); -extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn, - const GLvoid * pointer); - -extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer, - GLint size); - -extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa, - const GLvoid * pointer); - -void r200SaveHwState(r200ContextPtr radeon); -void r200SetUpAtomList(r200ContextPtr rmesa); - -/* ================================================================ - * Helper macros: - */ - -/* Close off the last primitive, if it exists. - */ -#define R200_NEWPRIM( rmesa ) \ -do { \ - if ( rmesa->dma.flush ) \ - rmesa->dma.flush( rmesa ); \ -} while (0) - -/* Can accomodate several state changes and primitive changes without - * actually firing the buffer. - */ -#define R200_STATECHANGE( rmesa, ATOM ) \ -do { \ - R200_NEWPRIM( rmesa ); \ - rmesa->hw.ATOM.dirty = GL_TRUE; \ - rmesa->hw.is_dirty = GL_TRUE; \ -} while (0) - -#define R200_DB_STATE( ATOM ) \ - memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ - rmesa->hw.ATOM.cmd_size * 4) - -static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa, - struct r200_state_atom *atom) -{ - if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) { - int *tmp; - R200_NEWPRIM(rmesa); - atom->dirty = GL_TRUE; - rmesa->hw.is_dirty = GL_TRUE; - tmp = atom->cmd; - atom->cmd = atom->lastcmd; - atom->lastcmd = tmp; - return 1; - } else - return 0; -} - -/* Fire the buffered vertices no matter what. - */ -#define R200_FIREVERTICES( r200 ) \ -do { \ - if ( (r200)->store.cmd_used || (r200)->dma.flush ) { \ - radeonFlush( (r200)->radeon.glCtx ); \ - } \ -} while (0) - -/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ - * are available, you will also be adding an rmesa->state.max_state_size because - * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. - */ -#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int)) -#define VERT_AOS_BUFSZ (5 * sizeof(int)) -#define ELTS_BUFSZ(nr) (12 + nr * 2) -#define VBUF_BUFSZ (3 * sizeof(int)) - -/* Ensure that a minimum amount of space is available in the command buffer. - * This is used to ensure atomicity of state updates with the rendering requests - * that rely on them. - * - * An alternative would be to implement a "soft lock" such that when the buffer - * wraps at an inopportune time, we grab the lock, flush the current buffer, - * and hang on to the lock until the critical section is finished and we flush - * the buffer again and unlock. - */ -static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes) -{ - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, __FUNCTION__); - assert(bytes <= R200_CMD_BUF_SZ); -} - -/* Alloc space in the command buffer - */ -static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa, - int bytes, const char *where) -{ - char *head; - - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, where); - - head = rmesa->store.cmd_buf + rmesa->store.cmd_used; - rmesa->store.cmd_used += bytes; - assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ); - return head; -} - -#endif /* __R200_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_reg.h b/src/mesa/drivers/dri/r300/r200_reg.h deleted file mode 100644 index 1336e961ac6..00000000000 --- a/src/mesa/drivers/dri/r300/r200_reg.h +++ /dev/null @@ -1,1423 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef _R200_REG_H_ -#define _R200_REG_H_ - -#define R200_PP_MISC 0x1c14 -#define R200_REF_ALPHA_MASK 0x000000ff -#define R200_ALPHA_TEST_FAIL (0 << 8) -#define R200_ALPHA_TEST_LESS (1 << 8) -#define R200_ALPHA_TEST_LEQUAL (2 << 8) -#define R200_ALPHA_TEST_EQUAL (3 << 8) -#define R200_ALPHA_TEST_GEQUAL (4 << 8) -#define R200_ALPHA_TEST_GREATER (5 << 8) -#define R200_ALPHA_TEST_NEQUAL (6 << 8) -#define R200_ALPHA_TEST_PASS (7 << 8) -#define R200_ALPHA_TEST_OP_MASK (7 << 8) -#define R200_CHROMA_FUNC_FAIL (0 << 16) -#define R200_CHROMA_FUNC_PASS (1 << 16) -#define R200_CHROMA_FUNC_NEQUAL (2 << 16) -#define R200_CHROMA_FUNC_EQUAL (3 << 16) -#define R200_CHROMA_KEY_NEAREST (0 << 18) -#define R200_CHROMA_KEY_ZERO (1 << 18) -#define R200_RIGHT_HAND_CUBE_D3D (0 << 24) -#define R200_RIGHT_HAND_CUBE_OGL (1 << 24) -#define R200_PP_FOG_COLOR 0x1c18 -#define R200_FOG_COLOR_MASK 0x00ffffff -#define R200_FOG_VERTEX (0 << 24) -#define R200_FOG_TABLE (1 << 24) -#define R200_FOG_USE_DEPTH (0 << 25) -#define R200_FOG_USE_W (1 << 25) -#define R200_FOG_USE_DIFFUSE_ALPHA (2 << 25) -#define R200_FOG_USE_SPEC_ALPHA (3 << 25) -#define R200_FOG_USE_VTX_FOG (4 << 25) -#define R200_FOG_USE_MASK (7 << 25) -#define R200_RE_SOLID_COLOR 0x1c1c -#define R200_RB3D_BLENDCNTL 0x1c20 -#define R200_COMB_FCN_MASK (7 << 12) -#define R200_COMB_FCN_ADD_CLAMP (0 << 12) -#define R200_COMB_FCN_ADD_NOCLAMP (1 << 12) -#define R200_COMB_FCN_SUB_CLAMP (2 << 12) -#define R200_COMB_FCN_SUB_NOCLAMP (3 << 12) -#define R200_COMB_FCN_MIN (4 << 12) -#define R200_COMB_FCN_MAX (5 << 12) -#define R200_COMB_FCN_RSUB_CLAMP (6 << 12) -#define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12) -#define R200_BLEND_GL_ZERO (32) -#define R200_BLEND_GL_ONE (33) -#define R200_BLEND_GL_SRC_COLOR (34) -#define R200_BLEND_GL_ONE_MINUS_SRC_COLOR (35) -#define R200_BLEND_GL_DST_COLOR (36) -#define R200_BLEND_GL_ONE_MINUS_DST_COLOR (37) -#define R200_BLEND_GL_SRC_ALPHA (38) -#define R200_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) -#define R200_BLEND_GL_DST_ALPHA (40) -#define R200_BLEND_GL_ONE_MINUS_DST_ALPHA (41) -#define R200_BLEND_GL_SRC_ALPHA_SATURATE (42) /* src factor only */ -#define R200_BLEND_GL_CONST_COLOR (43) -#define R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44) -#define R200_BLEND_GL_CONST_ALPHA (45) -#define R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) -#define R200_BLEND_MASK (63) -#define R200_SRC_BLEND_SHIFT (16) -#define R200_DST_BLEND_SHIFT (24) -#define R200_RB3D_DEPTHOFFSET 0x1c24 -#define R200_RB3D_DEPTHPITCH 0x1c28 -#define R200_DEPTHPITCH_MASK 0x00001ff8 -#define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18) -#define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18) -#define R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_RB3D_ZSTENCILCNTL 0x1c2c -#define R200_DEPTH_FORMAT_MASK (0xf << 0) -#define R200_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -#define R200_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) -#define R200_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) -#define R200_Z_TEST_NEVER (0 << 4) -#define R200_Z_TEST_LESS (1 << 4) -#define R200_Z_TEST_LEQUAL (2 << 4) -#define R200_Z_TEST_EQUAL (3 << 4) -#define R200_Z_TEST_GEQUAL (4 << 4) -#define R200_Z_TEST_GREATER (5 << 4) -#define R200_Z_TEST_NEQUAL (6 << 4) -#define R200_Z_TEST_ALWAYS (7 << 4) -#define R200_Z_TEST_MASK (7 << 4) -#define R200_STENCIL_TEST_NEVER (0 << 12) -#define R200_STENCIL_TEST_LESS (1 << 12) -#define R200_STENCIL_TEST_LEQUAL (2 << 12) -#define R200_STENCIL_TEST_EQUAL (3 << 12) -#define R200_STENCIL_TEST_GEQUAL (4 << 12) -#define R200_STENCIL_TEST_GREATER (5 << 12) -#define R200_STENCIL_TEST_NEQUAL (6 << 12) -#define R200_STENCIL_TEST_ALWAYS (7 << 12) -#define R200_STENCIL_TEST_MASK (0x7 << 12) -#define R200_STENCIL_FAIL_KEEP (0 << 16) -#define R200_STENCIL_FAIL_ZERO (1 << 16) -#define R200_STENCIL_FAIL_REPLACE (2 << 16) -#define R200_STENCIL_FAIL_INC (3 << 16) -#define R200_STENCIL_FAIL_DEC (4 << 16) -#define R200_STENCIL_FAIL_INVERT (5 << 16) -#define R200_STENCIL_FAIL_INC_WRAP (6 << 16) -#define R200_STENCIL_FAIL_DEC_WRAP (7 << 16) -#define R200_STENCIL_FAIL_MASK (0x7 << 16) -#define R200_STENCIL_ZPASS_KEEP (0 << 20) -#define R200_STENCIL_ZPASS_ZERO (1 << 20) -#define R200_STENCIL_ZPASS_REPLACE (2 << 20) -#define R200_STENCIL_ZPASS_INC (3 << 20) -#define R200_STENCIL_ZPASS_DEC (4 << 20) -#define R200_STENCIL_ZPASS_INVERT (5 << 20) -#define R200_STENCIL_ZPASS_INC_WRAP (6 << 20) -#define R200_STENCIL_ZPASS_DEC_WRAP (7 << 20) -#define R200_STENCIL_ZPASS_MASK (0x7 << 20) -#define R200_STENCIL_ZFAIL_KEEP (0 << 24) -#define R200_STENCIL_ZFAIL_ZERO (1 << 24) -#define R200_STENCIL_ZFAIL_REPLACE (2 << 24) -#define R200_STENCIL_ZFAIL_INC (3 << 24) -#define R200_STENCIL_ZFAIL_DEC (4 << 24) -#define R200_STENCIL_ZFAIL_INVERT (5 << 24) -#define R200_STENCIL_ZFAIL_INC_WRAP (6 << 24) -#define R200_STENCIL_ZFAIL_DEC_WRAP (7 << 24) -#define R200_STENCIL_ZFAIL_MASK (0x7 << 24) -#define R200_Z_WRITE_ENABLE (1 << 30) -/*gap*/ -#define R200_PP_CNTL 0x1c38 -#define R200_TEX_0_ENABLE 0x00000010 -#define R200_TEX_1_ENABLE 0x00000020 -#define R200_TEX_2_ENABLE 0x00000040 -#define R200_TEX_3_ENABLE 0x00000080 -#define R200_TEX_4_ENABLE 0x00000100 -#define R200_TEX_5_ENABLE 0x00000200 -#define R200_TEX_ENABLE_MASK 0x000003f0 -#define R200_FILTER_ROUND_MODE_MASK 0x00000400 -#define R200_TEX_BLEND_7_ENABLE 0x00000800 -#define R200_TEX_BLEND_0_ENABLE 0x00001000 -#define R200_TEX_BLEND_1_ENABLE 0x00002000 -#define R200_TEX_BLEND_2_ENABLE 0x00004000 -#define R200_TEX_BLEND_3_ENABLE 0x00008000 -#define R200_TEX_BLEND_4_ENABLE 0x00010000 -#define R200_TEX_BLEND_5_ENABLE 0x00020000 -#define R200_TEX_BLEND_6_ENABLE 0x00040000 -#define R200_MULTI_PASS_ENABLE 0x00080000 -#define R200_SPECULAR_ENABLE 0x00200000 -#define R200_FOG_ENABLE 0x00400000 -#define R200_ALPHA_TEST_ENABLE 0x00800000 -#define R200_ANTI_ALIAS_NONE 0x00000000 -#define R200_ANTI_ALIAS_LINE 0x01000000 -#define R200_ANTI_ALIAS_POLY 0x02000000 -#define R200_ANTI_ALIAS_MASK 0x03000000 -#define R200_RB3D_CNTL 0x1c3c -#define R200_ALPHA_BLEND_ENABLE (1 << 0) -#define R200_PLANE_MASK_ENABLE (1 << 1) -#define R200_DITHER_ENABLE (1 << 2) -#define R200_ROUND_ENABLE (1 << 3) -#define R200_SCALE_DITHER_ENABLE (1 << 4) -#define R200_DITHER_INIT (1 << 5) -#define R200_ROP_ENABLE (1 << 6) -#define R200_STENCIL_ENABLE (1 << 7) -#define R200_Z_ENABLE (1 << 8) -#define R200_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -#define R200_COLOR_FORMAT_ARGB1555 (3 << 10) -#define R200_COLOR_FORMAT_RGB565 (4 << 10) -#define R200_COLOR_FORMAT_ARGB8888 (6 << 10) -#define R200_COLOR_FORMAT_RGB332 (7 << 10) -#define R200_COLOR_FORMAT_Y8 (8 << 10) -#define R200_COLOR_FORMAT_RGB8 (9 << 10) -#define R200_COLOR_FORMAT_YUV422_VYUY (11 << 10) -#define R200_COLOR_FORMAT_YUV422_YVYU (12 << 10) -#define R200_COLOR_FORMAT_aYUV444 (14 << 10) -#define R200_COLOR_FORMAT_ARGB4444 (15 << 10) -#define R200_CLRCMP_FLIP_ENABLE (1 << 14) -#define R200_SEPARATE_ALPHA_ENABLE (1 << 16) -#define R200_RB3D_COLOROFFSET 0x1c40 -#define R200_COLOROFFSET_MASK 0xfffffff0 -#define R200_RE_WIDTH_HEIGHT 0x1c44 -#define R200_RE_WIDTH_SHIFT 0 -#define R200_RE_HEIGHT_SHIFT 16 -#define R200_RB3D_COLORPITCH 0x1c48 -#define R200_COLORPITCH_MASK 0x000001ff8 -#define R200_COLOR_ENDIAN_NO_SWAP (0 << 18) -#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18) -#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_SE_CNTL 0x1c4c -#define R200_FFACE_CULL_CW (0 << 0) -#define R200_FFACE_CULL_CCW (1 << 0) -#define R200_FFACE_CULL_DIR_MASK (1 << 0) -#define R200_BFACE_CULL (0 << 1) -#define R200_BFACE_SOLID (3 << 1) -#define R200_FFACE_CULL (0 << 3) -#define R200_FFACE_SOLID (3 << 3) -#define R200_FFACE_CULL_MASK (3 << 3) -#define R200_FLAT_SHADE_VTX_0 (0 << 6) -#define R200_FLAT_SHADE_VTX_1 (1 << 6) -#define R200_FLAT_SHADE_VTX_2 (2 << 6) -#define R200_FLAT_SHADE_VTX_LAST (3 << 6) -#define R200_DIFFUSE_SHADE_SOLID (0 << 8) -#define R200_DIFFUSE_SHADE_FLAT (1 << 8) -#define R200_DIFFUSE_SHADE_GOURAUD (2 << 8) -#define R200_DIFFUSE_SHADE_MASK (3 << 8) -#define R200_ALPHA_SHADE_SOLID (0 << 10) -#define R200_ALPHA_SHADE_FLAT (1 << 10) -#define R200_ALPHA_SHADE_GOURAUD (2 << 10) -#define R200_ALPHA_SHADE_MASK (3 << 10) -#define R200_SPECULAR_SHADE_SOLID (0 << 12) -#define R200_SPECULAR_SHADE_FLAT (1 << 12) -#define R200_SPECULAR_SHADE_GOURAUD (2 << 12) -#define R200_SPECULAR_SHADE_MASK (3 << 12) -#define R200_FOG_SHADE_SOLID (0 << 14) -#define R200_FOG_SHADE_FLAT (1 << 14) -#define R200_FOG_SHADE_GOURAUD (2 << 14) -#define R200_FOG_SHADE_MASK (3 << 14) -#define R200_ZBIAS_ENABLE_POINT (1 << 16) -#define R200_ZBIAS_ENABLE_LINE (1 << 17) -#define R200_ZBIAS_ENABLE_TRI (1 << 18) -#define R200_WIDELINE_ENABLE (1 << 20) -#define R200_VTX_PIX_CENTER_D3D (0 << 27) -#define R200_VTX_PIX_CENTER_OGL (1 << 27) -#define R200_ROUND_MODE_TRUNC (0 << 28) -#define R200_ROUND_MODE_ROUND (1 << 28) -#define R200_ROUND_MODE_ROUND_EVEN (2 << 28) -#define R200_ROUND_MODE_ROUND_ODD (3 << 28) -#define R200_ROUND_PREC_16TH_PIX (0 << 30) -#define R200_ROUND_PREC_8TH_PIX (1 << 30) -#define R200_ROUND_PREC_4TH_PIX (2 << 30) -#define R200_ROUND_PREC_HALF_PIX (3 << 30) -#define R200_RE_CNTL 0x1c50 -#define R200_STIPPLE_ENABLE 0x1 -#define R200_SCISSOR_ENABLE 0x2 -#define R200_PATTERN_ENABLE 0x4 -#define R200_PERSPECTIVE_ENABLE 0x8 -#define R200_POINT_SMOOTH 0x20 -#define R200_VTX_STQ0_D3D 0x00010000 -#define R200_VTX_STQ1_D3D 0x00040000 -#define R200_VTX_STQ2_D3D 0x00100000 -#define R200_VTX_STQ3_D3D 0x00400000 -#define R200_VTX_STQ4_D3D 0x01000000 -#define R200_VTX_STQ5_D3D 0x04000000 -/* gap */ -#define R200_RE_STIPPLE_ADDR 0x1cc8 -#define R200_RE_STIPPLE_DATA 0x1ccc -#define R200_RE_LINE_PATTERN 0x1cd0 -#define R200_LINE_PATTERN_MASK 0x0000ffff -#define R200_LINE_REPEAT_COUNT_SHIFT 16 -#define R200_LINE_PATTERN_START_SHIFT 24 -#define R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) -#define R200_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) -#define R200_LINE_PATTERN_AUTO_RESET (1 << 29) -#define R200_RE_LINE_STATE 0x1cd4 -#define R200_LINE_CURRENT_PTR_SHIFT 0 -#define R200_LINE_CURRENT_COUNT_SHIFT 8 -#define R200_RE_SCISSOR_TL_0 0x1cd8 -#define R200_RE_SCISSOR_BR_0 0x1cdc -#define R200_RE_SCISSOR_TL_1 0x1ce0 -#define R200_RE_SCISSOR_BR_1 0x1ce4 -#define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RE_SCISSOR_BR_2 0x1cec -/* gap */ -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 -#define R200_DEPTHX_SHIFT 0 -#define R200_DEPTHY_SHIFT 16 -/* gap */ -#define R200_RB3D_STENCILREFMASK 0x1d7c -#define R200_STENCIL_REF_SHIFT 0 -#define R200_STENCIL_REF_MASK (0xff << 0) -#define R200_STENCIL_MASK_SHIFT 16 -#define R200_STENCIL_VALUE_MASK (0xff << 16) -#define R200_STENCIL_WRITEMASK_SHIFT 24 -#define R200_STENCIL_WRITE_MASK (0xff << 24) -#define R200_RB3D_ROPCNTL 0x1d80 -#define R200_ROP_MASK (15 << 8) -#define R200_ROP_CLEAR (0 << 8) -#define R200_ROP_NOR (1 << 8) -#define R200_ROP_AND_INVERTED (2 << 8) -#define R200_ROP_COPY_INVERTED (3 << 8) -#define R200_ROP_AND_REVERSE (4 << 8) -#define R200_ROP_INVERT (5 << 8) -#define R200_ROP_XOR (6 << 8) -#define R200_ROP_NAND (7 << 8) -#define R200_ROP_AND (8 << 8) -#define R200_ROP_EQUIV (9 << 8) -#define R200_ROP_NOOP (10 << 8) -#define R200_ROP_OR_INVERTED (11 << 8) -#define R200_ROP_COPY (12 << 8) -#define R200_ROP_OR_REVERSE (13 << 8) -#define R200_ROP_OR (14 << 8) -#define R200_ROP_SET (15 << 8) -#define R200_RB3D_PLANEMASK 0x1d84 -/* gap */ -#define R200_SE_VPORT_XSCALE 0x1d98 -#define R200_SE_VPORT_XOFFSET 0x1d9c -#define R200_SE_VPORT_YSCALE 0x1da0 -#define R200_SE_VPORT_YOFFSET 0x1da4 -#define R200_SE_VPORT_ZSCALE 0x1da8 -#define R200_SE_VPORT_ZOFFSET 0x1dac -#define R200_SE_ZBIAS_FACTOR 0x1db0 -#define R200_SE_ZBIAS_CONSTANT 0x1db4 -#define R200_SE_LINE_WIDTH 0x1db8 -#define R200_LINE_WIDTH_SHIFT 0x00000000 -#define R200_MINPOINTSIZE_SHIFT 0x00000010 -/* gap */ -#define R200_SE_VAP_CNTL 0x2080 -#define R200_VAP_TCL_ENABLE 0x00000001 -#define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 -#define R200_VAP_FORCE_W_TO_ONE 0x00010000 -#define R200_VAP_D3D_TEX_DEFAULT 0x00020000 -#define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 -#define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 -#define R200_SE_VF_CNTL 0x2084 -#define R200_VF_PRIM_NONE 0x00000000 -#define R200_VF_PRIM_POINTS 0x00000001 -#define R200_VF_PRIM_LINES 0x00000002 -#define R200_VF_PRIM_LINE_STRIP 0x00000003 -#define R200_VF_PRIM_TRIANGLES 0x00000004 -#define R200_VF_PRIM_TRIANGLE_FAN 0x00000005 -#define R200_VF_PRIM_TRIANGLE_STRIP 0x00000006 -#define R200_VF_PRIM_RECT_LIST 0x00000008 -#define R200_VF_PRIM_3VRT_POINTS 0x00000009 -#define R200_VF_PRIM_3VRT_LINES 0x0000000a -#define R200_VF_PRIM_POINT_SPRITES 0x0000000b -#define R200_VF_PRIM_LINE_LOOP 0x0000000c -#define R200_VF_PRIM_QUADS 0x0000000d -#define R200_VF_PRIM_QUAD_STRIP 0x0000000e -#define R200_VF_PRIM_POLYGON 0x0000000f -#define R200_VF_PRIM_MASK 0x0000000f -#define R200_VF_PRIM_WALK_IND 0x00000010 -#define R200_VF_PRIM_WALK_LIST 0x00000020 -#define R200_VF_PRIM_WALK_RING 0x00000030 -#define R200_VF_PRIM_WALK_MASK 0x00000030 -#define R200_VF_COLOR_ORDER_RGBA 0x00000040 -#define R200_VF_TCL_OUTPUT_VTX_ENABLE 0x00000200 -#define R200_VF_INDEX_SZ_4 0x00000800 -#define R200_VF_VERTEX_NUMBER_MASK 0xffff0000 -#define R200_VF_VERTEX_NUMBER_SHIFT 16 -#define R200_SE_VTX_FMT_0 0x2088 -#define R200_VTX_XY 0 /* always have xy */ -#define R200_VTX_Z0 (1<<0) -#define R200_VTX_W0 (1<<1) -#define R200_VTX_WEIGHT_COUNT_SHIFT (2) -#define R200_VTX_PV_MATRIX_SEL (1<<5) -#define R200_VTX_N0 (1<<6) -#define R200_VTX_POINT_SIZE (1<<7) -#define R200_VTX_DISCRETE_FOG (1<<8) -#define R200_VTX_SHININESS_0 (1<<9) -#define R200_VTX_SHININESS_1 (1<<10) -#define R200_VTX_COLOR_NOT_PRESENT 0 -#define R200_VTX_PK_RGBA 1 -#define R200_VTX_FP_RGB 2 -#define R200_VTX_FP_RGBA 3 -#define R200_VTX_COLOR_MASK 3 -#define R200_VTX_COLOR_0_SHIFT 11 -#define R200_VTX_COLOR_1_SHIFT 13 -#define R200_VTX_COLOR_2_SHIFT 15 -#define R200_VTX_COLOR_3_SHIFT 17 -#define R200_VTX_COLOR_4_SHIFT 19 -#define R200_VTX_COLOR_5_SHIFT 21 -#define R200_VTX_COLOR_6_SHIFT 23 -#define R200_VTX_COLOR_7_SHIFT 25 -#define R200_VTX_XY1 (1<<28) -#define R200_VTX_Z1 (1<<29) -#define R200_VTX_W1 (1<<30) -#define R200_VTX_N1 (1<<31) -#define R200_SE_VTX_FMT_1 0x208c -#define R200_VTX_TEX0_COMP_CNT_SHIFT 0 -#define R200_VTX_TEX1_COMP_CNT_SHIFT 3 -#define R200_VTX_TEX2_COMP_CNT_SHIFT 6 -#define R200_VTX_TEX3_COMP_CNT_SHIFT 9 -#define R200_VTX_TEX4_COMP_CNT_SHIFT 12 -#define R200_VTX_TEX5_COMP_CNT_SHIFT 15 -#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 -#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 -/* gap */ -#define R200_SE_VTE_CNTL 0x20b0 -#define R200_VPORT_X_SCALE_ENA 0x00000001 -#define R200_VPORT_X_OFFSET_ENA 0x00000002 -#define R200_VPORT_Y_SCALE_ENA 0x00000004 -#define R200_VPORT_Y_OFFSET_ENA 0x00000008 -#define R200_VPORT_Z_SCALE_ENA 0x00000010 -#define R200_VPORT_Z_OFFSET_ENA 0x00000020 -#define R200_VTX_XY_FMT 0x00000100 -#define R200_VTX_Z_FMT 0x00000200 -#define R200_VTX_W0_FMT 0x00000400 -#define R200_VTX_W0_NORMALIZE 0x00000800 -#define R200_VTX_ST_DENORMALIZED 0x00001000 -/* gap */ -#define R200_SE_VTX_NUM_ARRAYS 0x20c0 -#define R200_SE_VTX_AOS_ATTR01 0x20c4 -#define R200_SE_VTX_AOS_ADDR0 0x20c8 -#define R200_SE_VTX_AOS_ADDR1 0x20cc -#define R200_SE_VTX_AOS_ATTR23 0x20d0 -#define R200_SE_VTX_AOS_ADDR2 0x20d4 -#define R200_SE_VTX_AOS_ADDR3 0x20d8 -#define R200_SE_VTX_AOS_ATTR45 0x20dc -#define R200_SE_VTX_AOS_ADDR4 0x20e0 -#define R200_SE_VTX_AOS_ADDR5 0x20e4 -#define R200_SE_VTX_AOS_ATTR67 0x20e8 -#define R200_SE_VTX_AOS_ADDR6 0x20ec -#define R200_SE_VTX_AOS_ADDR7 0x20f0 -#define R200_SE_VTX_AOS_ATTR89 0x20f4 -#define R200_SE_VTX_AOS_ADDR8 0x20f8 -#define R200_SE_VTX_AOS_ADDR9 0x20fc -#define R200_SE_VTX_AOS_ATTR1011 0x2100 -#define R200_SE_VTX_AOS_ADDR10 0x2104 -#define R200_SE_VTX_AOS_ADDR11 0x2108 -#define R200_SE_VF_MAX_VTX_INDX 0x210c -#define R200_SE_VF_MIN_VTX_INDX 0x2110 -/* gap */ -#define R200_SE_VAP_CNTL_STATUS 0x2140 -#define R200_VC_NO_SWAP (0 << 0) -#define R200_VC_16BIT_SWAP (1 << 0) -#define R200_VC_32BIT_SWAP (2 << 0) -/* gap */ -#define R200_SE_VTX_STATE_CNTL 0x2180 -#define R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT 0x00000000 -#define R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT 0x00000002 -#define R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT 0x00000004 -#define R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT 0x00000006 -#define R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT 0x00000008 -#define R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT 0x0000000a -#define R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT 0x0000000c -#define R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT 0x0000000e -#define R200_VSC_UPDATE_USER_COLOR_0_ENABLE 0x00010000 -#define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000 -/* gap */ -#define R200_SE_TCL_VECTOR_INDX_REG 0x2200 -#define R200_SE_TCL_VECTOR_DATA_REG 0x2204 -#define R200_SE_TCL_SCALAR_INDX_REG 0x2208 -#define R200_SE_TCL_SCALAR_DATA_REG 0x220c -/* gap */ -#define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_MODELVIEW_0_SHIFT (0) -#define R200_MODELVIEW_1_SHIFT (8) -#define R200_MODELVIEW_2_SHIFT (16) -#define R200_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_1 0x2234 -#define R200_IT_MODELVIEW_0_SHIFT (0) -#define R200_IT_MODELVIEW_1_SHIFT (8) -#define R200_IT_MODELVIEW_2_SHIFT (16) -#define R200_IT_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_2 0x2238 -#define R200_MODELPROJECT_0_SHIFT (0) -#define R200_MODELPROJECT_1_SHIFT (8) -#define R200_MODELPROJECT_2_SHIFT (16) -#define R200_MODELPROJECT_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_3 0x223c -#define R200_TEXMAT_0_SHIFT 0 -#define R200_TEXMAT_1_SHIFT 8 -#define R200_TEXMAT_2_SHIFT 16 -#define R200_TEXMAT_3_SHIFT 24 -#define R200_SE_TCL_MATRIX_SEL_4 0x2240 -#define R200_TEXMAT_4_SHIFT 0 -#define R200_TEXMAT_5_SHIFT 8 -/* gap */ -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -#define R200_OUTPUT_XYZW (1<<0) -#define R200_OUTPUT_COLOR_0 (1<<8) -#define R200_OUTPUT_COLOR_1 (1<<9) -#define R200_OUTPUT_TEX_0 (1<<16) -#define R200_OUTPUT_TEX_1 (1<<17) -#define R200_OUTPUT_TEX_2 (1<<18) -#define R200_OUTPUT_TEX_3 (1<<19) -#define R200_OUTPUT_TEX_4 (1<<20) -#define R200_OUTPUT_TEX_5 (1<<21) -#define R200_OUTPUT_TEX_MASK (0x3f<<16) -#define R200_OUTPUT_DISCRETE_FOG (1<<24) -#define R200_OUTPUT_PT_SIZE (1<<25) -#define R200_FORCE_INORDER_PROC (1<<31) -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 -#define R200_VERTEX_POSITION_ADDR__SHIFT 0x00000000 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1 0x2258 -#define R200_VTX_COLOR_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_COLOR_1_ADDR__SHIFT 0x00000008 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2 0x225c -#define R200_VTX_TEX_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_1_ADDR__SHIFT 0x00000008 -#define R200_VTX_TEX_2_ADDR__SHIFT 0x00000010 -#define R200_VTX_TEX_3_ADDR__SHIFT 0x00000018 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3 0x2260 -#define R200_VTX_TEX_4_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_5_ADDR__SHIFT 0x00000008 - -/* gap */ -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 -#define R200_LIGHTING_ENABLE (1<<0) -#define R200_LIGHT_IN_MODELSPACE (1<<1) -#define R200_LOCAL_VIEWER (1<<2) -#define R200_NORMALIZE_NORMALS (1<<3) -#define R200_RESCALE_NORMALS (1<<4) -#define R200_SPECULAR_LIGHTS (1<<5) -#define R200_DIFFUSE_SPECULAR_COMBINE (1<<6) -#define R200_LIGHT_ALPHA (1<<7) -#define R200_LOCAL_LIGHT_VEC_GL (1<<8) -#define R200_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9) -#define R200_LIGHT_TWOSIDE (1<<10) -#define R200_FRONT_SHININESS_SOURCE_SHIFT (0xb) -#define R200_BACK_SHININESS_SOURCE_SHIFT (0xd) -#define R200_LM0_SOURCE_MATERIAL_0 (0) -#define R200_LM0_SOURCE_MATERIAL_1 (1) -#define R200_LM0_SOURCE_VERTEX_SHININESS_0 (2) -#define R200_LM0_SOURCE_VERTEX_SHININESS_1 (3) -#define R200_SE_TCL_LIGHT_MODEL_CTL_1 0x226c -#define R200_LM1_SOURCE_LIGHT_PREMULT (0) -#define R200_LM1_SOURCE_MATERIAL_0 (1) -#define R200_LM1_SOURCE_VERTEX_COLOR_0 (2) -#define R200_LM1_SOURCE_VERTEX_COLOR_1 (3) -#define R200_LM1_SOURCE_VERTEX_COLOR_2 (4) -#define R200_LM1_SOURCE_VERTEX_COLOR_3 (5) -#define R200_LM1_SOURCE_VERTEX_COLOR_4 (6) -#define R200_LM1_SOURCE_VERTEX_COLOR_5 (7) -#define R200_LM1_SOURCE_VERTEX_COLOR_6 (8) -#define R200_LM1_SOURCE_VERTEX_COLOR_7 (9) -#define R200_LM1_SOURCE_MATERIAL_1 (0xf) -#define R200_FRONT_EMISSIVE_SOURCE_SHIFT (0) -#define R200_FRONT_AMBIENT_SOURCE_SHIFT (4) -#define R200_FRONT_DIFFUSE_SOURCE_SHIFT (8) -#define R200_FRONT_SPECULAR_SOURCE_SHIFT (12) -#define R200_BACK_EMISSIVE_SOURCE_SHIFT (16) -#define R200_BACK_AMBIENT_SOURCE_SHIFT (20) -#define R200_BACK_DIFFUSE_SOURCE_SHIFT (24) -#define R200_BACK_SPECULAR_SOURCE_SHIFT (28) -#define R200_SE_TCL_PER_LIGHT_CTL_0 0x2270 -#define R200_LIGHT_0_ENABLE (1<<0) -#define R200_LIGHT_0_ENABLE_AMBIENT (1<<1) -#define R200_LIGHT_0_ENABLE_SPECULAR (1<<2) -#define R200_LIGHT_0_IS_LOCAL (1<<3) -#define R200_LIGHT_0_IS_SPOT (1<<4) -#define R200_LIGHT_0_DUAL_CONE (1<<5) -#define R200_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6) -#define R200_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7) -#define R200_LIGHT_1_ENABLE (1<<16) -#define R200_LIGHT_1_ENABLE_AMBIENT (1<<17) -#define R200_LIGHT_1_ENABLE_SPECULAR (1<<18) -#define R200_LIGHT_1_IS_LOCAL (1<<19) -#define R200_LIGHT_1_IS_SPOT (1<<20) -#define R200_LIGHT_1_DUAL_CONE (1<<21) -#define R200_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22) -#define R200_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23) -#define R200_LIGHT_0_SHIFT (0) -#define R200_LIGHT_1_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_1 0x2274 -#define R200_LIGHT_2_SHIFT (0) -#define R200_LIGHT_3_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_2 0x2278 -#define R200_LIGHT_4_SHIFT (0) -#define R200_LIGHT_5_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_3 0x227c -#define R200_LIGHT_6_SHIFT (0) -#define R200_LIGHT_7_SHIFT (16) -/* gap */ -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_TEXGEN_0_COMP_MASK_SHIFT (0) -#define R200_TEXGEN_1_COMP_MASK_SHIFT (4) -#define R200_TEXGEN_2_COMP_MASK_SHIFT (8) -#define R200_TEXGEN_3_COMP_MASK_SHIFT (12) -#define R200_TEXGEN_4_COMP_MASK_SHIFT (16) -#define R200_TEXGEN_5_COMP_MASK_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_3 0x22ac -#define R200_TEXGEN_0_INPUT_TEX_SHIFT (0) -#define R200_TEXGEN_1_INPUT_TEX_SHIFT (4) -#define R200_TEXGEN_2_INPUT_TEX_SHIFT (8) -#define R200_TEXGEN_3_INPUT_TEX_SHIFT (12) -#define R200_TEXGEN_4_INPUT_TEX_SHIFT (16) -#define R200_TEXGEN_5_INPUT_TEX_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_0 0x22b0 -#define R200_TEXGEN_TEXMAT_0_ENABLE (1<<0) -#define R200_TEXGEN_TEXMAT_1_ENABLE (1<<1) -#define R200_TEXGEN_TEXMAT_2_ENABLE (1<<2) -#define R200_TEXGEN_TEXMAT_3_ENABLE (1<<3) -#define R200_TEXGEN_TEXMAT_4_ENABLE (1<<4) -#define R200_TEXGEN_TEXMAT_5_ENABLE (1<<5) -#define R200_TEXMAT_0_ENABLE (1<<8) -#define R200_TEXMAT_1_ENABLE (1<<9) -#define R200_TEXMAT_2_ENABLE (1<<10) -#define R200_TEXMAT_3_ENABLE (1<<11) -#define R200_TEXMAT_4_ENABLE (1<<12) -#define R200_TEXMAT_5_ENABLE (1<<13) -#define R200_TEXGEN_FORCE_W_TO_ONE (1<<16) -#define R200_SE_TCL_TEX_PROC_CTL_1 0x22b4 -#define R200_TEXGEN_INPUT_MASK (0xf) -#define R200_TEXGEN_INPUT_TEXCOORD_0 (0) -#define R200_TEXGEN_INPUT_TEXCOORD_1 (1) -#define R200_TEXGEN_INPUT_TEXCOORD_2 (2) -#define R200_TEXGEN_INPUT_TEXCOORD_3 (3) -#define R200_TEXGEN_INPUT_TEXCOORD_4 (4) -#define R200_TEXGEN_INPUT_TEXCOORD_5 (5) -#define R200_TEXGEN_INPUT_OBJ (8) -#define R200_TEXGEN_INPUT_EYE (9) -#define R200_TEXGEN_INPUT_EYE_NORMAL (0xa) -#define R200_TEXGEN_INPUT_EYE_REFLECT (0xb) -#define R200_TEXGEN_INPUT_SPHERE (0xd) -#define R200_TEXGEN_0_INPUT_SHIFT (0) -#define R200_TEXGEN_1_INPUT_SHIFT (4) -#define R200_TEXGEN_2_INPUT_SHIFT (8) -#define R200_TEXGEN_3_INPUT_SHIFT (12) -#define R200_TEXGEN_4_INPUT_SHIFT (16) -#define R200_TEXGEN_5_INPUT_SHIFT (20) -#define R200_SE_TC_TEX_CYL_WRAP_CTL 0x22b8 -/* gap */ -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_UCP_IN_CLIP_SPACE (1<<0) -#define R200_UCP_IN_MODEL_SPACE (1<<1) -#define R200_UCP_ENABLE_0 (1<<2) -#define R200_UCP_ENABLE_1 (1<<3) -#define R200_UCP_ENABLE_2 (1<<4) -#define R200_UCP_ENABLE_3 (1<<5) -#define R200_UCP_ENABLE_4 (1<<6) -#define R200_UCP_ENABLE_5 (1<<7) -#define R200_TCL_FOG_MASK (3<<8) -#define R200_TCL_FOG_DISABLE (0<<8) -#define R200_TCL_FOG_EXP (1<<8) -#define R200_TCL_FOG_EXP2 (2<<8) -#define R200_TCL_FOG_LINEAR (3<<8) -#define R200_RNG_BASED_FOG (1<<10) -#define R200_CLIP_DISABLE (1<<11) -#define R200_CULL_FRONT_IS_CW (0<<28) -#define R200_CULL_FRONT_IS_CCW (1<<28) -#define R200_CULL_FRONT (1<<29) -#define R200_CULL_BACK (1<<30) -#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 -/* gap */ -#define R200_SE_VTX_ST_POS_0_X_4 0x2300 -#define R200_SE_VTX_ST_POS_0_Y_4 0x2304 -#define R200_SE_VTX_ST_POS_0_Z_4 0x2308 -#define R200_SE_VTX_ST_POS_0_W_4 0x230c -#define R200_SE_VTX_ST_NORM_0_X 0x2310 -#define R200_SE_VTX_ST_NORM_0_Y 0x2314 -#define R200_SE_VTX_ST_NORM_0_Z 0x2318 -#define R200_SE_VTX_ST_PVMS 0x231c -#define R200_SE_VTX_ST_CLR_0_R 0x2320 -#define R200_SE_VTX_ST_CLR_0_G 0x2324 -#define R200_SE_VTX_ST_CLR_0_B 0x2328 -#define R200_SE_VTX_ST_CLR_0_A 0x232c -#define R200_SE_VTX_ST_CLR_1_R 0x2330 -#define R200_SE_VTX_ST_CLR_1_G 0x2334 -#define R200_SE_VTX_ST_CLR_1_B 0x2338 -#define R200_SE_VTX_ST_CLR_1_A 0x233c -#define R200_SE_VTX_ST_CLR_2_R 0x2340 -#define R200_SE_VTX_ST_CLR_2_G 0x2344 -#define R200_SE_VTX_ST_CLR_2_B 0x2348 -#define R200_SE_VTX_ST_CLR_2_A 0x234c -#define R200_SE_VTX_ST_CLR_3_R 0x2350 -#define R200_SE_VTX_ST_CLR_3_G 0x2354 -#define R200_SE_VTX_ST_CLR_3_B 0x2358 -#define R200_SE_VTX_ST_CLR_3_A 0x235c -#define R200_SE_VTX_ST_CLR_4_R 0x2360 -#define R200_SE_VTX_ST_CLR_4_G 0x2364 -#define R200_SE_VTX_ST_CLR_4_B 0x2368 -#define R200_SE_VTX_ST_CLR_4_A 0x236c -#define R200_SE_VTX_ST_CLR_5_R 0x2370 -#define R200_SE_VTX_ST_CLR_5_G 0x2374 -#define R200_SE_VTX_ST_CLR_5_B 0x2378 -#define R200_SE_VTX_ST_CLR_5_A 0x237c -#define R200_SE_VTX_ST_CLR_6_R 0x2380 -#define R200_SE_VTX_ST_CLR_6_G 0x2384 -#define R200_SE_VTX_ST_CLR_6_B 0x2388 -#define R200_SE_VTX_ST_CLR_6_A 0x238c -#define R200_SE_VTX_ST_CLR_7_R 0x2390 -#define R200_SE_VTX_ST_CLR_7_G 0x2394 -#define R200_SE_VTX_ST_CLR_7_B 0x2398 -#define R200_SE_VTX_ST_CLR_7_A 0x239c -#define R200_SE_VTX_ST_TEX_0_S 0x23a0 -#define R200_SE_VTX_ST_TEX_0_T 0x23a4 -#define R200_SE_VTX_ST_TEX_0_R 0x23a8 -#define R200_SE_VTX_ST_TEX_0_Q 0x23ac -#define R200_SE_VTX_ST_TEX_1_S 0x23b0 -#define R200_SE_VTX_ST_TEX_1_T 0x23b4 -#define R200_SE_VTX_ST_TEX_1_R 0x23b8 -#define R200_SE_VTX_ST_TEX_1_Q 0x23bc -#define R200_SE_VTX_ST_TEX_2_S 0x23c0 -#define R200_SE_VTX_ST_TEX_2_T 0x23c4 -#define R200_SE_VTX_ST_TEX_2_R 0x23c8 -#define R200_SE_VTX_ST_TEX_2_Q 0x23cc -#define R200_SE_VTX_ST_TEX_3_S 0x23d0 -#define R200_SE_VTX_ST_TEX_3_T 0x23d4 -#define R200_SE_VTX_ST_TEX_3_R 0x23d8 -#define R200_SE_VTX_ST_TEX_3_Q 0x23dc -#define R200_SE_VTX_ST_TEX_4_S 0x23e0 -#define R200_SE_VTX_ST_TEX_4_T 0x23e4 -#define R200_SE_VTX_ST_TEX_4_R 0x23e8 -#define R200_SE_VTX_ST_TEX_4_Q 0x23ec -#define R200_SE_VTX_ST_TEX_5_S 0x23f0 -#define R200_SE_VTX_ST_TEX_5_T 0x23f4 -#define R200_SE_VTX_ST_TEX_5_R 0x23f8 -#define R200_SE_VTX_ST_TEX_5_Q 0x23fc -#define R200_SE_VTX_ST_PNT_SPRT_SZ 0x2400 -#define R200_SE_VTX_ST_DISC_FOG 0x2404 -#define R200_SE_VTX_ST_SHININESS_0 0x2408 -#define R200_SE_VTX_ST_SHININESS_1 0x240c -#define R200_SE_VTX_ST_BLND_WT_0 0x2410 -#define R200_SE_VTX_ST_BLND_WT_1 0x2414 -#define R200_SE_VTX_ST_BLND_WT_2 0x2418 -#define R200_SE_VTX_ST_BLND_WT_3 0x241c -#define R200_SE_VTX_ST_POS_1_X 0x2420 -#define R200_SE_VTX_ST_POS_1_Y 0x2424 -#define R200_SE_VTX_ST_POS_1_Z 0x2428 -#define R200_SE_VTX_ST_POS_1_W 0x242c -#define R200_SE_VTX_ST_NORM_1_X 0x2430 -#define R200_SE_VTX_ST_NORM_1_Y 0x2434 -#define R200_SE_VTX_ST_NORM_1_Z 0x2438 -#define R200_SE_VTX_ST_USR_CLR_0_R 0x2440 -#define R200_SE_VTX_ST_USR_CLR_0_G 0x2444 -#define R200_SE_VTX_ST_USR_CLR_0_B 0x2448 -#define R200_SE_VTX_ST_USR_CLR_0_A 0x244c -#define R200_SE_VTX_ST_USR_CLR_1_R 0x2450 -#define R200_SE_VTX_ST_USR_CLR_1_G 0x2454 -#define R200_SE_VTX_ST_USR_CLR_1_B 0x2458 -#define R200_SE_VTX_ST_USR_CLR_1_A 0x245c -#define R200_SE_VTX_ST_CLR_0_PKD 0x2460 -#define R200_SE_VTX_ST_CLR_1_PKD 0x2464 -#define R200_SE_VTX_ST_CLR_2_PKD 0x2468 -#define R200_SE_VTX_ST_CLR_3_PKD 0x246c -#define R200_SE_VTX_ST_CLR_4_PKD 0x2470 -#define R200_SE_VTX_ST_CLR_5_PKD 0x2474 -#define R200_SE_VTX_ST_CLR_6_PKD 0x2478 -#define R200_SE_VTX_ST_CLR_7_PKD 0x247c -#define R200_SE_VTX_ST_POS_0_X_2 0x2480 -#define R200_SE_VTX_ST_POS_0_Y_2 0x2484 -#define R200_SE_VTX_ST_PAR_CLR_LD 0x2488 -#define R200_SE_VTX_ST_USR_CLR_PKD 0x248c -#define R200_SE_VTX_ST_POS_0_X_3 0x2490 -#define R200_SE_VTX_ST_POS_0_Y_3 0x2494 -#define R200_SE_VTX_ST_POS_0_Z_3 0x2498 -#define R200_SE_VTX_ST_END_OF_PKT 0x249c -/* gap */ -#define R200_RE_POINTSIZE 0x2648 -#define R200_POINTSIZE_SHIFT 0 -#define R200_MAXPOINTSIZE_SHIFT 16 -/* gap */ -#define R200_RE_TOP_LEFT 0x26c0 -#define R200_RE_LEFT_SHIFT 0 -#define R200_RE_TOP_SHIFT 16 -#define R200_RE_MISC 0x26c4 -#define R200_STIPPLE_COORD_MASK 0x1f -#define R200_STIPPLE_X_OFFSET_SHIFT 0 -#define R200_STIPPLE_X_OFFSET_MASK (0x1f << 0) -#define R200_STIPPLE_Y_OFFSET_SHIFT 8 -#define R200_STIPPLE_Y_OFFSET_MASK (0x1f << 8) -#define R200_STIPPLE_LITTLE_BIT_ORDER (0 << 16) -#define R200_STIPPLE_BIG_BIT_ORDER (1 << 16) -/* gap */ -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_EXCLUSIVE_SCISSOR_0 0x01000000 -#define R200_EXCLUSIVE_SCISSOR_1 0x02000000 -#define R200_EXCLUSIVE_SCISSOR_2 0x04000000 -#define R200_SCISSOR_ENABLE_0 0x10000000 -#define R200_SCISSOR_ENABLE_1 0x20000000 -#define R200_SCISSOR_ENABLE_2 0x40000000 -/* gap */ -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_MAG_FILTER_NEAREST (0 << 0) -#define R200_MAG_FILTER_LINEAR (1 << 0) -#define R200_MAG_FILTER_MASK (1 << 0) -#define R200_MIN_FILTER_NEAREST (0 << 1) -#define R200_MIN_FILTER_LINEAR (1 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) -#define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) -#define R200_MIN_FILTER_MASK (15 << 1) -#define R200_MAX_ANISO_1_TO_1 (0 << 5) -#define R200_MAX_ANISO_2_TO_1 (1 << 5) -#define R200_MAX_ANISO_4_TO_1 (2 << 5) -#define R200_MAX_ANISO_8_TO_1 (3 << 5) -#define R200_MAX_ANISO_16_TO_1 (4 << 5) -#define R200_MAX_ANISO_MASK (7 << 5) -#define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) -#define R200_MAX_MIP_LEVEL_SHIFT 16 -#define R200_YUV_TO_RGB (1 << 20) -#define R200_YUV_TEMPERATURE_COOL (0 << 21) -#define R200_YUV_TEMPERATURE_HOT (1 << 21) -#define R200_YUV_TEMPERATURE_MASK (1 << 21) -#define R200_WRAPEN_S (1 << 22) -#define R200_CLAMP_S_WRAP (0 << 23) -#define R200_CLAMP_S_MIRROR (1 << 23) -#define R200_CLAMP_S_CLAMP_LAST (2 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) -#define R200_CLAMP_S_CLAMP_BORDER (4 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) -#define R200_CLAMP_S_CLAMP_GL (6 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) -#define R200_CLAMP_S_MASK (7 << 23) -#define R200_WRAPEN_T (1 << 26) -#define R200_CLAMP_T_WRAP (0 << 27) -#define R200_CLAMP_T_MIRROR (1 << 27) -#define R200_CLAMP_T_CLAMP_LAST (2 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) -#define R200_CLAMP_T_CLAMP_BORDER (4 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) -#define R200_CLAMP_T_CLAMP_GL (6 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) -#define R200_CLAMP_T_MASK (7 << 27) -#define R200_KILL_LT_ZERO (1 << 30) -#define R200_BORDER_MODE_OGL (0 << 31) -#define R200_BORDER_MODE_D3D (1 << 31) -#define R200_PP_TXFORMAT_0 0x2c04 -#define R200_TXFORMAT_I8 (0 << 0) -#define R200_TXFORMAT_AI88 (1 << 0) -#define R200_TXFORMAT_RGB332 (2 << 0) -#define R200_TXFORMAT_ARGB1555 (3 << 0) -#define R200_TXFORMAT_RGB565 (4 << 0) -#define R200_TXFORMAT_ARGB4444 (5 << 0) -#define R200_TXFORMAT_ARGB8888 (6 << 0) -#define R200_TXFORMAT_RGBA8888 (7 << 0) -#define R200_TXFORMAT_Y8 (8 << 0) -#define R200_TXFORMAT_AVYU4444 (9 << 0) -#define R200_TXFORMAT_VYUY422 (10 << 0) -#define R200_TXFORMAT_YVYU422 (11 << 0) -#define R200_TXFORMAT_DXT1 (12 << 0) -#define R200_TXFORMAT_DXT23 (14 << 0) -#define R200_TXFORMAT_DXT45 (15 << 0) -#define R200_TXFORMAT_FORMAT_MASK (31 << 0) -#define R200_TXFORMAT_FORMAT_SHIFT 0 -#define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) -#define R200_TXFORMAT_NON_POWER2 (1 << 7) -#define R200_TXFORMAT_WIDTH_MASK (15 << 8) -#define R200_TXFORMAT_WIDTH_SHIFT 8 -#define R200_TXFORMAT_HEIGHT_MASK (15 << 12) -#define R200_TXFORMAT_HEIGHT_SHIFT 12 -#define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ -#define R200_TXFORMAT_F5_WIDTH_SHIFT 16 -#define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) -#define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 -#define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) -#define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) -#define R200_TXFORMAT_ST_ROUTE_SHIFT 24 -#define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) -#define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) -#define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) -#define R200_PP_TXFORMAT_X_0 0x2c08 -#define R200_DEPTH_LOG2_MASK (0xf << 0) -#define R200_DEPTH_LOG2_SHIFT 0 -#define R200_VOLUME_FILTER_SHIFT 4 -#define R200_VOLUME_FILTER_MASK (1 << 4) -#define R200_VOLUME_FILTER_NEAREST (0 << 4) -#define R200_VOLUME_FILTER_LINEAR (1 << 4) -#define R200_WRAPEN_Q (1 << 8) -#define R200_CLAMP_Q_WRAP (0 << 9) -#define R200_CLAMP_Q_MIRROR (1 << 9) -#define R200_CLAMP_Q_CLAMP_LAST (2 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9) -#define R200_CLAMP_Q_CLAMP_BORDER (4 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (5 << 9) -#define R200_CLAMP_Q_CLAMP_GL (6 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) -#define R200_CLAMP_Q_MASK (7 << 9) -#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) -#define R200_MIN_MIP_LEVEL_SHIFT 12 -#define R200_TEXCOORD_NONPROJ (0 << 16) -#define R200_TEXCOORD_CUBIC_ENV (1 << 16) -#define R200_TEXCOORD_VOLUME (2 << 16) -#define R200_TEXCOORD_PROJ (3 << 16) -#define R200_TEXCOORD_DEPTH (4 << 16) -#define R200_TEXCOORD_1D_PROJ (5 << 16) -#define R200_TEXCOORD_1D (6 << 16) -#define R200_TEXCOORD_ZERO (7 << 16) -#define R200_TEXCOORD_MASK (7 << 16) -#define R200_LOD_BIAS_MASK (0xfff80000) -#define R200_LOD_BIAS_SHIFT 19 -#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ -#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ -#define R200_PP_BORDER_COLOR_0 0x2c14 -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_FACE_WIDTH_1_SHIFT 0 -#define R200_FACE_HEIGHT_1_SHIFT 4 -#define R200_FACE_WIDTH_1_MASK (0xf << 0) -#define R200_FACE_HEIGHT_1_MASK (0xf << 4) -#define R200_FACE_WIDTH_2_SHIFT 8 -#define R200_FACE_HEIGHT_2_SHIFT 12 -#define R200_FACE_WIDTH_2_MASK (0xf << 8) -#define R200_FACE_HEIGHT_2_MASK (0xf << 12) -#define R200_FACE_WIDTH_3_SHIFT 16 -#define R200_FACE_HEIGHT_3_SHIFT 20 -#define R200_FACE_WIDTH_3_MASK (0xf << 16) -#define R200_FACE_HEIGHT_3_MASK (0xf << 20) -#define R200_FACE_WIDTH_4_SHIFT 24 -#define R200_FACE_HEIGHT_4_SHIFT 28 -#define R200_FACE_WIDTH_4_MASK (0xf << 24) -#define R200_FACE_HEIGHT_4_MASK (0xf << 28) -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFORMAT_1 0x2c24 -#define R200_PP_TXFORMAT_X_1 0x2c28 -#define R200_PP_TXSIZE_1 0x2c2c -#define R200_PP_TXPITCH_1 0x2c30 -#define R200_PP_BORDER_COLOR_1 0x2c34 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFORMAT_2 0x2c44 -#define R200_PP_TXSIZE_2 0x2c4c -#define R200_PP_TXFORMAT_X_2 0x2c48 -#define R200_PP_TXPITCH_2 0x2c50 -#define R200_PP_BORDER_COLOR_2 0x2c54 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFORMAT_3 0x2c64 -#define R200_PP_TXSIZE_3 0x2c6c -#define R200_PP_TXFORMAT_X_3 0x2c68 -#define R200_PP_TXPITCH_3 0x2c70 -#define R200_PP_BORDER_COLOR_3 0x2c74 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFORMAT_4 0x2c84 -#define R200_PP_TXSIZE_4 0x2c8c -#define R200_PP_TXFORMAT_X_4 0x2c88 -#define R200_PP_TXPITCH_4 0x2c90 -#define R200_PP_BORDER_COLOR_4 0x2c94 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFORMAT_5 0x2ca4 -#define R200_PP_TXSIZE_5 0x2cac -#define R200_PP_TXFORMAT_X_5 0x2ca8 -#define R200_PP_TXPITCH_5 0x2cb0 -#define R200_PP_BORDER_COLOR_5 0x2cb4 -#define R200_PP_CUBIC_FACES_5 0x2cb8 -/* gap */ -#define R200_PP_CNTL_X 0x2cc4 -/* gap */ -#define R200_PP_TXOFFSET_0 0x2d00 -#define R200_TXO_ENDIAN_NO_SWAP (0 << 0) -#define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) -#define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) -#define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -#define R200_TXO_OFFSET_MASK 0xffffffe0 -#define R200_TXO_OFFSET_SHIFT 5 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c -/* gap */ -#define R200_PP_TAM_DEBUG3 0x2d9c -/* gap */ -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_PP_TFACTOR_1 0x2ee4 -#define R200_PP_TFACTOR_2 0x2ee8 -#define R200_PP_TFACTOR_3 0x2eec -#define R200_PP_TFACTOR_4 0x2ef0 -#define R200_PP_TFACTOR_5 0x2ef4 -/* gap */ -#define R200_PP_TXCBLEND_0 0x2f00 -#define R200_TXC_ARG_A_ZERO (0) -#define R200_TXC_ARG_A_CURRENT_COLOR (2) -#define R200_TXC_ARG_A_CURRENT_ALPHA (3) -#define R200_TXC_ARG_A_DIFFUSE_COLOR (4) -#define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) -#define R200_TXC_ARG_A_SPECULAR_COLOR (6) -#define R200_TXC_ARG_A_SPECULAR_ALPHA (7) -#define R200_TXC_ARG_A_TFACTOR_COLOR (8) -#define R200_TXC_ARG_A_TFACTOR_ALPHA (9) -#define R200_TXC_ARG_A_R0_COLOR (10) -#define R200_TXC_ARG_A_R0_ALPHA (11) -#define R200_TXC_ARG_A_R1_COLOR (12) -#define R200_TXC_ARG_A_R1_ALPHA (13) -#define R200_TXC_ARG_A_R2_COLOR (14) -#define R200_TXC_ARG_A_R2_ALPHA (15) -#define R200_TXC_ARG_A_R3_COLOR (16) -#define R200_TXC_ARG_A_R3_ALPHA (17) -#define R200_TXC_ARG_A_R4_COLOR (18) -#define R200_TXC_ARG_A_R4_ALPHA (19) -#define R200_TXC_ARG_A_R5_COLOR (20) -#define R200_TXC_ARG_A_R5_ALPHA (21) -#define R200_TXC_ARG_A_TFACTOR1_COLOR (26) -#define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) -#define R200_TXC_ARG_A_MASK (31 << 0) -#define R200_TXC_ARG_A_SHIFT 0 -#define R200_TXC_ARG_B_ZERO (0<<5) -#define R200_TXC_ARG_B_CURRENT_COLOR (2<<5) -#define R200_TXC_ARG_B_CURRENT_ALPHA (3<<5) -#define R200_TXC_ARG_B_DIFFUSE_COLOR (4<<5) -#define R200_TXC_ARG_B_DIFFUSE_ALPHA (5<<5) -#define R200_TXC_ARG_B_SPECULAR_COLOR (6<<5) -#define R200_TXC_ARG_B_SPECULAR_ALPHA (7<<5) -#define R200_TXC_ARG_B_TFACTOR_COLOR (8<<5) -#define R200_TXC_ARG_B_TFACTOR_ALPHA (9<<5) -#define R200_TXC_ARG_B_R0_COLOR (10<<5) -#define R200_TXC_ARG_B_R0_ALPHA (11<<5) -#define R200_TXC_ARG_B_R1_COLOR (12<<5) -#define R200_TXC_ARG_B_R1_ALPHA (13<<5) -#define R200_TXC_ARG_B_R2_COLOR (14<<5) -#define R200_TXC_ARG_B_R2_ALPHA (15<<5) -#define R200_TXC_ARG_B_R3_COLOR (16<<5) -#define R200_TXC_ARG_B_R3_ALPHA (17<<5) -#define R200_TXC_ARG_B_R4_COLOR (18<<5) -#define R200_TXC_ARG_B_R4_ALPHA (19<<5) -#define R200_TXC_ARG_B_R5_COLOR (20<<5) -#define R200_TXC_ARG_B_R5_ALPHA (21<<5) -#define R200_TXC_ARG_B_TFACTOR1_COLOR (26<<5) -#define R200_TXC_ARG_B_TFACTOR1_ALPHA (27<<5) -#define R200_TXC_ARG_B_MASK (31 << 5) -#define R200_TXC_ARG_B_SHIFT 5 -#define R200_TXC_ARG_C_ZERO (0<<10) -#define R200_TXC_ARG_C_CURRENT_COLOR (2<<10) -#define R200_TXC_ARG_C_CURRENT_ALPHA (3<<10) -#define R200_TXC_ARG_C_DIFFUSE_COLOR (4<<10) -#define R200_TXC_ARG_C_DIFFUSE_ALPHA (5<<10) -#define R200_TXC_ARG_C_SPECULAR_COLOR (6<<10) -#define R200_TXC_ARG_C_SPECULAR_ALPHA (7<<10) -#define R200_TXC_ARG_C_TFACTOR_COLOR (8<<10) -#define R200_TXC_ARG_C_TFACTOR_ALPHA (9<<10) -#define R200_TXC_ARG_C_R0_COLOR (10<<10) -#define R200_TXC_ARG_C_R0_ALPHA (11<<10) -#define R200_TXC_ARG_C_R1_COLOR (12<<10) -#define R200_TXC_ARG_C_R1_ALPHA (13<<10) -#define R200_TXC_ARG_C_R2_COLOR (14<<10) -#define R200_TXC_ARG_C_R2_ALPHA (15<<10) -#define R200_TXC_ARG_C_R3_COLOR (16<<10) -#define R200_TXC_ARG_C_R3_ALPHA (17<<10) -#define R200_TXC_ARG_C_R4_COLOR (18<<10) -#define R200_TXC_ARG_C_R4_ALPHA (19<<10) -#define R200_TXC_ARG_C_R5_COLOR (20<<10) -#define R200_TXC_ARG_C_R5_ALPHA (21<<10) -#define R200_TXC_ARG_C_TFACTOR1_COLOR (26<<10) -#define R200_TXC_ARG_C_TFACTOR1_ALPHA (27<<10) -#define R200_TXC_ARG_C_MASK (31 << 10) -#define R200_TXC_ARG_C_SHIFT 10 -#define R200_TXC_COMP_ARG_A (1 << 16) -#define R200_TXC_COMP_ARG_A_SHIFT (16) -#define R200_TXC_BIAS_ARG_A (1 << 17) -#define R200_TXC_SCALE_ARG_A (1 << 18) -#define R200_TXC_NEG_ARG_A (1 << 19) -#define R200_TXC_COMP_ARG_B (1 << 20) -#define R200_TXC_COMP_ARG_B_SHIFT (20) -#define R200_TXC_BIAS_ARG_B (1 << 21) -#define R200_TXC_SCALE_ARG_B (1 << 22) -#define R200_TXC_NEG_ARG_B (1 << 23) -#define R200_TXC_COMP_ARG_C (1 << 24) -#define R200_TXC_COMP_ARG_C_SHIFT (24) -#define R200_TXC_BIAS_ARG_C (1 << 25) -#define R200_TXC_SCALE_ARG_C (1 << 26) -#define R200_TXC_NEG_ARG_C (1 << 27) -#define R200_TXC_OP_MADD (0 << 28) -#define R200_TXC_OP_CND0 (2 << 28) -#define R200_TXC_OP_LERP (3 << 28) -#define R200_TXC_OP_DOT3 (4 << 28) -#define R200_TXC_OP_DOT4 (5 << 28) -#define R200_TXC_OP_CONDITIONAL (6 << 28) -#define R200_TXC_OP_DOT2_ADD (7 << 28) -#define R200_TXC_OP_MASK (7 << 28) -#define R200_PP_TXCBLEND2_0 0x2f04 -#define R200_TXC_TFACTOR_SEL_SHIFT 0 -#define R200_TXC_TFACTOR_SEL_MASK 0x7 -#define R200_TXC_TFACTOR1_SEL_SHIFT 4 -#define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXC_SCALE_SHIFT 8 -#define R200_TXC_SCALE_MASK (7 << 8) -#define R200_TXC_SCALE_1X (0 << 8) -#define R200_TXC_SCALE_2X (1 << 8) -#define R200_TXC_SCALE_4X (2 << 8) -#define R200_TXC_SCALE_8X (3 << 8) -#define R200_TXC_SCALE_INV2 (5 << 8) -#define R200_TXC_SCALE_INV4 (6 << 8) -#define R200_TXC_SCALE_INV8 (7 << 8) -#define R200_TXC_CLAMP_SHIFT 12 -#define R200_TXC_CLAMP_MASK (3 << 12) -#define R200_TXC_CLAMP_WRAP (0 << 12) -#define R200_TXC_CLAMP_0_1 (1 << 12) -#define R200_TXC_CLAMP_8_8 (2 << 12) -#define R200_TXC_OUTPUT_REG_MASK (7 << 16) -#define R200_TXC_OUTPUT_REG_NONE (0 << 16) -#define R200_TXC_OUTPUT_REG_R0 (1 << 16) -#define R200_TXC_OUTPUT_REG_R1 (2 << 16) -#define R200_TXC_OUTPUT_REG_R2 (3 << 16) -#define R200_TXC_OUTPUT_REG_R3 (4 << 16) -#define R200_TXC_OUTPUT_REG_R4 (5 << 16) -#define R200_TXC_OUTPUT_REG_R5 (6 << 16) -#define R200_TXC_OUTPUT_MASK_MASK (7 << 20) -#define R200_TXC_OUTPUT_MASK_RGB (0 << 20) -#define R200_TXC_OUTPUT_MASK_RG (1 << 20) -#define R200_TXC_OUTPUT_MASK_RB (2 << 20) -#define R200_TXC_OUTPUT_MASK_R (3 << 20) -#define R200_TXC_OUTPUT_MASK_GB (4 << 20) -#define R200_TXC_OUTPUT_MASK_G (5 << 20) -#define R200_TXC_OUTPUT_MASK_B (6 << 20) -#define R200_TXC_OUTPUT_MASK_NONE (7 << 20) -#define R200_TXC_REPL_NORMAL 0 -#define R200_TXC_REPL_RED 1 -#define R200_TXC_REPL_GREEN 2 -#define R200_TXC_REPL_BLUE 3 -#define R200_TXC_REPL_ARG_A_SHIFT 26 -#define R200_TXC_REPL_ARG_A_MASK (3 << 26) -#define R200_TXC_REPL_ARG_B_SHIFT 28 -#define R200_TXC_REPL_ARG_B_MASK (3 << 28) -#define R200_TXC_REPL_ARG_C_SHIFT 30 -#define R200_TXC_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXABLEND_0 0x2f08 -#define R200_TXA_ARG_A_ZERO (0) -#define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ -#define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ -#define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) -#define R200_TXA_ARG_A_DIFFUSE_BLUE (5) -#define R200_TXA_ARG_A_SPECULAR_ALPHA (6) -#define R200_TXA_ARG_A_SPECULAR_BLUE (7) -#define R200_TXA_ARG_A_TFACTOR_ALPHA (8) -#define R200_TXA_ARG_A_TFACTOR_BLUE (9) -#define R200_TXA_ARG_A_R0_ALPHA (10) -#define R200_TXA_ARG_A_R0_BLUE (11) -#define R200_TXA_ARG_A_R1_ALPHA (12) -#define R200_TXA_ARG_A_R1_BLUE (13) -#define R200_TXA_ARG_A_R2_ALPHA (14) -#define R200_TXA_ARG_A_R2_BLUE (15) -#define R200_TXA_ARG_A_R3_ALPHA (16) -#define R200_TXA_ARG_A_R3_BLUE (17) -#define R200_TXA_ARG_A_R4_ALPHA (18) -#define R200_TXA_ARG_A_R4_BLUE (19) -#define R200_TXA_ARG_A_R5_ALPHA (20) -#define R200_TXA_ARG_A_R5_BLUE (21) -#define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) -#define R200_TXA_ARG_A_TFACTOR1_BLUE (27) -#define R200_TXA_ARG_A_MASK (31 << 0) -#define R200_TXA_ARG_A_SHIFT 0 -#define R200_TXA_ARG_B_ZERO (0<<5) -#define R200_TXA_ARG_B_CURRENT_ALPHA (2<<5) /* guess */ -#define R200_TXA_ARG_B_CURRENT_BLUE (3<<5) /* guess */ -#define R200_TXA_ARG_B_DIFFUSE_ALPHA (4<<5) -#define R200_TXA_ARG_B_DIFFUSE_BLUE (5<<5) -#define R200_TXA_ARG_B_SPECULAR_ALPHA (6<<5) -#define R200_TXA_ARG_B_SPECULAR_BLUE (7<<5) -#define R200_TXA_ARG_B_TFACTOR_ALPHA (8<<5) -#define R200_TXA_ARG_B_TFACTOR_BLUE (9<<5) -#define R200_TXA_ARG_B_R0_ALPHA (10<<5) -#define R200_TXA_ARG_B_R0_BLUE (11<<5) -#define R200_TXA_ARG_B_R1_ALPHA (12<<5) -#define R200_TXA_ARG_B_R1_BLUE (13<<5) -#define R200_TXA_ARG_B_R2_ALPHA (14<<5) -#define R200_TXA_ARG_B_R2_BLUE (15<<5) -#define R200_TXA_ARG_B_R3_ALPHA (16<<5) -#define R200_TXA_ARG_B_R3_BLUE (17<<5) -#define R200_TXA_ARG_B_R4_ALPHA (18<<5) -#define R200_TXA_ARG_B_R4_BLUE (19<<5) -#define R200_TXA_ARG_B_R5_ALPHA (20<<5) -#define R200_TXA_ARG_B_R5_BLUE (21<<5) -#define R200_TXA_ARG_B_TFACTOR1_ALPHA (26<<5) -#define R200_TXA_ARG_B_TFACTOR1_BLUE (27<<5) -#define R200_TXA_ARG_B_MASK (31 << 5) -#define R200_TXA_ARG_B_SHIFT 5 -#define R200_TXA_ARG_C_ZERO (0<<10) -#define R200_TXA_ARG_C_CURRENT_ALPHA (2<<10) /* guess */ -#define R200_TXA_ARG_C_CURRENT_BLUE (3<<10) /* guess */ -#define R200_TXA_ARG_C_DIFFUSE_ALPHA (4<<10) -#define R200_TXA_ARG_C_DIFFUSE_BLUE (5<<10) -#define R200_TXA_ARG_C_SPECULAR_ALPHA (6<<10) -#define R200_TXA_ARG_C_SPECULAR_BLUE (7<<10) -#define R200_TXA_ARG_C_TFACTOR_ALPHA (8<<10) -#define R200_TXA_ARG_C_TFACTOR_BLUE (9<<10) -#define R200_TXA_ARG_C_R0_ALPHA (10<<10) -#define R200_TXA_ARG_C_R0_BLUE (11<<10) -#define R200_TXA_ARG_C_R1_ALPHA (12<<10) -#define R200_TXA_ARG_C_R1_BLUE (13<<10) -#define R200_TXA_ARG_C_R2_ALPHA (14<<10) -#define R200_TXA_ARG_C_R2_BLUE (15<<10) -#define R200_TXA_ARG_C_R3_ALPHA (16<<10) -#define R200_TXA_ARG_C_R3_BLUE (17<<10) -#define R200_TXA_ARG_C_R4_ALPHA (18<<10) -#define R200_TXA_ARG_C_R4_BLUE (19<<10) -#define R200_TXA_ARG_C_R5_ALPHA (20<<10) -#define R200_TXA_ARG_C_R5_BLUE (21<<10) -#define R200_TXA_ARG_C_TFACTOR1_ALPHA (26<<10) -#define R200_TXA_ARG_C_TFACTOR1_BLUE (27<<10) -#define R200_TXA_ARG_C_MASK (31 << 10) -#define R200_TXA_ARG_C_SHIFT 10 -#define R200_TXA_COMP_ARG_A (1 << 16) -#define R200_TXA_COMP_ARG_A_SHIFT (16) -#define R200_TXA_BIAS_ARG_A (1 << 17) -#define R200_TXA_SCALE_ARG_A (1 << 18) -#define R200_TXA_NEG_ARG_A (1 << 19) -#define R200_TXA_COMP_ARG_B (1 << 20) -#define R200_TXA_COMP_ARG_B_SHIFT (20) -#define R200_TXA_BIAS_ARG_B (1 << 21) -#define R200_TXA_SCALE_ARG_B (1 << 22) -#define R200_TXA_NEG_ARG_B (1 << 23) -#define R200_TXA_COMP_ARG_C (1 << 24) -#define R200_TXA_COMP_ARG_C_SHIFT (24) -#define R200_TXA_BIAS_ARG_C (1 << 25) -#define R200_TXA_SCALE_ARG_C (1 << 26) -#define R200_TXA_NEG_ARG_C (1 << 27) -#define R200_TXA_OP_MADD (0 << 28) -#define R200_TXA_OP_CND0 (2 << 28) -#define R200_TXA_OP_LERP (3 << 28) -#define R200_TXA_OP_CONDITIONAL (6 << 28) -#define R200_TXA_OP_MASK (7 << 28) -#define R200_PP_TXABLEND2_0 0x2f0c -#define R200_TXA_TFACTOR_SEL_SHIFT 0 -#define R200_TXA_TFACTOR_SEL_MASK 0x7 -#define R200_TXA_TFACTOR1_SEL_SHIFT 4 -#define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXA_SCALE_SHIFT 8 -#define R200_TXA_SCALE_MASK (7 << 8) -#define R200_TXA_SCALE_1X (0 << 8) -#define R200_TXA_SCALE_2X (1 << 8) -#define R200_TXA_SCALE_4X (2 << 8) -#define R200_TXA_SCALE_8X (3 << 8) -#define R200_TXA_SCALE_INV2 (5 << 8) -#define R200_TXA_SCALE_INV4 (6 << 8) -#define R200_TXA_SCALE_INV8 (7 << 8) -#define R200_TXA_CLAMP_SHIFT 12 -#define R200_TXA_CLAMP_MASK (3 << 12) -#define R200_TXA_CLAMP_WRAP (0 << 12) -#define R200_TXA_CLAMP_0_1 (1 << 12) -#define R200_TXA_CLAMP_8_8 (2 << 12) -#define R200_TXA_OUTPUT_REG_MASK (7 << 16) -#define R200_TXA_OUTPUT_REG_NONE (0 << 16) -#define R200_TXA_OUTPUT_REG_R0 (1 << 16) -#define R200_TXA_OUTPUT_REG_R1 (2 << 16) -#define R200_TXA_OUTPUT_REG_R2 (3 << 16) -#define R200_TXA_OUTPUT_REG_R3 (4 << 16) -#define R200_TXA_OUTPUT_REG_R4 (5 << 16) -#define R200_TXA_OUTPUT_REG_R5 (6 << 16) -#define R200_TXA_DOT_ALPHA (1 << 20) -#define R200_TXA_REPL_NORMAL 0 -#define R200_TXA_REPL_RED 1 -#define R200_TXA_REPL_GREEN 2 -#define R200_TXA_REPL_ARG_A_SHIFT 26 -#define R200_TXA_REPL_ARG_A_MASK (3 << 26) -#define R200_TXA_REPL_ARG_B_SHIFT 28 -#define R200_TXA_REPL_ARG_B_MASK (3 << 28) -#define R200_TXA_REPL_ARG_C_SHIFT 30 -#define R200_TXA_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXCBLEND_1 0x2f10 -#define R200_PP_TXCBLEND2_1 0x2f14 -#define R200_PP_TXABLEND_1 0x2f18 -#define R200_PP_TXABLEND2_1 0x2f1c -#define R200_PP_TXCBLEND_2 0x2f20 -#define R200_PP_TXCBLEND2_2 0x2f24 -#define R200_PP_TXABLEND_2 0x2f28 -#define R200_PP_TXABLEND2_2 0x2f2c -#define R200_PP_TXCBLEND_3 0x2f30 -#define R200_PP_TXCBLEND2_3 0x2f34 -#define R200_PP_TXABLEND_3 0x2f38 -#define R200_PP_TXABLEND2_3 0x2f3c -#define R200_PP_TXCBLEND_4 0x2f40 -#define R200_PP_TXCBLEND2_4 0x2f44 -#define R200_PP_TXABLEND_4 0x2f48 -#define R200_PP_TXABLEND2_4 0x2f4c -#define R200_PP_TXCBLEND_5 0x2f50 -#define R200_PP_TXCBLEND2_5 0x2f54 -#define R200_PP_TXABLEND_5 0x2f58 -#define R200_PP_TXABLEND2_5 0x2f5c -#define R200_PP_TXCBLEND_6 0x2f60 -#define R200_PP_TXCBLEND2_6 0x2f64 -#define R200_PP_TXABLEND_6 0x2f68 -#define R200_PP_TXABLEND2_6 0x2f6c -#define R200_PP_TXCBLEND_7 0x2f70 -#define R200_PP_TXCBLEND2_7 0x2f74 -#define R200_PP_TXABLEND_7 0x2f78 -#define R200_PP_TXABLEND2_7 0x2f7c -/* gap */ -#define R200_RB3D_BLENDCOLOR 0x3218 /* ARGB 8888 */ -#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCTL */ -#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCTL */ - -/* - * Offsets in TCL vector state. NOTE: Hardwiring matrix positions. - * Multiple contexts could collaberate to eliminate state bouncing. - */ -#define R200_VS_LIGHT_AMBIENT_ADDR 0x00000028 -#define R200_VS_LIGHT_DIFFUSE_ADDR 0x00000030 -#define R200_VS_LIGHT_SPECULAR_ADDR 0x00000038 -#define R200_VS_LIGHT_DIRPOS_ADDR 0x00000040 -#define R200_VS_LIGHT_HWVSPOT_ADDR 0x00000048 -#define R200_VS_LIGHT_ATTENUATION_ADDR 0x00000050 -#define R200_VS_SPOT_DUAL_CONE 0x00000058 -#define R200_VS_GLOBAL_AMBIENT_ADDR 0x0000005C -#define R200_VS_FOG_PARAM_ADDR 0x0000005D -#define R200_VS_EYE_VECTOR_ADDR 0x0000005E -#define R200_VS_UCP_ADDR 0x00000060 -#define R200_VS_PNT_SPRITE_VPORT_SCALE 0x00000068 -#define R200_VS_MATRIX_0_MV 0x00000080 -#define R200_VS_MATRIX_1_INV_MV 0x00000084 -#define R200_VS_MATRIX_2_MVP 0x00000088 -#define R200_VS_MATRIX_3_TEX0 0x0000008C -#define R200_VS_MATRIX_4_TEX1 0x00000090 -#define R200_VS_MATRIX_5_TEX2 0x00000094 -#define R200_VS_MATRIX_6_TEX3 0x00000098 -#define R200_VS_MATRIX_7_TEX4 0x0000009C -#define R200_VS_MATRIX_8_TEX5 0x000000A0 -#define R200_VS_MAT_0_EMISS 0x000000B0 -#define R200_VS_MAT_0_AMB 0x000000B1 -#define R200_VS_MAT_0_DIF 0x000000B2 -#define R200_VS_MAT_0_SPEC 0x000000B3 -#define R200_VS_MAT_1_EMISS 0x000000B4 -#define R200_VS_MAT_1_AMB 0x000000B5 -#define R200_VS_MAT_1_DIF 0x000000B6 -#define R200_VS_MAT_1_SPEC 0x000000B7 -#define R200_VS_EYE2CLIP_MTX 0x000000B8 -#define R200_VS_PNT_SPRITE_ATT_CONST 0x000000BC -#define R200_VS_PNT_SPRITE_EYE_IN_MODEL 0x000000BD -#define R200_VS_PNT_SPRITE_CLAMP 0x000000BE -#define R200_VS_MAX 0x000001C0 - -/* - * Offsets in TCL scalar state - */ -#define R200_SS_LIGHT_DCD_ADDR 0x00000000 -#define R200_SS_LIGHT_DCM_ADDR 0x00000008 -#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR 0x00000010 -#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR 0x00000018 -#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR 0x00000020 -#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD 0x00000028 -#define R200_SS_LIGHT_RANGE_ATT_CONST 0x00000030 -#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR 0x00000080 -#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081 -#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR 0x00000082 -#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083 -#define R200_SS_MAT_0_SHININESS 0x00000100 -#define R200_SS_MAT_1_SHININESS 0x00000101 - -/* - * Matrix indices - */ -#define R200_MTX_MV 0 -#define R200_MTX_IMV 1 -#define R200_MTX_MVP 2 -#define R200_MTX_TEX0 3 -#define R200_MTX_TEX1 4 -#define R200_MTX_TEX2 5 -#define R200_MTX_TEX3 6 -#define R200_MTX_TEX4 7 -#define R200_MTX_TEX5 8 - -/* Color formats for 2d packets - */ -#define R200_CP_COLOR_FORMAT_CI8 2 -#define R200_CP_COLOR_FORMAT_ARGB1555 3 -#define R200_CP_COLOR_FORMAT_RGB565 4 -#define R200_CP_COLOR_FORMAT_ARGB8888 6 -#define R200_CP_COLOR_FORMAT_RGB332 7 -#define R200_CP_COLOR_FORMAT_RGB8 9 -#define R200_CP_COLOR_FORMAT_ARGB4444 15 - -/* - * CP type-3 packets - */ -#define R200_CP_CMD_NOP 0xC0001000 -#define R200_CP_CMD_NEXT_CHAR 0xC0001900 -#define R200_CP_CMD_PLY_NEXTSCAN 0xC0001D00 -#define R200_CP_CMD_SET_SCISSORS 0xC0001E00 -#define R200_CP_CMD_LOAD_MICROCODE 0xC0002400 -#define R200_CP_CMD_WAIT_FOR_IDLE 0xC0002600 -#define R200_CP_CMD_3D_DRAW_VBUF 0xC0002800 -#define R200_CP_CMD_3D_DRAW_IMMD 0xC0002900 -#define R200_CP_CMD_3D_DRAW_INDX 0xC0002A00 -#define R200_CP_CMD_LOAD_PALETTE 0xC0002C00 -#define R200_CP_CMD_3D_LOAD_VBPNTR 0xC0002F00 -#define R200_CP_CMD_INDX_BUFFER 0xC0003300 -#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 -#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 -#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 -#define R200_CP_CMD_PAINT 0xC0009100 -#define R200_CP_CMD_BITBLT 0xC0009200 -#define R200_CP_CMD_SMALLTEXT 0xC0009300 -#define R200_CP_CMD_HOSTDATA_BLT 0xC0009400 -#define R200_CP_CMD_POLYLINE 0xC0009500 -#define R200_CP_CMD_POLYSCANLINES 0xC0009800 -#define R200_CP_CMD_PAINT_MULTI 0xC0009A00 -#define R200_CP_CMD_BITBLT_MULTI 0xC0009B00 -#define R200_CP_CMD_TRANS_BITBLT 0xC0009C00 - -#endif diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h deleted file mode 100644 index 3e1a9c8ba19..00000000000 --- a/src/mesa/drivers/dri/r300/r200_state.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __R200_STATE_H__ -#define __R200_STATE_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "r200_context.h" - -extern void r200InitState(r200ContextPtr rmesa); -extern void r200InitStateFuncs(struct dd_function_table *functions); -extern void r200InitTnlFuncs(GLcontext * ctx); - -extern void r200UpdateMaterial(GLcontext * ctx); - -extern void r200UpdateViewportOffset(GLcontext * ctx); -extern void r200UpdateWindow(GLcontext * ctx); - -extern void r200ValidateState(GLcontext * ctx); - -extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg); - -extern void r200LightingSpaceChange(GLcontext * ctx); - -#endif -#endif diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 54eb081d055..d10a9d87d31 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -44,7 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -73,6 +73,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int future_hw_tcl_on=1; int hw_tcl_on=1; +#define need_GL_EXT_stencil_two_side #define need_GL_ARB_multisample #define need_GL_ARB_texture_compression #define need_GL_ARB_vertex_buffer_object @@ -126,6 +127,10 @@ const struct dri_extension card_extensions[] = { {NULL, NULL} }; +const struct dri_extension stencil_two_side[] = { + {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions}, +}; + extern struct tnl_pipeline_stage _r300_render_stage; extern const struct tnl_pipeline_stage _r300_tcl_stage; extern const struct tnl_pipeline_stage _r300_texrect_stage; @@ -195,6 +200,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, */ driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, screen->driScreen->myNum, "r300"); + r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, + "def_max_anisotropy"); //r300->texmicrotile = GL_TRUE; @@ -287,7 +294,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); @@ -300,7 +307,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials(ctx, GL_TRUE); +/* _tnl_isolate_materials(ctx, GL_TRUE); */ /* Configure swrast and TNL to match hardware characteristics: */ @@ -331,6 +338,9 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, driInitExtensions(ctx, card_extensions, GL_TRUE); + if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0) + driInitSingleExtension(ctx, stencil_two_side); + if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); _mesa_enable_extension( ctx, "GL_S3_s3tc" ); @@ -478,7 +488,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) _swsetup_DestroyContext(r300->radeon.glCtx); _tnl_ProgramCacheDestroy(r300->radeon.glCtx); _tnl_DestroyContext(r300->radeon.glCtx); - _ac_DestroyContext(r300->radeon.glCtx); + _vbo_DestroyContext(r300->radeon.glCtx); _swrast_DestroyContext(r300->radeon.glCtx); if (r300->dma.current.buf) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index dd3ecbb2357..48b50bca653 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -48,7 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #define USER_BUFFERS -#define RADEON_VTXFMT_A +/* KW: Disable this code. Driver should hook into vbo module + * directly, see i965 driver for example. + */ +/* #define RADEON_VTXFMT_A */ #define HW_VBOS /* We don't handle 16 bits elts swapping yet */ @@ -726,6 +729,11 @@ struct r300_fragment_program { GLboolean params_uptodate; int max_temp_idx; + + /* the index of the sin constant is stored here */ + GLint const_sin[2]; + + GLuint optimization; }; #define R300_MAX_AOS_ARRAYS 16 @@ -754,7 +762,7 @@ struct radeon_vertex_buffer { struct dt AttribPtr[VERT_ATTRIB_MAX]; - struct tnl_prim *Primitive; + const struct _mesa_prim *Primitive; GLuint PrimitiveCount; GLint LockFirst; GLsizei LockCount; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 32c0128eaa2..8e45bd54030 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -33,7 +33,6 @@ /*TODO'S * - * - COS/SIN/SCS instructions * - Depth write, WPOS/FOGC inputs * - FogOption * - Verify results of opcodes for accuracy, I've only checked them @@ -51,18 +50,110 @@ #include "r300_fragprog.h" #include "r300_reg.h" +/* + * Usefull macros and values + */ +#define ERROR(fmt, args...) do { \ + fprintf(stderr, "%s::%s(): " fmt "\n", \ + __FILE__, __func__, ##args); \ + rp->error = GL_TRUE; \ + } while(0) + #define PFS_INVAL 0xFFFFFFFF #define COMPILE_STATE struct r300_pfs_compile_state *cs = rp->cs -static void dump_program(struct r300_fragment_program *rp); -static void emit_arith(struct r300_fragment_program *rp, int op, - pfs_reg_t dest, int mask, - pfs_reg_t src0, pfs_reg_t src1, pfs_reg_t src2, - int flags); +#define SWIZZLE_XYZ 0 +#define SWIZZLE_XXX 1 +#define SWIZZLE_YYY 2 +#define SWIZZLE_ZZZ 3 +#define SWIZZLE_WWW 4 +#define SWIZZLE_YZX 5 +#define SWIZZLE_ZXY 6 +#define SWIZZLE_WZY 7 +#define SWIZZLE_111 8 +#define SWIZZLE_000 9 +#define SWIZZLE_HHH 10 + +#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \ + ((SWIZZLE_##x<<0)| \ + (SWIZZLE_##y<<3)| \ + (SWIZZLE_##z<<6)| \ + (SWIZZLE_##w<<9)), \ + 0) + +#define REG_TYPE_INPUT 0 +#define REG_TYPE_OUTPUT 1 +#define REG_TYPE_TEMP 2 +#define REG_TYPE_CONST 3 + +#define REG_TYPE_SHIFT 0 +#define REG_INDEX_SHIFT 2 +#define REG_VSWZ_SHIFT 8 +#define REG_SSWZ_SHIFT 13 +#define REG_NEGV_SHIFT 18 +#define REG_NEGS_SHIFT 19 +#define REG_ABS_SHIFT 20 +#define REG_NO_USE_SHIFT 21 +#define REG_VALID_SHIFT 22 + +#define REG_TYPE_MASK (0x03 << REG_TYPE_SHIFT) +#define REG_INDEX_MASK (0x3F << REG_INDEX_SHIFT) +#define REG_VSWZ_MASK (0x1F << REG_VSWZ_SHIFT) +#define REG_SSWZ_MASK (0x1F << REG_SSWZ_SHIFT) +#define REG_NEGV_MASK (0x01 << REG_NEGV_SHIFT) +#define REG_NEGS_MASK (0x01 << REG_NEGS_SHIFT) +#define REG_ABS_MASK (0x01 << REG_ABS_SHIFT) +#define REG_NO_USE_MASK (0x01 << REG_NO_USE_SHIFT) +#define REG_VALID_MASK (0x01 << REG_VALID_SHIFT) + +#define REG(type, index, vswz, sswz, nouse, valid) \ + (((type << REG_TYPE_SHIFT) & REG_TYPE_MASK) | \ + ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK) | \ + ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK) | \ + ((valid << REG_VALID_SHIFT) & REG_VALID_MASK) | \ + ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK) | \ + ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK)) +#define REG_GET_TYPE(reg) \ + ((reg & REG_TYPE_MASK) >> REG_TYPE_SHIFT) +#define REG_GET_INDEX(reg) \ + ((reg & REG_INDEX_MASK) >> REG_INDEX_SHIFT) +#define REG_GET_VSWZ(reg) \ + ((reg & REG_VSWZ_MASK) >> REG_VSWZ_SHIFT) +#define REG_GET_SSWZ(reg) \ + ((reg & REG_SSWZ_MASK) >> REG_SSWZ_SHIFT) +#define REG_GET_NO_USE(reg) \ + ((reg & REG_NO_USE_MASK) >> REG_NO_USE_SHIFT) +#define REG_GET_VALID(reg) \ + ((reg & REG_VALID_MASK) >> REG_VALID_SHIFT) +#define REG_SET_TYPE(reg, type) \ + reg = ((reg & ~REG_TYPE_MASK) | \ + ((type << REG_TYPE_SHIFT) & REG_TYPE_MASK)) +#define REG_SET_INDEX(reg, index) \ + reg = ((reg & ~REG_INDEX_MASK) | \ + ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK)) +#define REG_SET_VSWZ(reg, vswz) \ + reg = ((reg & ~REG_VSWZ_MASK) | \ + ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK)) +#define REG_SET_SSWZ(reg, sswz) \ + reg = ((reg & ~REG_SSWZ_MASK) | \ + ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK)) +#define REG_SET_NO_USE(reg, nouse) \ + reg = ((reg & ~REG_NO_USE_MASK) | \ + ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK)) +#define REG_SET_VALID(reg, valid) \ + reg = ((reg & ~REG_VALID_MASK) | \ + ((valid << REG_VALID_SHIFT) & REG_VALID_MASK)) +#define REG_ABS(reg) \ + reg = (reg | REG_ABS_MASK) +#define REG_NEGV(reg) \ + reg = (reg | REG_NEGV_MASK) +#define REG_NEGS(reg) \ + reg = (reg | REG_NEGS_MASK) -/*************************************** - * begin: useful data structions for fragment program generation - ***************************************/ + +/* + * Datas structures for fragment program generation + */ /* description of r300 native hw instructions */ static const struct { @@ -86,20 +177,23 @@ static const struct { { "CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL }, }; -#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ - SWIZZLE_##y, \ - SWIZZLE_##z, \ - SWIZZLE_ZERO)) - -#define SLOT_VECTOR (1<<0) -#define SLOT_SCALAR (1<<3) -#define SLOT_BOTH (SLOT_VECTOR|SLOT_SCALAR) /* vector swizzles r300 can support natively, with a couple of * cases we handle specially * - * pfs_reg_t.v_swz/pfs_reg_t.s_swz is an index into this table - **/ + * REG_VSWZ/REG_SSWZ is an index into this table + */ +#define SLOT_VECTOR (1<<0) +#define SLOT_SCALAR (1<<3) +#define SLOT_BOTH (SLOT_VECTOR | SLOT_SCALAR) + +/* mapping from SWIZZLE_* to r300 native values for scalar insns */ +#define SWIZZLE_HALF 6 + +#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ + SWIZZLE_##y, \ + SWIZZLE_##z, \ + SWIZZLE_ZERO)) static const struct r300_pfs_swizzle { GLuint hash; /* swizzle value this matches */ GLuint base; /* base value for hw swizzle */ @@ -117,42 +211,30 @@ static const struct r300_pfs_swizzle { { MAKE_SWZ3(W, Z, Y), R300_FPI0_ARGC_SRC0CA_WZY, 1, SLOT_BOTH }, { MAKE_SWZ3(ONE, ONE, ONE), R300_FPI0_ARGC_ONE, 0, 0}, { MAKE_SWZ3(ZERO, ZERO, ZERO), R300_FPI0_ARGC_ZERO, 0, 0}, - { PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0}, + { MAKE_SWZ3(HALF, HALF, HALF), R300_FPI0_ARGC_HALF, 0, 0}, { PFS_INVAL, 0, 0, 0}, }; -#define SWIZZLE_XYZ 0 -#define SWIZZLE_XXX 1 -#define SWIZZLE_YYY 2 -#define SWIZZLE_ZZZ 3 -#define SWIZZLE_WWW 4 -#define SWIZZLE_YZX 5 -#define SWIZZLE_ZXY 6 -#define SWIZZLE_WZY 7 -#define SWIZZLE_111 8 -#define SWIZZLE_000 9 -#define SWIZZLE_HHH 10 +/* used during matching of non-native swizzles */ #define SWZ_X_MASK (7 << 0) #define SWZ_Y_MASK (7 << 3) #define SWZ_Z_MASK (7 << 6) #define SWZ_W_MASK (7 << 9) -/* used during matching of non-native swizzles */ static const struct { - GLuint hash; /* used to mask matching swizzle components */ + GLuint hash; /* used to mask matching swizzle components */ int mask; /* actual outmask */ int count; /* count of components matched */ } s_mask[] = { - { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3}, - { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2}, - { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2}, - { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2}, - { SWZ_X_MASK, 1, 1}, - { SWZ_Y_MASK, 2, 1}, - { SWZ_Z_MASK, 4, 1}, - { PFS_INVAL, PFS_INVAL, PFS_INVAL} + { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3}, + { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2}, + { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2}, + { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2}, + { SWZ_X_MASK, 1, 1}, + { SWZ_Y_MASK, 2, 1}, + { SWZ_Z_MASK, 4, 1}, + { PFS_INVAL, PFS_INVAL, PFS_INVAL} }; -/* mapping from SWIZZLE_* to r300 native values for scalar insns */ static const struct { int base; /* hw value of swizzle */ int stride; /* difference between SRC0/1/2 */ @@ -166,58 +248,51 @@ static const struct { { R300_FPI2_ARGA_ONE , 0, 0 }, { R300_FPI2_ARGA_HALF , 0, 0 } }; -#define SWIZZLE_HALF 6 /* boiler-plate reg, for convenience */ -static const pfs_reg_t undef = { - type: REG_TYPE_TEMP, - index: 0, - v_swz: SWIZZLE_XYZ, - s_swz: SWIZZLE_W, - negate_v: 0, - negate_s: 0, - absolute: 0, - no_use: GL_FALSE, - valid: GL_FALSE -}; +static const GLuint undef = REG(REG_TYPE_TEMP, + 0, + SWIZZLE_XYZ, + SWIZZLE_W, + GL_FALSE, + GL_FALSE); /* constant one source */ -static const pfs_reg_t pfs_one = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_111, - s_swz: SWIZZLE_ONE, - valid: GL_TRUE -}; +static const GLuint pfs_one = REG(REG_TYPE_CONST, + 0, + SWIZZLE_111, + SWIZZLE_ONE, + GL_FALSE, + GL_TRUE); /* constant half source */ -static const pfs_reg_t pfs_half = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_HHH, - s_swz: SWIZZLE_HALF, - valid: GL_TRUE -}; +static const GLuint pfs_half = REG(REG_TYPE_CONST, + 0, + SWIZZLE_HHH, + SWIZZLE_HALF, + GL_FALSE, + GL_TRUE); /* constant zero source */ -static const pfs_reg_t pfs_zero = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_000, - s_swz: SWIZZLE_ZERO, - valid: GL_TRUE -}; - -/*************************************** - * end: data structures - ***************************************/ +static const GLuint pfs_zero = REG(REG_TYPE_CONST, + 0, + SWIZZLE_000, + SWIZZLE_ZERO, + GL_FALSE, + GL_TRUE); -#define ERROR(fmt, args...) do { \ - fprintf(stderr, "%s::%s(): " fmt "\n",\ - __FILE__, __func__, ##args); \ - rp->error = GL_TRUE; \ -} while(0) +/* + * Common functions prototypes + */ +static void dump_program(struct r300_fragment_program *rp); +static void emit_arith(struct r300_fragment_program *rp, int op, + GLuint dest, int mask, + GLuint src0, GLuint src1, GLuint src2, + int flags); +/* + * Helper functions prototypes + */ static int get_hw_temp(struct r300_fragment_program *rp) { COMPILE_STATE; @@ -256,263 +331,360 @@ static void free_hw_temp(struct r300_fragment_program *rp, int idx) cs->hwreg_in_use &= ~(1<<idx); } -static pfs_reg_t get_temp_reg(struct r300_fragment_program *rp) +static GLuint get_temp_reg(struct r300_fragment_program *rp) { COMPILE_STATE; - pfs_reg_t r = undef; + GLuint r = undef; + GLuint index; - r.index = ffs(~cs->temp_in_use); - if (!r.index) { + index = ffs(~cs->temp_in_use); + if (!index) { ERROR("Out of program temps\n"); return r; } - cs->temp_in_use |= (1 << --r.index); - - cs->temps[r.index].refcount = 0xFFFFFFFF; - cs->temps[r.index].reg = -1; - r.valid = GL_TRUE; + + cs->temp_in_use |= (1 << --index); + cs->temps[index].refcount = 0xFFFFFFFF; + cs->temps[index].reg = -1; + + REG_SET_TYPE(r, REG_TYPE_TEMP); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static pfs_reg_t get_temp_reg_tex(struct r300_fragment_program *rp) +static GLuint get_temp_reg_tex(struct r300_fragment_program *rp) { COMPILE_STATE; - pfs_reg_t r = undef; + GLuint r = undef; + GLuint index; - r.index = ffs(~cs->temp_in_use); - if (!r.index) { + index = ffs(~cs->temp_in_use); + if (!index) { ERROR("Out of program temps\n"); return r; } - cs->temp_in_use |= (1 << --r.index); - - cs->temps[r.index].refcount = 0xFFFFFFFF; - cs->temps[r.index].reg = get_hw_temp_tex(rp); - r.valid = GL_TRUE; + + cs->temp_in_use |= (1 << --index); + cs->temps[index].refcount = 0xFFFFFFFF; + cs->temps[index].reg = get_hw_temp_tex(rp); + + REG_SET_TYPE(r, REG_TYPE_TEMP); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static void free_temp(struct r300_fragment_program *rp, pfs_reg_t r) +static void free_temp(struct r300_fragment_program *rp, GLuint r) { COMPILE_STATE; - if (!(cs->temp_in_use & (1<<r.index))) return; + GLuint index = REG_GET_INDEX(r); + + if (!(cs->temp_in_use & (1 << index))) + return; - if (r.type == REG_TYPE_TEMP) { - free_hw_temp(rp, cs->temps[r.index].reg); - cs->temps[r.index].reg = -1; - cs->temp_in_use &= ~(1<<r.index); - } else if (r.type == REG_TYPE_INPUT) { - free_hw_temp(rp, cs->inputs[r.index].reg); - cs->inputs[r.index].reg = -1; + if (REG_GET_TYPE(r) == REG_TYPE_TEMP) { + free_hw_temp(rp, cs->temps[index].reg); + cs->temps[index].reg = -1; + cs->temp_in_use &= ~(1 << index); + } else if (REG_GET_TYPE(r) == REG_TYPE_INPUT) { + free_hw_temp(rp, cs->inputs[index].reg); + cs->inputs[index].reg = -1; } } -static pfs_reg_t emit_param4fv(struct r300_fragment_program *rp, - GLfloat *values) +static GLuint emit_param4fv(struct r300_fragment_program *rp, + GLfloat *values) { - pfs_reg_t r = undef; - r.type = REG_TYPE_CONST; + GLuint r = undef; + GLuint index; int pidx; pidx = rp->param_nr++; - r.index = rp->const_nr++; - if (pidx >= PFS_NUM_CONST_REGS || r.index >= PFS_NUM_CONST_REGS) { + index = rp->const_nr++; + if (pidx >= PFS_NUM_CONST_REGS || index >= PFS_NUM_CONST_REGS) { ERROR("Out of const/param slots!\n"); return r; } - - rp->param[pidx].idx = r.index; + + rp->param[pidx].idx = index; rp->param[pidx].values = values; rp->params_uptodate = GL_FALSE; - r.valid = GL_TRUE; + REG_SET_TYPE(r, REG_TYPE_CONST); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) +static GLuint emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) { - pfs_reg_t r = undef; - r.type = REG_TYPE_CONST; + GLuint r = undef; + GLuint index; - r.index = rp->const_nr++; - if (r.index >= PFS_NUM_CONST_REGS) { + index = rp->const_nr++; + if (index >= PFS_NUM_CONST_REGS) { ERROR("Out of hw constants!\n"); return r; } - COPY_4V(rp->constant[r.index], cp); - r.valid = GL_TRUE; + COPY_4V(rp->constant[index], cp); + + REG_SET_TYPE(r, REG_TYPE_CONST); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static __inline pfs_reg_t negate(pfs_reg_t r) +static inline GLuint negate(GLuint r) { - r.negate_v = 1; - r.negate_s = 1; + REG_NEGS(r); + REG_NEGV(r); return r; } /* Hack, to prevent clobbering sources used multiple times when * emulating non-native instructions */ -static __inline pfs_reg_t keep(pfs_reg_t r) +static inline GLuint keep(GLuint r) { - r.no_use = GL_TRUE; + REG_SET_NO_USE(r, GL_TRUE); return r; } -static __inline pfs_reg_t absolute(pfs_reg_t r) +static inline GLuint absolute(GLuint r) { - r.absolute = 1; + REG_ABS(r); return r; } static int swz_native(struct r300_fragment_program *rp, - pfs_reg_t src, pfs_reg_t *r, GLuint arbneg) + GLuint src, + GLuint *r, + GLuint arbneg) { - /* Native swizzle, nothing to see here */ - src.negate_s = (arbneg >> 3) & 1; + /* Native swizzle, handle negation */ + src = (src & ~REG_NEGS_MASK) | + (((arbneg >> 3) & 1) << REG_NEGS_SHIFT); if ((arbneg & 0x7) == 0x0) { - src.negate_v = 0; + src = src & ~REG_NEGV_MASK; *r = src; } else if ((arbneg & 0x7) == 0x7) { - src.negate_v = 1; + src |= REG_NEGV_MASK; *r = src; } else { - if (!r->valid) + if (!REG_GET_VALID(*r)) *r = get_temp_reg(rp); - src.negate_v = 1; - emit_arith(rp, PFS_OP_MAD, *r, arbneg & 0x7, - keep(src), pfs_one, pfs_zero, 0); - src.negate_v = 0; - emit_arith(rp, PFS_OP_MAD, *r, + src |= REG_NEGV_MASK; + emit_arith(rp, + PFS_OP_MAD, + *r, + arbneg & 0x7, + keep(src), + pfs_one, + pfs_zero, + 0); + src = src & ~REG_NEGV_MASK; + emit_arith(rp, + PFS_OP_MAD, + *r, (arbneg ^ 0x7) | WRITEMASK_W, - src, pfs_one, pfs_zero, 0); + src, + pfs_one, + pfs_zero, + 0); } return 3; } -static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src, - pfs_reg_t *r, int mask, int mc, GLuint arbneg) +static int swz_emit_partial(struct r300_fragment_program *rp, + GLuint src, + GLuint *r, + int mask, + int mc, + GLuint arbneg) { GLuint tmp; GLuint wmask = 0; - if (!r->valid) + if (!REG_GET_VALID(*r)) *r = get_temp_reg(rp); - /* A partial match, src.v_swz/mask define what parts of the - * desired swizzle we match */ + /* A partial match, VSWZ/mask define what parts of the + * desired swizzle we match + */ if (mc + s_mask[mask].count == 3) { wmask = WRITEMASK_W; - src.negate_s = (arbneg >> 3) & 1; + src |= ((arbneg >> 3) & 1) << REG_NEGS_SHIFT; } tmp = arbneg & s_mask[mask].mask; if (tmp) { tmp = tmp ^ s_mask[mask].mask; if (tmp) { - src.negate_v = 1; - emit_arith(rp, PFS_OP_MAD, *r, + emit_arith(rp, + PFS_OP_MAD, + *r, arbneg & s_mask[mask].mask, - keep(src), pfs_one, pfs_zero, 0); - src.negate_v = 0; - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, tmp | wmask, - src, pfs_one, pfs_zero, 0); + keep(src) | REG_NEGV_MASK, + pfs_one, + pfs_zero, + 0); + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, + PFS_OP_MAD, + *r, + tmp | wmask, + src, + pfs_one, + pfs_zero, + 0); } else { - src.negate_v = 1; - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, + PFS_OP_MAD, + *r, (arbneg & s_mask[mask].mask) | wmask, - src, pfs_one, pfs_zero, 0); - src.negate_v = 0; + src | REG_NEGV_MASK, + pfs_one, + pfs_zero, + 0); } } else { - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, PFS_OP_MAD, + *r, s_mask[mask].mask | wmask, - src, pfs_one, pfs_zero, 0); + src, + pfs_one, + pfs_zero, + 0); } return s_mask[mask].count; } -#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \ - ((SWIZZLE_##x<<0)| \ - (SWIZZLE_##y<<3)| \ - (SWIZZLE_##z<<6)| \ - (SWIZZLE_##w<<9)), \ - 0) - -static pfs_reg_t do_swizzle(struct r300_fragment_program *rp, - pfs_reg_t src, GLuint arbswz, GLuint arbneg) +static GLuint do_swizzle(struct r300_fragment_program *rp, + GLuint src, + GLuint arbswz, + GLuint arbneg) { - pfs_reg_t r = undef; - + GLuint r = undef; + GLuint vswz; int c_mask = 0; - int v_matched = 0; + int v_match = 0; /* If swizzling from something without an XYZW native swizzle, * emit result to a temp, and do new swizzle from the temp. */ - if (src.v_swz != SWIZZLE_XYZ || src.s_swz != SWIZZLE_W) { - pfs_reg_t temp = get_temp_reg(rp); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_XYZW, src, pfs_one, - pfs_zero, 0); +#if 0 + if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || + REG_GET_SSWZ(src) != SWIZZLE_W) { + GLuint temp = get_temp_reg(rp); + emit_arith(rp, + PFS_OP_MAD, + temp, + WRITEMASK_XYZW, + src, + pfs_one, + pfs_zero, + 0); src = temp; } - src.s_swz = GET_SWZ(arbswz, 3); +#endif + + if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || + REG_GET_SSWZ(src) != SWIZZLE_W) { + GLuint vsrcswz = (v_swiz[REG_GET_VSWZ(src)].hash & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK)) | REG_GET_SSWZ(src) << 9; + GLint i; + + GLuint newswz = 0; + GLuint offset; + for(i=0; i < 4; ++i){ + offset = GET_SWZ(arbswz, i); + + newswz |= (offset <= 3)?GET_SWZ(vsrcswz, offset) << i*3:offset << i*3; + } + + arbswz = newswz & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK); + REG_SET_SSWZ(src, GET_SWZ(newswz, 3)); + } + else + { + /* set scalar swizzling */ + REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); + } do { + vswz = REG_GET_VSWZ(src); do { -#define CUR_HASH (v_swiz[src.v_swz].hash & s_mask[c_mask].hash) - if (CUR_HASH == (arbswz & s_mask[c_mask].hash)) { - if (s_mask[c_mask].count == 3) - v_matched += swz_native(rp, src, &r, + int chash; + + REG_SET_VSWZ(src, vswz); + chash = v_swiz[REG_GET_VSWZ(src)].hash & + s_mask[c_mask].hash; + + if (chash == (arbswz & s_mask[c_mask].hash)) { + if (s_mask[c_mask].count == 3) { + v_match += swz_native(rp, + src, + &r, arbneg); - else - v_matched += swz_emit_partial(rp, src, - &r, - c_mask, - v_matched, - arbneg); - - if (v_matched == 3) + } else { + v_match += swz_emit_partial(rp, + src, + &r, + c_mask, + v_match, + arbneg); + } + + if (v_match == 3) return r; /* Fill with something invalid.. all 0's was * wrong before, matched SWIZZLE_X. So all - * 1's will be okay for now */ + * 1's will be okay for now + */ arbswz |= (PFS_INVAL & s_mask[c_mask].hash); } - } while(v_swiz[++src.v_swz].hash != PFS_INVAL); - src.v_swz = SWIZZLE_XYZ; + } while(v_swiz[++vswz].hash != PFS_INVAL); + REG_SET_VSWZ(src, SWIZZLE_XYZ); } while (s_mask[++c_mask].hash != PFS_INVAL); ERROR("should NEVER get here\n"); return r; } - -static pfs_reg_t t_src(struct r300_fragment_program *rp, - struct prog_src_register fpsrc) + +static GLuint t_src(struct r300_fragment_program *rp, + struct prog_src_register fpsrc) { - pfs_reg_t r = undef; + GLuint r = undef; switch (fpsrc.File) { case PROGRAM_TEMPORARY: - r.index = fpsrc.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, fpsrc.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_TEMP); break; case PROGRAM_INPUT: - r.index = fpsrc.Index; - r.type = REG_TYPE_INPUT; - r.valid = GL_TRUE; + REG_SET_INDEX(r, fpsrc.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_INPUT); break; case PROGRAM_LOCAL_PARAM: r = emit_param4fv(rp, @@ -533,13 +705,13 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp, } /* no point swizzling ONE/ZERO/HALF constants... */ - if (r.v_swz < SWIZZLE_111 || r.s_swz < SWIZZLE_ZERO) + if (REG_GET_VSWZ(r) < SWIZZLE_111 || REG_GET_SSWZ(r) < SWIZZLE_ZERO) r = do_swizzle(rp, r, fpsrc.Swizzle, fpsrc.NegateBase); return r; } -static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp, - struct prog_src_register fpsrc) +static GLuint t_scalar_src(struct r300_fragment_program *rp, + struct prog_src_register fpsrc) { struct prog_src_register src = fpsrc; int sc = GET_SWZ(fpsrc.Swizzle, 0); /* X */ @@ -549,22 +721,24 @@ static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp, return t_src(rp, src); } -static pfs_reg_t t_dst(struct r300_fragment_program *rp, - struct prog_dst_register dest) { - pfs_reg_t r = undef; +static GLuint t_dst(struct r300_fragment_program *rp, + struct prog_dst_register dest) +{ + GLuint r = undef; switch (dest.File) { case PROGRAM_TEMPORARY: - r.index = dest.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, dest.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_TEMP); return r; case PROGRAM_OUTPUT: - r.type = REG_TYPE_OUTPUT; + REG_SET_TYPE(r, REG_TYPE_OUTPUT); switch (dest.Index) { case FRAG_RESULT_COLR: case FRAG_RESULT_DEPR: - r.index = dest.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, dest.Index); + REG_SET_VALID(r, GL_TRUE); return r; default: ERROR("Bad DstReg->Index 0x%x\n", dest.Index); @@ -576,66 +750,77 @@ static pfs_reg_t t_dst(struct r300_fragment_program *rp, } } -static int t_hw_src(struct r300_fragment_program *rp, pfs_reg_t src, +static int t_hw_src(struct r300_fragment_program *rp, + GLuint src, GLboolean tex) { COMPILE_STATE; int idx; + int index = REG_GET_INDEX(src); - switch (src.type) { + switch(REG_GET_TYPE(src)) { case REG_TYPE_TEMP: /* NOTE: if reg==-1 here, a source is being read that - * hasn't been written to. Undefined results */ - if (cs->temps[src.index].reg == -1) - cs->temps[src.index].reg = get_hw_temp(rp); - idx = cs->temps[src.index].reg; + * hasn't been written to. Undefined results + */ + if (cs->temps[index].reg == -1) + cs->temps[index].reg = get_hw_temp(rp); + + idx = cs->temps[index].reg; - if (!src.no_use && (--cs->temps[src.index].refcount == 0)) + if (!REG_GET_NO_USE(src) && + (--cs->temps[index].refcount == 0)) free_temp(rp, src); break; case REG_TYPE_INPUT: - idx = cs->inputs[src.index].reg; + idx = cs->inputs[index].reg; - if (!src.no_use && (--cs->inputs[src.index].refcount == 0)) - free_hw_temp(rp, cs->inputs[src.index].reg); + if (!REG_GET_NO_USE(src) && + (--cs->inputs[index].refcount == 0)) + free_hw_temp(rp, cs->inputs[index].reg); break; case REG_TYPE_CONST: - return (src.index | SRC_CONST); + return (index | SRC_CONST); default: ERROR("Invalid type for source reg\n"); return (0 | SRC_CONST); } - if (!tex) cs->used_in_node |= (1 << idx); + if (!tex) + cs->used_in_node |= (1 << idx); return idx; } -static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest, +static int t_hw_dst(struct r300_fragment_program *rp, + GLuint dest, GLboolean tex) { COMPILE_STATE; int idx; - assert(dest.valid); + GLuint index = REG_GET_INDEX(dest); + assert(REG_GET_VALID(dest)); - switch (dest.type) { + switch(REG_GET_TYPE(dest)) { case REG_TYPE_TEMP: - if (cs->temps[dest.index].reg == -1) { - if (!tex) - cs->temps[dest.index].reg = get_hw_temp(rp); - else - cs->temps[dest.index].reg = get_hw_temp_tex(rp); + if (cs->temps[REG_GET_INDEX(dest)].reg == -1) { + if (!tex) { + cs->temps[index].reg = get_hw_temp(rp); + } else { + cs->temps[index].reg = get_hw_temp_tex(rp); + } } - idx = cs->temps[dest.index].reg; + idx = cs->temps[index].reg; - if (!dest.no_use && (--cs->temps[dest.index].refcount == 0)) + if (!REG_GET_NO_USE(dest) && + (--cs->temps[index].refcount == 0)) free_temp(rp, dest); cs->dest_in_node |= (1 << idx); cs->used_in_node |= (1 << idx); break; case REG_TYPE_OUTPUT: - switch (dest.index) { + switch(index) { case FRAG_RESULT_COLR: rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_COLOR; break; @@ -643,17 +828,18 @@ static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest, rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_DEPTH; break; } - return dest.index; + return index; break; default: - ERROR("invalid dest reg type %d\n", dest.type); + ERROR("invalid dest reg type %d\n", REG_GET_TYPE(dest)); return 0; } return idx; } -static void emit_nop(struct r300_fragment_program *rp, GLuint mask, +static void emit_nop(struct r300_fragment_program *rp, + GLuint mask, GLboolean sync) { COMPILE_STATE; @@ -679,8 +865,8 @@ static void emit_tex(struct r300_fragment_program *rp, int opcode) { COMPILE_STATE; - pfs_reg_t coord = t_src(rp, fpi->SrcReg[0]); - pfs_reg_t dest = undef, rdest = undef; + GLuint coord = t_src(rp, fpi->SrcReg[0]); + GLuint dest = undef, rdest = undef; GLuint din = cs->dest_in_node, uin = cs->used_in_node; int unit = fpi->TexSrcUnit; int hwsrc, hwdest; @@ -691,7 +877,7 @@ static void emit_tex(struct r300_fragment_program *rp, dest = t_dst(rp, fpi->DstReg); /* r300 doesn't seem to be able to do TEX->output reg */ - if (dest.type == REG_TYPE_OUTPUT) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { rdest = dest; dest = get_temp_reg_tex(rp); } @@ -703,7 +889,7 @@ static void emit_tex(struct r300_fragment_program *rp, if (uin & (1 << hwdest)) { free_hw_temp(rp, hwdest); hwdest = get_hw_temp_tex(rp); - cs->temps[dest.index].reg = hwdest; + cs->temps[REG_GET_INDEX(dest)].reg = hwdest; } } else { hwdest = 0; @@ -713,8 +899,8 @@ static void emit_tex(struct r300_fragment_program *rp, /* Indirection if source has been written in this node, or if the * dest has been read/written in this node */ - if ((coord.type != REG_TYPE_CONST && (din & (1<<hwsrc))) || - (uin & (1<<hwdest))) { + if ((REG_GET_TYPE(coord) != REG_TYPE_CONST && + (din & (1<<hwsrc))) || (uin & (1<<hwdest))) { /* Finish off current node */ cs->v_pos = cs->s_pos = MAX2(cs->v_pos, cs->s_pos); @@ -754,13 +940,13 @@ static void emit_tex(struct r300_fragment_program *rp, | (opcode << R300_FPITX_OPCODE_SHIFT); cs->dest_in_node |= (1 << hwdest); - if (coord.type != REG_TYPE_CONST) + if (REG_GET_TYPE(coord) != REG_TYPE_CONST) cs->used_in_node |= (1 << hwsrc); rp->node[rp->cur_node].tex_end++; /* Copy from temp to output if needed */ - if (rdest.valid) { + if (REG_GET_VALID(rdest)) { emit_arith(rp, PFS_OP_MAD, rdest, WRITEMASK_XYZW, dest, pfs_one, pfs_zero, 0); free_temp(rp, dest); @@ -770,7 +956,9 @@ static void emit_tex(struct r300_fragment_program *rp, /* Add sources to FPI1/FPI3 lists. If source is already on list, * reuse the index instead of wasting a source. */ -static int add_src(struct r300_fragment_program *rp, int reg, int pos, +static int add_src(struct r300_fragment_program *rp, + int reg, + int pos, int srcmask) { COMPILE_STATE; @@ -819,9 +1007,12 @@ static int add_src(struct r300_fragment_program *rp, int reg, int pos, * It's not necessary to force the first case, but it makes disassembled * shaders easier to read. */ -static GLboolean force_same_slot(int vop, int sop, - GLboolean emit_vop, GLboolean emit_sop, - int argc, pfs_reg_t *src) +static GLboolean force_same_slot(int vop, + int sop, + GLboolean emit_vop, + GLboolean emit_sop, + int argc, + GLuint *src) { int i; @@ -833,20 +1024,24 @@ static GLboolean force_same_slot(int vop, int sop, if (emit_vop) { for (i=0;i<argc;i++) - if (src[i].v_swz == SWIZZLE_WZY) + if (REG_GET_VSWZ(src[i]) == SWIZZLE_WZY) return GL_TRUE; } return GL_FALSE; } -static void emit_arith(struct r300_fragment_program *rp, int op, - pfs_reg_t dest, int mask, - pfs_reg_t src0, pfs_reg_t src1, pfs_reg_t src2, +static void emit_arith(struct r300_fragment_program *rp, + int op, + GLuint dest, + int mask, + GLuint src0, + GLuint src1, + GLuint src2, int flags) { COMPILE_STATE; - pfs_reg_t src[3] = { src0, src1, src2 }; + GLuint src[3] = { src0, src1, src2 }; int hwsrc[3], sswz[3], vswz[3]; int hwdest; GLboolean emit_vop = GL_FALSE, emit_sop = GL_FALSE; @@ -863,7 +1058,8 @@ static void emit_arith(struct r300_fragment_program *rp, int op, if ((mask & WRITEMASK_W) || vop == R300_FPI0_OUTC_REPL_ALPHA) emit_sop = GL_TRUE; - if (dest.type == REG_TYPE_OUTPUT && dest.index == FRAG_RESULT_DEPR) + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT && + REG_GET_INDEX(dest) == FRAG_RESULT_DEPR) emit_vop = GL_FALSE; if (force_same_slot(vop, sop, emit_vop, emit_sop, argc, src)) { @@ -879,12 +1075,12 @@ static void emit_arith(struct r300_fragment_program *rp, int op, */ for (i=0;i<3;i++) { if (emit_vop && - (v_swiz[src[i].v_swz].flags & SLOT_SCALAR)) { + (v_swiz[REG_GET_VSWZ(src[i])].flags & SLOT_SCALAR)) { vpos = spos = MAX2(vpos, spos); break; } if (emit_sop && - (s_swiz[src[i].s_swz].flags & SLOT_VECTOR)) { + (s_swiz[REG_GET_SSWZ(src[i])].flags & SLOT_VECTOR)) { vpos = spos = MAX2(vpos, spos); break; } @@ -908,20 +1104,22 @@ static void emit_arith(struct r300_fragment_program *rp, int op, if (emit_vop && vop != R300_FPI0_OUTC_REPL_ALPHA) { srcpos = add_src(rp, hwsrc[i], vpos, - v_swiz[src[i].v_swz].flags); - vswz[i] = (v_swiz[src[i].v_swz].base + - (srcpos * v_swiz[src[i].v_swz].stride)) | - (src[i].negate_v ? ARG_NEG : 0) | - (src[i].absolute ? ARG_ABS : 0); + v_swiz[REG_GET_VSWZ(src[i])].flags); + vswz[i] = (v_swiz[REG_GET_VSWZ(src[i])].base + + (srcpos * + v_swiz[REG_GET_VSWZ(src[i])].stride)) | + ((src[i] & REG_NEGV_MASK) ? ARG_NEG : 0) | + ((src[i] & REG_ABS_MASK) ? ARG_ABS : 0); } else vswz[i] = R300_FPI0_ARGC_ZERO; if (emit_sop) { srcpos = add_src(rp, hwsrc[i], spos, - s_swiz[src[i].s_swz].flags); - sswz[i] = (s_swiz[src[i].s_swz].base + - (srcpos * s_swiz[src[i].s_swz].stride)) | - (src[i].negate_s ? ARG_NEG : 0) | - (src[i].absolute ? ARG_ABS : 0); + s_swiz[REG_GET_SSWZ(src[i])].flags); + sswz[i] = (s_swiz[REG_GET_SSWZ(src[i])].base + + (srcpos * + s_swiz[REG_GET_SSWZ(src[i])].stride)) | + ((src[i] & REG_NEGS_MASK) ? ARG_NEG : 0) | + ((src[i] & REG_ABS_MASK) ? ARG_ABS : 0); } else sswz[i] = R300_FPI2_ARGA_ZERO; } hwdest = t_hw_dst(rp, dest, GL_FALSE); @@ -943,8 +1141,8 @@ static void emit_arith(struct r300_fragment_program *rp, int op, (vswz[2] << R300_FPI0_ARG2C_SHIFT); rp->alu.inst[vpos].inst1 |= hwdest << R300_FPI1_DSTC_SHIFT; - if (dest.type == REG_TYPE_OUTPUT) { - if (dest.index == FRAG_RESULT_COLR) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { + if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { rp->alu.inst[vpos].inst1 |= (mask & WRITEMASK_XYZ) << R300_FPI1_DSTC_OUTPUT_MASK_SHIFT; } else assert(0); @@ -968,11 +1166,11 @@ static void emit_arith(struct r300_fragment_program *rp, int op, sswz[2] << R300_FPI2_ARG2A_SHIFT; if (mask & WRITEMASK_W) { - if (dest.type == REG_TYPE_OUTPUT) { - if (dest.index == FRAG_RESULT_COLR) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { + if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { rp->alu.inst[spos].inst3 |= (hwdest << R300_FPI3_DSTA_SHIFT) | R300_FPI3_DSTA_OUTPUT; - } else if (dest.index == FRAG_RESULT_DEPR) { + } else if (REG_GET_INDEX(dest) == FRAG_RESULT_DEPR) { rp->alu.inst[spos].inst3 |= R300_FPI3_DSTA_DEPTH; } else assert(0); } else { @@ -985,33 +1183,52 @@ static void emit_arith(struct r300_fragment_program *rp, int op, rp->alu.inst[vpos].inst2 = NOP_INST2; return; -}; +} #if 0 -static pfs_reg_t get_attrib(struct r300_fragment_program *rp, GLuint attr) +static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr) { struct gl_fragment_program *mp = &rp->mesa_program; - pfs_reg_t r = undef; + GLuint r = undef; if (!(mp->Base.InputsRead & (1<<attr))) { ERROR("Attribute %d was not provided!\n", attr); return undef; } - r.type = REG_TYPE_INPUT; - r.index = attr; - r.valid = GL_TRUE; + REG_SET_TYPE(r, REG_TYPE_INPUT); + REG_SET_INDEX(r, attr); + REG_SET_VALID(r, GL_TRUE); return r; } #endif +static void make_sin_const(struct r300_fragment_program *rp) +{ + if(rp->const_sin[0] == -1){ + GLfloat cnstv[4]; + + cnstv[0] = 1.273239545; // 4/PI + cnstv[1] =-0.405284735; // -4/(PI*PI) + cnstv[2] = 3.141592654; // PI + cnstv[3] = 0.2225; // weight + rp->const_sin[0] = emit_const4fv(rp, cnstv); + + cnstv[0] = 0.5; + cnstv[1] = -1.5; + cnstv[2] = 0.159154943; // 1/(2*PI) + cnstv[3] = 6.283185307; // 2*PI + rp->const_sin[1] = emit_const4fv(rp, cnstv); + } +} + static GLboolean parse_program(struct r300_fragment_program *rp) { struct gl_fragment_program *mp = &rp->mesa_program; const struct prog_instruction *inst = mp->Base.Instructions; struct prog_instruction *fpi; - pfs_reg_t src[3], dest, temp; - pfs_reg_t cnst; + GLuint src[3], dest, temp; + GLuint cnst; int flags, mask = 0; GLfloat cnstv[4] = {0.0, 0.0, 0.0, 0.0}; @@ -1058,62 +1275,71 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_COS: /* - * cos using taylor serie: - * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI + * result = sin(x) */ temp = get_temp_reg(rp); - cnstv[0] = 0.5; - cnstv[1] = 0.041666667; - cnstv[2] = 0.001388889; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - pfs_one, - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, + /* add 0.5*PI and do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(rp->const_sin[0], Z, Z, Z, Z), //PI + pfs_half, + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, swizzle(temp, X, X, X, X), - pfs_one, + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, + 0); + + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, + swizzle(temp, X, X, X, X), + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //-PI + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), flags); + free_temp(rp, temp); break; case OPCODE_DP3: @@ -1167,7 +1393,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) /* result.x = 1.0 * result.w = src1.w */ if (mask & WRITEMASK_XW) { - src[1].v_swz = SWIZZLE_111; /* Cheat.. */ + REG_SET_VSWZ(src[1], SWIZZLE_111); /*Cheat*/ emit_arith(rp, PFS_OP_MAD, dest, mask & WRITEMASK_XW, src[1], pfs_one, pfs_zero, @@ -1222,7 +1448,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) * change the compare to (t.x + 0.5) > 0.5 we may * save one instruction by doing CMP -t.x */ - cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001; + cnstv[0] = cnstv[1] = cnstv[2] = cnstv[3] = 0.50001; src[0] = t_src(rp, fpi->SrcReg[0]); temp = get_temp_reg(rp); cnst = emit_const4fv(rp, cnstv); @@ -1353,7 +1579,93 @@ static GLboolean parse_program(struct r300_fragment_program *rp) flags); break; case OPCODE_SCS: - ERROR("SCS not implemented\n"); + /* + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI + * result = sin(x) + */ + temp = get_temp_reg(rp); + make_sin_const(rp); + src[0] = t_scalar_src(rp, fpi->SrcReg[0]); + + /* add 0.5*PI and do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X|WRITEMASK_Y, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + rp->const_sin[1], + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_W, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + negate(pfs_half), + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(temp, Y, Y, Y, Y), + swizzle(temp, W, W, W, W), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(keep(src[0]), X, X, X, X), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(keep(src[0]), X, X, X, X)), + swizzle(temp, X, X, X, X), + 0); + } + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, W, W, W, W), + absolute(swizzle(temp, W, W, W, W)), + negate(swizzle(temp, W, W, W, W)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_X, + swizzle(temp, Z, Z, Z, Z), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, W, W, W, W), + flags); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y, + swizzle(temp, W, W, W, W), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } + free_temp(rp, temp); break; case OPCODE_SGE: src[0] = t_src(rp, fpi->SrcReg[0]); @@ -1372,68 +1684,63 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_SIN: /* - * sin using taylor serie: - * sin(x) = x - x^3/3! + x^5/5! - x^7/7! + * using a parabola: + * sin(x) = 4/pi * x + -4/(pi*pi) * x * abs(x) + * extra precision is obtained by weighting against + * itself squared. */ + temp = get_temp_reg(rp); - cnstv[0] = 0.333333333; - cnstv[1] = 0.008333333; - cnstv[2] = 0.000198413; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - src[0], - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, + /* do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(keep(src[0]), X, X, X, X), + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, + 0); + + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, swizzle(temp, X, X, X, X), - pfs_one, + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //PI + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), flags); + free_temp(rp, temp); break; case OPCODE_SLT: @@ -1505,7 +1812,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) /* - Init structures * - Determine what hwregs each input corresponds to */ -static void init_program(struct r300_fragment_program *rp) +static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; struct gl_fragment_program *mp = &rp->mesa_program; @@ -1515,6 +1822,7 @@ static void init_program(struct r300_fragment_program *rp) int i,j; /* New compile, reset tracking data */ + rp->optimization = driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); rp->translated = GL_FALSE; rp->error = GL_FALSE; rp->cs = cs = &(R300_CONTEXT(rp->ctx)->state.pfs_compile); @@ -1527,6 +1835,7 @@ static void init_program(struct r300_fragment_program *rp) rp->max_temp_idx = 0; rp->node[0].alu_end = -1; rp->node[0].tex_end = -1; + rp->const_sin[0] = -1; _mesa_memset(cs, 0, sizeof(*rp->cs)); for (i=0;i<PFS_MAX_ALU_INST;i++) { @@ -1640,13 +1949,13 @@ static void update_params(struct r300_fragment_program *rp) rp->params_uptodate = GL_TRUE; } -void r300_translate_fragment_shader(struct r300_fragment_program *rp) +void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; if (!rp->translated) { - init_program(rp); + init_program(r300, rp); cs = rp->cs; if (parse_program(rp) == GL_FALSE) { diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index 4bbaa07e012..73986abc3cc 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -41,6 +41,7 @@ #include "r300_context.h" #include "program_instruction.h" +#if 0 /* representation of a register for emit_arith/swizzle */ typedef struct _pfs_reg_t { enum { @@ -58,7 +59,7 @@ typedef struct _pfs_reg_t { GLboolean no_use:1; GLboolean valid:1; } pfs_reg_t; - +#endif typedef struct r300_fragment_program_swizzle { GLuint length; GLuint src[4]; @@ -111,8 +112,11 @@ typedef struct r300_fragment_program_swizzle { ((0 | SRC_CONST) << R300_FPI3_SRC1A_SHIFT) | \ ((0 | SRC_CONST) << R300_FPI3_SRC2A_SHIFT)) +#define DRI_CONF_FP_OPTIMIZATION_SPEED 0 +#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 + struct r300_fragment_program; -extern void r300_translate_fragment_shader(struct r300_fragment_program *rp); +extern void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp); #endif diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c b/src/mesa/drivers/dri/r300/r300_fragprog_swz.c deleted file mode 100644 index b29331d7bde..00000000000 --- a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* - * Copyright (C) 2005 Jerome Glisse. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include "r300_fragprog.h" -#include "r300_reg.h" - - -#define I0_000 ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_ZERO) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_111 ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_ZERO) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG2C_SHIFT) ) -#define I0_XXX ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_XXX) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_YYY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_YYY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_ZZZ ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_ZZZ) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_XYZ ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_XYZ) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_YZX ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_YZX) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_ZXY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_ZXY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_WZY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0CA_WZY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_WWW ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0A) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) - -#define IEMPTY 0 - -#define I1_XYZ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Y | \ - R300_FPI1_DSTC_REG_Z ) -#define I1_XY_ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Y ) -#define I1_X_Z ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Z ) -#define I1__YZ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Y | \ - R300_FPI1_DSTC_REG_Z ) -#define I1_X__ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X ) -#define I1__Y_ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Y ) -#define I1___Z ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Z ) - -#define SEMPTY {0,{0,0,0,0},{0,0,0,0,0,0,0,0}} - -struct r300_fragment_program_swizzle r300_swizzle [512] = { - /* XXX */ - {1,{0,0,0,0},{ I0_XXX, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* YXX */ - {2,{0,0,0,0},{ I0_YZX, I1_X_Z, - I0_XXX, I1__Y_, - 0,0, - 0,0 } }, - /* ZXX */ - {2,{0,0,0,0},{ I0_ZZZ, I1_X__, - I0_XXX, I1__YZ, - 0,0, - 0,0 } }, - /* WXX */ - {2,{0,0,0,0},{ I0_WZY, I1_X__, - I0_XXX, I1__YZ, - 0,0, - 0,0} }, - /* 0XX */ - {2,{0,2,0,0},{ I0_XXX, I1__YZ, - I0_000, I1_X__, - 0,0, - 0,0 } }, - /* 1XX */ - {2,{0,2,0,0},{ I0_XXX, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XYX */ - {2,{0,0,0,0},{ I0_YYY, I1__Y_, - I0_XXX, I1_X_Z, - 0,0,0,0}}, - /* YYX */ - {2,{0,0,0,0},{ I0_YYY, I1_XY_, - I0_XXX, I1___Z, - 0,0,0,0}}, - /* ZYX */ - {3,{0,0,0,0},{ I0_ZZZ, I1_X__, - I0_YYY, I1__Y_, - I0_XXX, I1___Z, - 0,0}}, - /* WYX */ - {3,{0,0,0,0},{ I0_WZY, I1_X__, - I0_YYY, I1__Y_, - I0_XXX, I1___Z, - 0,0}}, - /* 0YX */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_XXX, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1YX */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_XXX, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XZX */ - {2,{0,0,0,0},{ I0_YZX, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZX */ - {1,{0,0,0,0},{ I0_YZX, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* ZZX */ - {2,{0,0,0,0},{ I0_YZX, I1__YZ, - I0_ZZZ, I1_X__,0,0,0,0}}, - /* WZX */ - {2,{0,0,0,0},{ I0_WZY, I1_XY_, - I0_XXX, I1___Z,0,0,0,0}}, - /* 0ZX */ - {2,{0,2,0,0},{ I0_YZX, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZX */ - {2,{0,2,0,0},{ I0_YZX, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWX */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XXX, I1_X_Z, - 0,0,0,0}}, - /* YWX */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YZX, I1_X_Z, - 0,0,0,0}}, - /* ZWX */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZZZ, I1_X__, - I0_XXX, I1___Z, - 0,0}}, - /* WWX */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_YZX, I1___Z, - 0,0,0,0}}, - /* 0WX */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XXX, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WX */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XXX, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0X */ - {2,{0,2,0,0},{ I0_XXX, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Y0X */ - {2,{0,2,0,0},{ I0_YZX, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Z0X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* W0X */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 00X */ - {2,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1X */ - {2,{0,2,0,0},{ I0_XXX, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Y1X */ - {2,{0,2,0,0},{ I0_YZX, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Z1X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* W1X */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 01X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11X */ - {2,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXY */ - {2,{0,0,0,0},{ I0_YYY, I1___Z, - I0_XXX, I1_XY_, - 0,0,0,0}}, - /* YXY */ - {2,{0,0,0,0},{ I0_YYY, I1_X_Z, - I0_XXX, I1__Y_, - 0,0,0,0}}, - /* ZXY */ - {1,{0,0,0,0},{ I0_ZXY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* WXY */ - {2,{0,0,0,0},{ I0_WZY, I1_X__, - I0_ZXY, I1__YZ, - 0,0,0,0}}, - /* 0XY */ - {2,{0,0,0,0},{ I0_ZXY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1XY */ - {2,{0,0,0,0},{ I0_ZXY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XYY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YYY */ - {1,{0,0,0,0},{ I0_YYY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* ZYY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WYY */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_YYY, I1__YZ, - 0,0,0,0}}, - /* 0YY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1YY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WZY */ - {1,{0,0,0,0},{ I0_WZY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* 0ZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWY */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XXX, I1_X__, - I0_YYY, I1___Z, - 0,0}}, - /* YWY */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YYY, I1_X_Z, - 0,0,0,0}}, - /* ZWY */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1_X_Z, - 0,0,0,0}}, - /* WWY */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_ZXY, I1___Z, - 0,0,0,0}}, - /* 0WY */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WY */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0Y */ - {3,{0,2,0,0},{ I0_XXX, I1_X__, - I0_000, I1__Y_, - I0_YYY, I1___Z, - 0,0}}, - /* Y0Y */ - {2,{0,2,0,0},{ I0_YYY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Z0Y */ - {2,{0,2,0,0},{ I0_ZXY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* W0Y */ - {2,{0,2,0,0},{ I0_WZY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* 00Y */ - {2,{0,2,0,0},{ I0_YYY, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10Y */ - {3,{0,2,0,0},{ I0_YYY, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1Y */ - {3,{0,2,0,0},{ I0_XXX, I1_X__, - I0_111, I1__Y_, - I0_YYY, I1___Z, - 0,0}}, - /* Y1Y */ - {2,{0,2,0,0},{ I0_YYY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Z1Y */ - {2,{0,2,0,0},{ I0_ZXY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* W1Y */ - {3,{0,2,0,0},{ I0_WZY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* 01Y */ - {3,{0,2,0,0},{ I0_YYY, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11Y */ - {2,{0,2,0,0},{ I0_YYY, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXZ */ - {2,{0,0,0,0},{ I0_XXX, I1_XY_, - I0_ZZZ, I1___Z, - 0,0,0,0}}, - /* YXZ */ - {3,{0,0,0,0},{ I0_XXX, I1__Y_, - I0_YYY, I1_X__, - I0_ZZZ, I1___Z, - 0,0}}, - /* ZXZ */ - {2,{0,0,0,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1_X_Z, - 0,0,0,0}}, - /* WXZ */ - {3,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - 0,0}}, - /* 0XZ */ - {3,{0,0,2,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1XZ */ - {3,{0,0,2,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XYZ */ - {1,{0,0,0,0},{ I0_XYZ, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* YYZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1___Z, - I0_YYY, I1_XY_, - 0,0,0,0}}, - /* ZYZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1_X_Z, - I0_YYY, I1__Y_, - 0,0,0,0}}, - /* WYZ */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_XYZ, I1__YZ, - 0,0,0,0}}, - /* 0YZ */ - {2,{0,2,0,0},{ I0_XYZ, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1YZ */ - {2,{0,2,0,0},{ I0_XYZ, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZZZ */ - {1,{0,0,0,0},{ I0_ZZZ, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* WZZ */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_ZZZ, I1__YZ, - 0,0,0,0}}, - /* 0ZZ */ - {2,{0,2,0,0},{ I0_ZZZ, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZZ */ - {2,{0,2,0,0},{ I0_ZZZ, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWZ */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X_Z, - 0,0,0,0}}, - /* YWZ */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YYY, I1_X__, - I0_XYZ, I1___Z, - 0,0}}, - /* ZWZ */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZZZ, I1_X_Z, - 0,0,0,0}}, - /* WWZ */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_XYZ, I1___Z, - 0,0,0,0}}, - /* 0WZ */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WZ */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0Z */ - {2,{0,2,0,0},{ I0_XYZ, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Y0Z */ - {3,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_000, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* Z0Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* W0Z */ - {3,{0,0,2,0},{ I0_WZY, I1_X_Z, - I0_ZZZ, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 00Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10Z */ - {3,{0,2,2,0},{ I0_ZZZ, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1Z */ - {2,{0,2,0,0},{ I0_XYZ, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Y1Z */ - {3,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_111, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* Z1Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* W1Z */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_ZZZ, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 01Z */ - {3,{0,2,2,0},{ I0_ZZZ, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XXX, I1_XY_, - 0,0,0,0}}, - /* YXW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* ZXW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_ZXY, I1_XY_, - 0,0,0,0}}, - /* WXW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_XXX, I1__Y_, - 0,0,0,0}}, - /* 0XW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1XW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XYW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_XY_, - 0,0,0,0}}, - /* YYW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_YYY, I1_XY_, - 0,0}}, - /* ZYW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* WYW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_YYY, I1__Y_, - 0,0,0,0}}, - /* 0YW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1YW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1__Y_, - I0_111, I1_X__, - 0,0}}, - - SEMPTY,SEMPTY, - /* XZW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_ZZZ, I1__Y_, - 0,0}}, - /* YZW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_YZX, I1_XY_, - 0,0,0,0}}, - /* ZZW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_XY_, - 0,0,0,0}}, - /* WZW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_ZZZ, I1__Y_, - 0,0,0,0}}, - /* 0ZW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1ZW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1__Y_, - I0_111, I1_X__, - 0,0}}, - - SEMPTY,SEMPTY, - /* XWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_XYZ, I1_X__, - 0,0,0,0}}, - /* YWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WWW */ - {1,{0,0,0,0},{ I0_WWW, I1_XYZ, - 0,0,0,0,0,0}}, - /* 0WW */ - {2,{0,2,0,0},{ I0_WWW, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1WW */ - {2,{0,2,0,0},{ I0_WWW, I1__YZ, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* Y0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* Z0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* W0W */ - {2,{0,2,0,0},{ I0_WWW, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* 00W */ - {2,{0,2,0,0},{ I0_WWW, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10W */ - {3,{0,2,2,0},{ I0_WWW, I1___Z, - I0_111, I1_X__, - I0_000, I1__Y_, - 0,0}}, - SEMPTY,SEMPTY, - /* X1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* Y1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* Z1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* W1W */ - {2,{0,2,0,0},{ I0_WWW, I1_XYZ, - I0_111, I1__Y_, - 0,0,0,0}}, - /* 01W */ - {3,{0,2,2,0},{ I0_WWW, I1___Z, - I0_000, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* 11W */ - {2,{0,2,0,0},{ I0_WWW, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XX0 */ - {2,{0,2,0,0},{ I0_XXX, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* YX0 */ - {3,{0,0,2,0},{ I0_YYY, I1_X__, - I0_XXX, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* ZX0 */ - {2,{0,2,0,0},{ I0_ZXY, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* WX0 */ - {3,{0,0,2,0},{ I0_WZY, I1_X__, - I0_XXX, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* 0X0 */ - {2,{0,2,0,0},{ I0_XXX, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1X0 */ - {3,{0,2,2,0},{ I0_XXX, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XY0 */ - {2,{0,2,0,0},{ I0_XYZ, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* YY0 */ - {2,{0,2,0,0},{ I0_YYY, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* ZY0 */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_ZZZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* WY0 */ - {3,{0,0,2,0},{ I0_WZY, I1_X__, - I0_XYZ, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* 0Y0 */ - {2,{0,2,0,0},{ I0_XYZ, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1Y0 */ - {3,{0,2,2,0},{ I0_XYZ, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XZ0 */ - {3,{0,0,2,0},{ I0_ZZZ, I1__Y_, - I0_XYZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* YZ0 */ - {2,{0,2,0,0},{ I0_YZX, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* ZZ0 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* WZ0 */ - {3,{0,0,2,0},{ I0_XYZ, I1_XYZ, - I0_WZY, I1_XY_, - I0_000, I1___Z, - 0,0}}, - /* 0Z0 */ - {2,{0,2,0,0},{ I0_ZZZ, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1Z0 */ - {3,{0,2,2,0},{ I0_ZZZ, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XW0 */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* YW0 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_YYY, I1_X__, - 0,0}}, - /* ZW0 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_ZZZ, I1_X__, - 0,0}}, - /* WW0 */ - {2,{0,2,0,0},{ I0_WWW, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* 0W0 */ - {2,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1W0 */ - {3,{0,2,2,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X00 */ - {2,{0,2,0,0},{ I0_XYZ, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* Y00 */ - {2,{0,2,0,0},{ I0_YYY, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* Z00 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* W00 */ - {2,{2,0,0,0},{ I0_WZY, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* 000 */ - {1,{2,0,0,0},{ I0_000, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* 100 */ - {2,{2,2,0,0},{ I0_000, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* X10 */ - {3,{0,2,2,0},{ I0_XYZ, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* Y10 */ - {3,{0,2,2,0},{ I0_YYY, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* Z10 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* W10 */ - {3,{0,2,2,0},{ I0_WZY, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 010 */ - {2,{2,2,0,0},{ I0_000, I1_X_Z, - I0_111, I1__Y_, - 0, 0, 0, 0 } }, - /* 110 */ - {2,{2,2,0,0},{ I0_000, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - - - - /* XX1 */ - {2,{0,2,0,0},{ I0_XXX, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* YX1 */ - {3,{0,0,2,0},{ I0_YYY, I1_X__, - I0_XXX, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* ZX1 */ - {2,{0,2,0,0},{ I0_ZXY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* WX1 */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* 0X1 */ - {3,{0,2,2,0},{ I0_XXX, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1X1 */ - {2,{0,2,0,0},{ I0_XXX, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XY1 */ - {2,{0,2,0,0},{ I0_XYZ, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* YY1 */ - {2,{0,2,0,0},{ I0_YYY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* ZY1 */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_ZZZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* WY1 */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XYZ, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* 0Y1 */ - {3,{0,2,2,0},{ I0_XYZ, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1Y1 */ - {2,{0,2,0,0},{ I0_XYZ, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZ1 */ - {3,{0,0,2,0},{ I0_ZZZ, I1__Y_, - I0_XYZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* YZ1 */ - {2,{0,2,0,0},{ I0_YZX, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* ZZ1 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_XYZ, - I0_111, I1___Z, - 0,0,0,0}}, - /* WZ1 */ - {2,{0,2,0,0},{ I0_WZY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* 0Z1 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1Z1 */ - {2,{0,2,0,0},{ I0_ZZZ, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XW1 */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* YW1 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_YYY, I1_X__, - 0,0}}, - /* ZW1 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_ZZZ, I1_X__, - 0,0}}, - /* WW1 */ - {2,{0,2,0,0},{ I0_WWW, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* 0W1 */ - {3,{0,2,2,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1W1 */ - {2,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* X01 */ - {3,{0,2,2,0},{ I0_XYZ, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* Y01 */ - {3,{0,2,2,0},{ I0_YYY, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* Z01 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* W01 */ - {3,{0,2,2,0},{ I0_WZY, I1_XYZ, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 001 */ - {2,{2,2,0,0},{ I0_111, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 101 */ - {2,{2,2,0,0},{ I0_111, I1_X_Z, - I0_000, I1__Y_, - 0, 0, 0, 0 } }, - SEMPTY,SEMPTY, - /* X11 */ - {2,{0,2,0,0},{ I0_XYZ, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* Y11 */ - {2,{0,2,0,0},{ I0_YYY, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* Z11 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* W11 */ - {2,{0,2,0,0},{ I0_WZY, I1_XYZ, - I0_111, I1__YZ, - 0,0,0,0}}, - /* 011 */ - {2,{2,2,0,0},{ I0_111, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 111 */ - {1,{2,0,0,0},{ I0_111, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY -}; - -/****************************************************************************** -* Color source mask table -******************************************************************************/ - -#define S_111 R300_FPI0_ARGC_ONE -#define S_000 R300_FPI0_ARGC_ZERO - -#define S0XXX R300_FPI0_ARGC_SRC0C_XXX -#define S0YYY R300_FPI0_ARGC_SRC0C_YYY -#define S0ZZZ R300_FPI0_ARGC_SRC0C_ZZZ -#define S0WWW R300_FPI0_ARGC_SRC0A -#define S0XYZ R300_FPI0_ARGC_SRC0C_XYZ -#define S0ZXY R300_FPI0_ARGC_SRC0C_ZXY -#define S0YZX R300_FPI0_ARGC_SRC0C_YZX -#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY -#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY - -#define S1XXX R300_FPI0_ARGC_SRC1C_XXX -#define S1YYY R300_FPI0_ARGC_SRC1C_YYY -#define S1ZZZ R300_FPI0_ARGC_SRC1C_ZZZ -#define S1WWW R300_FPI0_ARGC_SRC1A -#define S1XYZ R300_FPI0_ARGC_SRC1C_XYZ -#define S1ZXY R300_FPI0_ARGC_SRC1C_ZXY -#define S1YZX R300_FPI0_ARGC_SRC1C_YZX -#define S1WZY R300_FPI0_ARGC_SRC1CA_WZY - -#define S2XXX R300_FPI0_ARGC_SRC2C_XXX -#define S2YYY R300_FPI0_ARGC_SRC2C_YYY -#define S2ZZZ R300_FPI0_ARGC_SRC2C_ZZZ -#define S2WWW R300_FPI0_ARGC_SRC2A -#define S2XYZ R300_FPI0_ARGC_SRC2C_XYZ -#define S2ZXY R300_FPI0_ARGC_SRC2C_ZXY -#define S2YZX R300_FPI0_ARGC_SRC2C_YZX -#define S2WZY R300_FPI0_ARGC_SRC2CA_WZY - -#define ntnat 32 - -const GLuint r300_swz_srcc_mask[3][512] = { - { - S0XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S0YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S0WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - }, - { - S1XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S1YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S1WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - }, - { - S2XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S2YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S2WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - } -}; - -/****************************************************************************** -* Alpha source mask table -******************************************************************************/ - -GLuint r300_swz_srca_mask[3][6] = { - { R300_FPI2_ARGA_SRC0C_X, - R300_FPI2_ARGA_SRC0C_Y, - R300_FPI2_ARGA_SRC0C_Z, - R300_FPI2_ARGA_SRC0A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, - { R300_FPI2_ARGA_SRC1C_X, - R300_FPI2_ARGA_SRC1C_Y, - R300_FPI2_ARGA_SRC1C_Z, - R300_FPI2_ARGA_SRC1A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, - { R300_FPI2_ARGA_SRC2C_X, - R300_FPI2_ARGA_SRC2C_Y, - R300_FPI2_ARGA_SRC2C_Z, - R300_FPI2_ARGA_SRC2A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, -}; diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 03f168365dc..211c451f661 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_vp_build.h" @@ -352,7 +352,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx, r300EmitState(rmesa); for(i=0; i < VB->PrimitiveCount; i++){ - GLuint prim = VB->Primitive[i].mode; + GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; @@ -385,8 +385,18 @@ GLboolean r300_run_vb_render(GLcontext *ctx, int r300Fallback(GLcontext *ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program *rp = + (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; int i; + if (rp) { + if (!rp->translated) + r300_translate_fragment_shader(r300, rp); + + FALLBACK_IF(!rp->translated); + } + /* We do not do SELECT or FEEDBACK (yet ?) * Is it worth doing them ? */ @@ -406,6 +416,10 @@ int r300Fallback(GLcontext *ctx) */ FALLBACK_IF(ctx->Fog.Enabled); #endif + FALLBACK_IF(ctx->Stencil._TestTwoSide && + (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] || + ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] || + ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1])); if(!r300->disable_lowimpact_fallback){ /* GL_POLYGON_OFFSET_POINT */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 72255066d59..906dfceb482 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "texformat.h" @@ -509,7 +509,6 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) if (r300->state.stencil.hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { - WARN_ONCE("TODO - double side stencil !\n"); r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_STENCIL_ENABLE; } else { @@ -863,9 +862,12 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); flag = translate_func(ctx->Stencil.Function[0]); - - rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) - | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT); + + if (ctx->Stencil._TestTwoSide) + flag = translate_func(ctx->Stencil.Function[1]); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; } @@ -894,10 +896,19 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT); + + if (ctx->Stencil._TestTwoSide) { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } else { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } } static void r300ClearStencil(GLcontext * ctx, GLint s) @@ -1809,10 +1820,10 @@ void r300SetupPixelShader(r300ContextPtr rmesa) if (!rp) /* should only happenen once, just after context is created */ return; - r300_translate_fragment_shader(rp); + r300_translate_fragment_shader(rmesa, rp); if (!rp->translated) { fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__); - exit(-1); + return; } #define OUTPUT_FIELD(st, reg, field) \ @@ -1874,7 +1885,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _ae_invalidate_state(ctx, new_state); diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index 2492a4a3a0a..2ff92e13289 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -960,26 +960,23 @@ static void position_invariant(struct gl_program *prog) static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, - GLint pos) + GLuint temp_index) { GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 }; struct prog_instruction *vpi; struct prog_instruction *vpi_insert; - GLuint temp_index; GLuint window_index; int i = 0; vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction)); - memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction)); + /* all but END */ + memcpy(vpi, prog->Instructions, (prog->NumInstructions - 1) * sizeof(struct prog_instruction)); + /* END */ + memcpy(&vpi[prog->NumInstructions + 4], &prog->Instructions[prog->NumInstructions - 1], + sizeof(struct prog_instruction)); - vpi_insert = &vpi[pos]; - - /* make a copy before outputting VERT_RESULT_HPOS */ - vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File; - vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index; - - vpi_insert++; + vpi_insert = &vpi[prog->NumInstructions - 1]; memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction)); vpi_insert[i].Opcode = OPCODE_MOV; @@ -1062,8 +1059,6 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE); i++; - memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction)); - free(prog->Instructions); prog->Instructions = vpi; @@ -1078,16 +1073,18 @@ static void pos_as_texcoord(struct r300_vertex_program *vp, struct gl_program *prog) { struct prog_instruction *vpi; - int pos = 0; - - for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){ + GLuint tempregi = prog->NumTemporaries; + /* should do something else if no temps left... */ + prog->NumTemporaries++; + + for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++){ if( vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS ){ - insert_wpos(vp, prog, pos); - break; + vpi->DstReg.File = PROGRAM_TEMPORARY; + vpi->DstReg.Index = tempregi; } } - + insert_wpos(vp, prog, tempregi); } static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key, @@ -1101,8 +1098,9 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key vp->wpos_idx = wpos_idx; - if(mesa_vp->IsPositionInvariant) + if(mesa_vp->IsPositionInvariant) { position_invariant(&mesa_vp->Base); + } if(wpos_idx > -1) pos_as_texcoord(vp, &mesa_vp->Base); @@ -1158,6 +1156,10 @@ void r300_select_vertex_shader(r300ContextPtr r300) wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + if(vpc->mesa_program.IsPositionInvariant) { + /* we wan't position don't we ? */ + wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); + } for (vp = vpc->progs; vp; vp = vp->next) if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { @@ -1170,6 +1172,5 @@ void r300_select_vertex_shader(r300ContextPtr r300) vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; - r300->selected_vp = vp; } diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 0ceaf7ebb7d..ddadf83a003 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" diff --git a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c index 72c03c53ad9..0625e5bc571 100644 --- a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c +++ b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c @@ -46,6 +46,8 @@ #include "state.h" #include "image.h" +#include "vbo/vbo_context.h" + #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \ rvb->AttribPtr[(a)].type = GL_FLOAT, \ rvb->AttribPtr[(a)].stride = vb->b->stride, \ @@ -129,15 +131,7 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) CONV(i, VertexAttrib[i]); for (i=0; i < VERT_ATTRIB_MAX; i++) { - if (enabled & (1 << i)) { - rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; - } else { - def.data = ctx->Current.Attrib[i]; - memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt)); - } - - /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i]) - fprintf(stderr, "%d is default coord\n", i);*/ + rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; } for(i=0; i < VERT_ATTRIB_MAX; i++){ @@ -177,177 +171,18 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) void radeon_init_vtxfmt_a(r300ContextPtr rmesa); -static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices ) -{ - GET_CURRENT_CONTEXT(ctx); - r300ContextPtr rmesa = R300_CONTEXT(ctx); - int elt_size; - int i; - unsigned int min = ~0, max = 0; - struct tnl_prim prim; - static void *ptr = NULL; - struct r300_dma_region rvb; - const GLvoid *indices = c_indices; - - if (count > 65535) { - WARN_ONCE("Too many verts!\n"); - goto fallback; - } - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Data) { - _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; - } - /* actual address is the sum of pointers */ - indices = (GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); - } - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - memset(&rvb, 0, sizeof(rvb)); - switch (type) { - case GL_UNSIGNED_BYTE: - for (i=0; i < count; i++) { - if(((unsigned char *)indices)[i] < min) - min = ((unsigned char *)indices)[i]; - if(((unsigned char *)indices)[i] > max) - max = ((unsigned char *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_SHORT: - for (i=0; i < count; i++) { - if(((unsigned short int *)indices)[i] < min) - min = ((unsigned short int *)indices)[i]; - if(((unsigned short int *)indices)[i] > max) - max = ((unsigned short int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_INT: - for (i=0; i < count; i++) { - if(((unsigned int *)indices)[i] < min) - min = ((unsigned int *)indices)[i]; - if(((unsigned int *)indices)[i] > max) - max = ((unsigned int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - if (max - min <= 65535) - elt_size = 2; - else - elt_size = 4; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - - - if (elt_size == 2) - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - else - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - break; - - default: - WARN_ONCE("Unknown elt type!\n"); - goto fallback; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - r300UpdateShaders(rmesa); - - if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - rmesa->state.VB.Count = max - min + 1; - - r300UpdateShaderStates(rmesa); - - rmesa->state.VB.Primitive = &prim; - rmesa->state.VB.PrimitiveCount = 1; - - prim.mode = mode | PRIM_BEGIN | PRIM_END; - if (rmesa->state.VB.LockCount) - prim.start = min - rmesa->state.VB.LockFirst; - else - prim.start = 0; - prim.count = count; - - rmesa->state.VB.Elts = ptr; - rmesa->state.VB.elt_size = elt_size; - - if (r300_run_vb_render(ctx, NULL)) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - if(rvb.buf) - radeon_mm_use(rmesa, rvb.buf->id); - - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); -} -static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices) +static void radeonDrawRangeElements(GLcontext *ctx, + GLenum mode, + GLuint min, + GLuint max, + GLsizei count, + GLenum type, + const GLvoid *c_indices) { - GET_CURRENT_CONTEXT(ctx); +#if 1 + return GL_FALSE; +#else r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; int elt_size; @@ -371,26 +206,23 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei indices += i * _mesa_sizeof_type(type); count -= i; } - return ; + return GL_TRUE; } WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ if (!ctx->Array.ElementArrayBufferObj->Data) { _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; + return GL_TRUE; } /* actual address is the sum of pointers */ indices = (GLvoid *) ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); } - if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices )) - return; - FLUSH_CURRENT( ctx, 0 ); #ifdef OPTIMIZE_ELTS min = 0; @@ -465,7 +297,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei default: WARN_ONCE("Unknown elt type!\n"); - goto fallback; + return GL_FALSE; } /* XXX: setup_arrays before state update? */ @@ -477,7 +309,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } rmesa->state.VB.Count = max - min + 1; @@ -501,37 +333,34 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (r300_run_vb_render(ctx, NULL)) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } if(rvb.buf) radeon_mm_use(rmesa, rvb.buf->id); r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } -static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) +static GLboolean radeonDrawArrays( GLcontext *ctx, + GLenum mode, GLint start, GLsizei count ) { +#if 1 + return GL_FALSE; +#else GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; if (count > 65535) { + /* TODO: split into multiple draws. + */ WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - FLUSH_CURRENT( ctx, 0 ); if (ctx->NewState) @@ -542,7 +371,7 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) r300UpdateShaders(rmesa); if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL) - goto fallback; + return GL_FALSE; rmesa->state.VB.Count = count; @@ -564,31 +393,70 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) rmesa->state.VB.elt_max = 0; if (r300_run_vb_render(ctx, NULL)) - goto fallback; + return GL_FALSE; - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawArrays(GET_DISPATCH(), (mode, start, count)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } +static void radeon_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + if (ib == NULL) { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawArrays(ctx, + prim->mode, + prim->start, + prim->count)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } else { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawRangeElements(ctx, + prim->mode, + min_index, + max_index, + prim->count, + ib->types, + ib->ptr)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } +} + void radeon_init_vtxfmt_a(r300ContextPtr rmesa) { GLcontext *ctx; - GLvertexformat *vfmt; - - ctx = rmesa->radeon.glCtx; - vfmt = (GLvertexformat *)ctx->TnlModule.Current; - - vfmt->DrawElements = radeonDrawElements; - vfmt->DrawArrays = radeonDrawArrays; - vfmt->DrawRangeElements = radeonDrawRangeElements; + struct vbo_context *vbo = vbo_context(ctx); + vbo->draw_prims = radeon_draw_prims; } + #endif #ifdef HW_VBOS diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 6e46620b397..f223b2d9228 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -22,11 +22,7 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_span.c \ radeon_maos.c \ - radeon_sanity.c \ - radeon_vtxfmt.c \ - radeon_vtxfmt_c.c \ - radeon_vtxfmt_sse.c \ - radeon_vtxfmt_x86.c + radeon_sanity.c C_SOURCES = \ $(COMMON_SOURCES) \ @@ -34,8 +30,7 @@ C_SOURCES = \ DRIVER_DEFINES = -DRADEON_COMMON=0 -X86_SOURCES = \ - radeon_vtxtmp_x86.S +X86_SOURCES = include ../Makefile.template diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 8b92e3fe65f..6bc2c4aa5c5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_tcl.h" -#include "radeon_vtxfmt.h" #include "radeon_maos.h" #define need_GL_ARB_multisample @@ -361,7 +360,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -370,13 +369,10 @@ radeonCreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, radeon_pipeline ); - ctx->Driver.FlushVertices = radeonFlushVertices; /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); - -/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */ +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and T&L to match hardware characteristics: */ @@ -450,10 +446,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, } if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); +/* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */ } return GL_TRUE; } @@ -484,7 +477,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); radeonDestroySwtcl( rmesa->glCtx ); @@ -494,12 +487,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) radeonFlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtDestroy( rmesa->glCtx ); - } - _mesa_vector4f_free( &rmesa->tcl.ObjClean ); if (rmesa->state.scissor.pClipRects) { @@ -621,9 +608,6 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - radeonVtxfmtMakeCurrent( newCtx->glCtx ); - } else { if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx is null\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 0a7c3b2f544..02cea2f4e37 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -529,7 +529,6 @@ struct radeon_store { */ struct radeon_tcl_info { GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* Temporary for cases where incoming vertex data is incompatible @@ -600,75 +599,6 @@ struct radeon_ioctl { #define RADEON_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, int ); - struct dynfn *(*Vertex2fv)( GLcontext *, int ); - struct dynfn *(*Vertex3f)( GLcontext *, int ); - struct dynfn *(*Vertex3fv)( GLcontext *, int ); - struct dynfn *(*Color4ub)( GLcontext *, int ); - struct dynfn *(*Color4ubv)( GLcontext *, int ); - struct dynfn *(*Color3ub)( GLcontext *, int ); - struct dynfn *(*Color3ubv)( GLcontext *, int ); - struct dynfn *(*Color4f)( GLcontext *, int ); - struct dynfn *(*Color4fv)( GLcontext *, int ); - struct dynfn *(*Color3f)( GLcontext *, int ); - struct dynfn *(*Color3fv)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int ); - struct dynfn *(*Normal3f)( GLcontext *, int ); - struct dynfn *(*Normal3fv)( GLcontext *, int ); - struct dynfn *(*TexCoord2f)( GLcontext *, int ); - struct dynfn *(*TexCoord2fv)( GLcontext *, int ); - struct dynfn *(*TexCoord1f)( GLcontext *, int ); - struct dynfn *(*TexCoord1fv)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int ); -}; - - struct radeon_prim { GLuint start; @@ -685,43 +615,6 @@ struct radeon_prim { */ #define RADEON_MAX_VERTEX_SIZE 20 -struct radeon_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; radeon_color_t color; } vertex[RADEON_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - radeon_color_t *colorptr; - GLfloat *floatspecptr; - radeon_color_t *specptr; - GLfloat *texcoordptr[4]; /* 3 (TMU) + 1 for radeon_vtxfmt_c.c when GL_TEXTURE3 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vertex_format; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct radeon_prim primlist[RADEON_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - - - struct radeon_context { GLcontext *glCtx; /* Mesa context */ @@ -808,10 +701,6 @@ struct radeon_context { */ struct radeon_swtcl_info swtcl; - /* radeon_vtxfmt.c - */ - struct radeon_vbinfo vb; - /* Mirrors of some DRI state */ struct radeon_dri_mirror dri; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 737490fcde0..4c64bc201ae 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -1087,10 +1087,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } } - /* Flip top to bottom */ - cx += dPriv->x; - cy = dPriv->y + dPriv->h - cy - ch; - LOCK_HARDWARE( rmesa ); /* compute region after locking: */ @@ -1099,6 +1095,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + /* Throttle the number of clear ioctls we do. */ while ( 1 ) { diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 91a60bb9f15..65dbecf7a6c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -37,7 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "imports.h" #include "mtypes.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 279357ab590..fc5aa114621 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_span.h" #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) #include "r300_context.h" +#include "r300_fragprog.h" #include "radeon_span.h" #endif @@ -163,6 +164,18 @@ DRI_CONF_OPT_BEGIN(disable_lowimpact_fallback,bool,def) \ DRI_CONF_DESC(en,"Disable Low-impact fallback") \ DRI_CONF_OPT_END +#define DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(def) \ +DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \ + DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \ +DRI_CONF_OPT_END + +#define DRI_CONF_FP_OPTIMIZATION(def) \ +DRI_CONF_OPT_BEGIN_V(fp_optimization,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Fragment Program optimization") \ + DRI_CONF_ENUM(0,"Optimize for Speed") \ + DRI_CONF_ENUM(1,"Optimize for Quality") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -174,6 +187,7 @@ DRI_CONF_BEGIN DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8) DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) DRI_CONF_DISABLE_FALLBACK(false) + DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) @@ -184,12 +198,13 @@ DRI_CONF_BEGIN DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) + DRI_CONF_FP_OPTIMIZATION(DRI_CONF_FP_OPTIMIZATION_SPEED) DRI_CONF_SECTION_END DRI_CONF_SECTION_DEBUG DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 16; +static const GLuint __driNConfigOptions = 18; #ifndef RADEON_DEBUG int RADEON_DEBUG = 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 216d7dca174..e19202fa443 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "context.h" #include "framebuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "drirenderbuffer.h" static void radeonUpdateSpecular( GLcontext *ctx ); @@ -2303,11 +2302,10 @@ static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); RADEON_CONTEXT(ctx)->NewGLState |= new_state; - radeonVtxfmtInvalidate( ctx ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 5682d95ae10..5fc34f09331 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -33,7 +33,7 @@ #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -44,7 +44,6 @@ #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index e36a710d33a..7ce1fa67cf6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" /* for _tnl_FlushVertices */ #include "radeon_context.h" #include "radeon_ioctl.h" @@ -848,14 +847,6 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) } -void radeonFlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) ); -} - /**********************************************************************/ /* Initialization. */ /**********************************************************************/ diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.h b/src/mesa/drivers/dri/radeon/radeon_swtcl.h index f95a52c0b8e..64f9019513d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.h +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.h @@ -43,7 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonInitSwtcl( GLcontext *ctx ); extern void radeonDestroySwtcl( GLcontext *ctx ); -extern void radeonFlushVertices( GLcontext *ctx, GLuint flags ); extern void radeonChooseRenderState( GLcontext *ctx ); extern void radeonChooseVertexState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index ffd49b525b8..5ad044c2628 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "enums.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c deleted file mode 100644 index a5a9eb144b5..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ -#include "glheader.h" -#include "imports.h" -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_tex.h" -#include "radeon_tcl.h" -#include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" - -#define VERT_ATTRIB_TEX(u) (VERT_ATTRIB_TEX0 + (u)) - -#include "dispatch.h" - -static void radeonVtxfmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( radeonContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - - -void radeon_copy_to_current( GLcontext *ctx ) -{ - GLuint unit; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA) - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (rmesa->vb.vertex_format & RADEON_ST_BIT(unit)) { - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0] = rmesa->vb.texcoordptr[unit][0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1] = rmesa->vb.texcoordptr[unit][1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][2] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( radeonContextPtr rmesa ) -{ - int i,j; - struct radeon_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vertex_format; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - radeonEmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( radeonContextPtr rmesa, GLuint mode ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( radeonContextPtr rmesa, GLuint flags ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[RADEON_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2(nr, 2); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - radeonVtxfmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -static void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind = rmesa->vb.vertex_format; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint unit; - - if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - if (ind & RADEON_CP_VC_FRMT_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - radeon_color_t *col = (radeon_color_t *)&tmp[i][offset]; - CALL_Color4ub(GET_DISPATCH(), (col->red, col->green, col->blue, col->alpha)); - offset++; - } - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset]; - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec->red, spec->green, spec->blue)); - offset++; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), &tmp[i][offset])); - offset += 2; - } - } - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind & RADEON_CP_VC_FRMT_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha)); - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - else - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), - rmesa->vb.texcoordptr[unit])); - } - } -} - -static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - radeonRefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (RADEON_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, (void *)rmesa->vb.dmaptr); - if (RADEON_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - - -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint ind = RADEON_CP_VC_FRMT_Z; - GLuint unit; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind |= RADEON_CP_VC_FRMT_N0; - - /* TODO: make this data driven: If we receive only ubytes, send - * color as ubytes. Also check if converting (with free - * checking for overflow) is cheaper than sending floats - * directly. - */ - if (ctx->Light.ColorMaterialEnabled) { - ind |= (RADEON_CP_VC_FRMT_FPCOLOR | - RADEON_CP_VC_FRMT_FPALPHA); - } - else - ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */ - } - else { - /* TODO: make this data driven? - */ - ind |= RADEON_CP_VC_FRMT_PKCOLOR; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - if (ctx->Texture.Unit[unit].TexGenEnabled) { - if (rmesa->TexGenNeedNormals[unit]) { - ind |= RADEON_CP_VC_FRMT_N0; - } - } else { - if (ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] != 1.0) { - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s: q%u\n", __FUNCTION__, unit); - return GL_FALSE; - } - ind |= RADEON_ST_BIT(unit); - } - } - } - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind ); - - RADEON_NEWPRIM(rmesa); - rmesa->vb.vertex_format = ind; - rmesa->vb.vertex_size = 3; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind & RADEON_CP_VC_FRMT_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - - if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR)); - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - - if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - rmesa->vb.vertex_size += 1; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - /* fog ??? */ -/* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha, - radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */ - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - rmesa->vb.texcoordptr[unit] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 2; - rmesa->vb.texcoordptr[unit][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0]; - rmesa->vb.texcoordptr[unit][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format; - } - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - -void radeonVtxfmtInvalidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void radeonVtxfmtValidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = radeonVtxfmtFlushVertices; - ctx->Driver.NewList = radeonNewList; - rmesa->vb.installed = GL_TRUE; - } - else if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void radeon_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - radeonUpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void radeon_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { -/* FIXME: what are these constants? */ - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - RADEON_NEWPRIM( rmesa ); - radeonRefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void radeon_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (RADEON_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) radeon_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - radeon_Begin( p ); - return GL_TRUE; -} - -static void radeonVtxfmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - radeon_copy_to_current( ctx ); - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( RADEON_CONTEXT( ctx ) ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - radeonVtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = radeon_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = radeon_Begin; - vfmt->End = radeon_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = radeon_fallback_DrawArrays; - vfmt->DrawElements = radeon_fallback_DrawElements; - vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = radeon_fallback_CallList; - vfmt->CallLists = radeon_fallback_CallLists; - vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = radeon_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = radeon_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = radeon_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = radeon_fallback_EvalMesh1; - vfmt->EvalMesh2 = radeon_fallback_EvalMesh2; - vfmt->EvalPoint1 = radeon_fallback_EvalPoint1; - vfmt->EvalPoint2 = radeon_fallback_EvalPoint2; - vfmt->TexCoord3f = radeon_fallback_TexCoord3f; - vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv; - vfmt->TexCoord4f = radeon_fallback_TexCoord4f; - vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv; - vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = radeon_fallback_Vertex4f; - vfmt->Vertex4fv = radeon_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = radeon_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = radeon_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = radeon_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = radeon_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = radeon_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = radeon_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT; - - (void)radeon_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); - - radeonInitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - - - -void radeonVtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void radeonVtxfmtDestroy( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h deleted file mode 100644 index a656e49e445..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.3 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __RADEON_VTXFMT_H__ -#define __RADEON_VTXFMT_H__ - -#include "radeon_context.h" - - -extern void radeonVtxfmtUpdate( GLcontext *ctx ); -extern void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void radeonVtxfmtInvalidate( GLcontext *ctx ); -extern void radeonVtxfmtDestroy( GLcontext *ctx ); -extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void radeonVtxfmtMakeCurrent( GLcontext *ctx ); -extern void radeonVtxfmtUnbindContext( GLcontext *ctx ); - -extern void radeon_copy_to_current( GLcontext *ctx ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key = key; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \ - __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void radeonInitX86Codegen( struct dfn_generators *gen ); -void radeonInitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in radeon_vtxfmt_x86.c - */ -struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int ); - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c deleted file mode 100644 index aac029aa0e4..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c +++ /dev/null @@ -1,924 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c,v 1.2 2002/12/16 16:18:59 dawes Exp $ */ -/************************************************************************** - -Copyright 2002 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "radeon_vtxfmt.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = *(int *)&rmesa->vb.vertex[i]; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -#if 0 -/* Color for ubyte (packed) color formats: - */ -static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void radeon_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void radeon_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void radeon_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void radeon_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void radeon_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void radeon_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void radeon_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void radeon_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - -/* Normal - */ -static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void radeon_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* TexCoord - */ -static void radeon_TexCoord1f( GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_TexCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_TexCoord2f( GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_TexCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = v[1]; -} - - -/* MultiTexcoord - * - * Technically speaking, these functions should subtract GL_TEXTURE0 from - * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, - * which has the low-order 5 bits 0. For all possible valid values of - * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target - * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so - * the subtraction has been omitted. - */ - -static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = v[1]; -} - -static struct dynfn *lookup( struct dynfn *l, int key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, radeon_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_ub); \ - } \ - else if ((rmesa->vb.vertex_format & \ - (ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - radeon_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, radeon_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, ((rmesa->vb.vertex_format & ACTIVE_PKSPEC) != 0) \ - ? radeon_##FN##_ub : radeon_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - -/* Shorthands - */ -#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z) -#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0 - -#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR -#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR -#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA -#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR) - -#define ACTIVE_PKSPEC RADEON_CP_VC_FRMT_PKSPEC -#define ACTIVE_FPSPEC RADEON_CP_VC_FRMT_FPSPEC -#define ACTIVE_SPEC (ACTIVE_FPSPEC|ACTIVE_PKSPEC) - -#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0 -#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1 -#define ACTIVE_ST2 RADEON_CP_VC_FRMT_ST2 -#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST2) - -/* Each codegen function should be able to be fully specified by a - * subsetted version of rmesa->vb.vertex_format. - */ -#define MASK_NORM (ACTIVE_XYZW) -#define MASK_COLOR (MASK_NORM|ACTIVE_NORM) -#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR) -#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC) -#define MASK_ST1 (MASK_ST0|ACTIVE_ST0) -#define MASK_ST2 (MASK_ST1|ACTIVE_ST1) -#define MASK_ST_ALL (MASK_ST2|ACTIVE_ST2) -#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA) - - -typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); -typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); -typedef void (*p2f)( GLfloat, GLfloat ); -typedef void (*p1f)( GLfloat ); -typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); -typedef void (*pe1f)( GLenum, GLfloat ); -typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); -typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); -typedef void (*pfv)( const GLfloat * ); -typedef void (*pefv)( GLenum, const GLfloat * ); -typedef void (*pubv)( const GLubyte * ); - - -CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM, - (const GLfloat *v), (v)) - -#if 0 -CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) -CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -#endif - -CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) -CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) -CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) - - -#if 0 -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC, - (const GLubyte *v), (v)) -#endif -CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC, - (const GLfloat *v), (v)) - -CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) -CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0, - (GLfloat a), (a)) -CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) - -CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a,GLfloat b), (u,a,b)) -CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) -CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a), (u,a)) -CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) - -CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) -CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) - - - - - -void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ) -{ - vfmt->Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; - -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - radeonInitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - radeonInitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c deleted file mode 100644 index 0f0fc9e0653..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *radeon_makeSSEAttribute2fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn * radeon_makeSSENormal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSENormal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSEColor3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSEColor3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSETexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *radeon_makeSSETexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -static struct dynfn *radeon_makeSSEMultiTexCoord2fv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *radeon_makeSSEMultiTexCoord2f( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) radeon_makeSSENormal3fv; - gen->Normal3f = (void *) radeon_makeSSENormal3f; - gen->Color3fv = (void *) radeon_makeSSEColor3fv; - gen->Color3f = (void *) radeon_makeSSEColor3f; - gen->TexCoord2fv = (void *) radeon_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) radeon_makeSSETexCoord2f; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fvARB = (void *) radeon_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) radeon_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c deleted file mode 100644 index 529e79065e9..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c,v 1.2 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -radeon_makeX86Attribute3fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key ) -{ - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, - int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = radeon_makeX86Vertex3f; - gen->Vertex3fv = radeon_makeX86Vertex3fv; - gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = radeon_makeX86Normal3f; - gen->Normal3fv = radeon_makeX86Normal3fv; - gen->TexCoord2f = radeon_makeX86TexCoord2f; - gen->TexCoord2fv = radeon_makeX86TexCoord2fv; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = radeon_makeX86Color3f; - gen->Color3fv = radeon_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = radeon_makeX86Vertex2f; */ -/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */ -/* gen->Color3ub = radeon_makeX86Color3ub; */ -/* gen->Color3ubv = radeon_makeX86Color3ubv; */ -/* gen->Color4f = radeon_makeX86Color4f; */ -/* gen->Color4fv = radeon_makeX86Color4fv; */ -/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S deleted file mode 100644 index 1b433491aa8..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S +++ /dev/null @@ -1,498 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $3, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $3,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $3, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $3,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/drivers/dri/s3v/s3v_context.c b/src/mesa/drivers/dri/s3v/s3v_context.c index 7b0aa0daee0..2d2f704ad77 100644 --- a/src/mesa/drivers/dri/s3v/s3v_context.c +++ b/src/mesa/drivers/dri/s3v/s3v_context.c @@ -6,7 +6,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -139,7 +139,7 @@ GLboolean s3vCreateContext(const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c index fcea901c1c9..b86b618c117 100644 --- a/src/mesa/drivers/dri/s3v/s3v_state.c +++ b/src/mesa/drivers/dri/s3v/s3v_state.c @@ -10,7 +10,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" /* #define DEBUG(str) printf str */ @@ -825,7 +825,7 @@ static void s3vDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); S3V_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c index 533424cdeab..c451f7452bf 100644 --- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c +++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c @@ -13,7 +13,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" /* #define DEBUG(str) printf str */ @@ -38,7 +38,7 @@ s3vDestroyContext(__DRIcontextPrivate *driContextPriv) if (vmesa) { _swsetup_DestroyContext( vmesa->glCtx ); _tnl_DestroyContext( vmesa->glCtx ); - _ac_DestroyContext( vmesa->glCtx ); + _vbo_DestroyContext( vmesa->glCtx ); _swrast_DestroyContext( vmesa->glCtx ); s3vFreeVB( vmesa->glCtx ); diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index f51e321a4a6..ad79b9235c1 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -40,7 +40,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -509,7 +509,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -599,7 +599,7 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index 2f20dc23b6e..741a9dda4f7 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -41,7 +41,7 @@ #include "savage_bci.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1673,7 +1673,7 @@ static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c index 6bc2c6de3bf..08402fb3e2a 100644 --- a/src/mesa/drivers/dri/sis/sis6326_state.c +++ b/src/mesa/drivers/dri/sis/sis6326_state.c @@ -37,7 +37,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -645,7 +645,7 @@ sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c index a300a080ec0..89b81da347a 100644 --- a/src/mesa/drivers/dri/sis/sis_context.c +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -53,7 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -306,7 +306,7 @@ sisCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -353,7 +353,7 @@ sisDestroyContext ( __DRIcontextPrivate *driContextPriv ) if ( smesa != NULL ) { _swsetup_DestroyContext( smesa->glCtx ); _tnl_DestroyContext( smesa->glCtx ); - _ac_DestroyContext( smesa->glCtx ); + _vbo_DestroyContext( smesa->glCtx ); _swrast_DestroyContext( smesa->glCtx ); if (smesa->using_agp) diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c index 2a10a5fbf62..33a2f089b82 100644 --- a/src/mesa/drivers/dri/sis/sis_state.c +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -707,7 +707,7 @@ sisDDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c index bd9dade89b5..a9163f49a8f 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c @@ -49,7 +49,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -328,7 +328,7 @@ GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -609,7 +609,7 @@ tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( fxMesa->glCtx ); _tnl_DestroyContext( fxMesa->glCtx ); - _ac_DestroyContext( fxMesa->glCtx ); + _vbo_DestroyContext( fxMesa->glCtx ); _swrast_DestroyContext( fxMesa->glCtx ); tdfxFreeVB( fxMesa->glCtx ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index 59e6549e5ef..42cb5dfaa38 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -46,7 +46,7 @@ #include "teximage.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -1234,7 +1234,7 @@ static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TDFX_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c index d3806586475..dbbd1ac0c69 100644 --- a/src/mesa/drivers/dri/trident/trident_context.c +++ b/src/mesa/drivers/dri/trident/trident_context.c @@ -30,7 +30,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -143,7 +143,7 @@ tridentCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -183,7 +183,7 @@ tridentDestroyContext(__DRIcontextPrivate *driContextPriv) if (tmesa) { _swsetup_DestroyContext( tmesa->glCtx ); _tnl_DestroyContext( tmesa->glCtx ); - _ac_DestroyContext( tmesa->glCtx ); + _vbo_DestroyContext( tmesa->glCtx ); _swrast_DestroyContext( tmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c index 037cce5f862..5303bd422ed 100644 --- a/src/mesa/drivers/dri/trident/trident_state.c +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -26,7 +26,7 @@ */ #include "trident_context.h" #include "trident_lock.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -468,7 +468,7 @@ tridentDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c index 2fe61e40390..6944bd66f9c 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_dri.c +++ b/src/mesa/drivers/dri/unichrome/server/via_dri.c @@ -1179,6 +1179,7 @@ static int viaInitFBDev(DRIDriverContext *ctx) pVia->Chipset = VIA_KM400; break; case PCI_CHIP_VT3204: + case PCI_CHIP_VT3344: pVia->Chipset = VIA_K8M800; break; case PCI_CHIP_VT3259: diff --git a/src/mesa/drivers/dri/unichrome/server/via_regs.h b/src/mesa/drivers/dri/unichrome/server/via_regs.h index 5c5eecbe831..87e1e9daa92 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_regs.h +++ b/src/mesa/drivers/dri/unichrome/server/via_regs.h @@ -44,6 +44,7 @@ #define PCI_CHIP_VT7205 0x7205 #define PCI_CHIP_VT3204 0x3108 #define PCI_CHIP_VT3259 0x3118 +#define PCI_CHIP_VT3344 0x3344 #define BIOS_BSIZE 1024 diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 49c24656551..bc5a414df60 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -42,7 +42,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -583,7 +583,7 @@ viaCreateContext(const __GLcontextModes *visual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -708,7 +708,7 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(vmesa->glCtx); _tnl_DestroyContext(vmesa->glCtx); - _ac_DestroyContext(vmesa->glCtx); + _vbo_DestroyContext(vmesa->glCtx); _swrast_DestroyContext(vmesa->glCtx); /* free the Mesa context */ _mesa_destroy_context(vmesa->glCtx); diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index 2c9cfca522e..30b9dc289a7 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -40,7 +40,7 @@ #include "via_3d_reg.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1507,7 +1507,7 @@ static void viaInvalidateState(GLcontext *ctx, GLuint newState) _swrast_InvalidateState(ctx, newState); _swsetup_InvalidateState(ctx, newState); - _ac_InvalidateState(ctx, newState); + _vbo_InvalidateState(ctx, newState); _tnl_InvalidateState(ctx, newState); } diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c index bd9d3ac0ad9..f9d57dbdd81 100644 --- a/src/mesa/drivers/fbdev/glfbdev.c +++ b/src/mesa/drivers/fbdev/glfbdev.c @@ -54,7 +54,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -143,7 +143,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -776,7 +776,7 @@ glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share ) /* Create module contexts */ glctx = (GLcontext *) &ctx->glcontext; _swrast_CreateContext( glctx ); - _ac_CreateContext( glctx ); + _vbo_CreateContext( glctx ); _tnl_CreateContext( glctx ); _swsetup_CreateContext( glctx ); _swsetup_Wakeup( glctx ); diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 47d7f2bdb99..85592d98dab 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -39,7 +39,7 @@ #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "teximage.h" #include "texformat.h" #include "texstore.h" @@ -563,7 +563,7 @@ ggi_mesa_context_t ggiMesaCreateContext(ggi_visual_t vis) _mesa_enable_sw_extensions(ctx->gl_ctx); _swrast_CreateContext(ctx->gl_ctx); - _ac_CreateContext(ctx->gl_ctx); + _vbo_CreateContext(ctx->gl_ctx); _tnl_CreateContext(ctx->gl_ctx); _swsetup_CreateContext(ctx->gl_ctx); diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index ef60602c832..43d3cd94051 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -55,7 +55,7 @@ #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" @@ -1783,7 +1783,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa) /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -1826,7 +1826,7 @@ fxDDDestroyFxMesaContext(fxMesaContext fxMesa) { _swsetup_DestroyContext(fxMesa->glCtx); _tnl_DestroyContext(fxMesa->glCtx); - _ac_DestroyContext(fxMesa->glCtx); + _vbo_DestroyContext(fxMesa->glCtx); _swrast_DestroyContext(fxMesa->glCtx); if (fxMesa->state) @@ -2101,7 +2101,7 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state) } _swrast_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 0b027eddec5..c4fc8821e50 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -41,7 +41,6 @@ #include "imports.h" #include "mtypes.h" #include "renderbuffer.h" -#include "array_cache/acache.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -51,6 +50,7 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" +#include "vbo/vbo.h" @@ -110,8 +110,8 @@ osmesa_update_state( GLcontext *ctx, GLuint new_state ) /* easy - just propogate */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); } @@ -1261,7 +1261,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, TNLcontext *tnl; if (!_swrast_CreateContext( ctx ) || - !_ac_CreateContext( ctx ) || + !_vbo_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(osmesa->gl_visual); @@ -1299,7 +1299,7 @@ OSMesaDestroyContext( OSMesaContext osmesa ) if (osmesa) { _swsetup_DestroyContext( &osmesa->mesa ); _tnl_DestroyContext( &osmesa->mesa ); - _ac_DestroyContext( &osmesa->mesa ); + _vbo_DestroyContext( &osmesa->mesa ); _swrast_DestroyContext( &osmesa->mesa ); _mesa_destroy_visual( osmesa->gl_visual ); diff --git a/src/mesa/drivers/svga/svgamesa15.c b/src/mesa/drivers/svga/svgamesa15.c index a4c0901e38f..ae5104d0c01 100644 --- a/src/mesa/drivers/svga/svgamesa15.c +++ b/src/mesa/drivers/svga/svgamesa15.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa15.c,v 1.12 2006/11/01 19:35:23 brianp Exp $ */ +/* $Id: svgamesa15.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library diff --git a/src/mesa/drivers/svga/svgamesa16.c b/src/mesa/drivers/svga/svgamesa16.c index 999c6331c9c..a59937bfb4b 100644 --- a/src/mesa/drivers/svga/svgamesa16.c +++ b/src/mesa/drivers/svga/svgamesa16.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa16.c,v 1.12 2006/11/01 19:35:23 brianp Exp $ */ +/* $Id: svgamesa16.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library diff --git a/src/mesa/drivers/svga/svgamesa24.c b/src/mesa/drivers/svga/svgamesa24.c index 93c84167ebb..dd15bf38db2 100644 --- a/src/mesa/drivers/svga/svgamesa24.c +++ b/src/mesa/drivers/svga/svgamesa24.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa24.c,v 1.13 2006/11/01 19:35:23 brianp Exp $ */ +/* $Id: svgamesa24.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library diff --git a/src/mesa/drivers/svga/svgamesa32.c b/src/mesa/drivers/svga/svgamesa32.c index 5a3a6776ce7..4da18795d8c 100644 --- a/src/mesa/drivers/svga/svgamesa32.c +++ b/src/mesa/drivers/svga/svgamesa32.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa32.c,v 1.13 2006/11/01 19:35:23 brianp Exp $ */ +/* $Id: svgamesa32.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library diff --git a/src/mesa/drivers/svga/svgamesa8.c b/src/mesa/drivers/svga/svgamesa8.c index e3f5eaebf6a..4264fcd9599 100644 --- a/src/mesa/drivers/svga/svgamesa8.c +++ b/src/mesa/drivers/svga/svgamesa8.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa8.c,v 1.10 2006/11/01 19:35:23 brianp Exp $ */ +/* $Id: svgamesa8.c,v 1.9.10.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library diff --git a/src/mesa/drivers/windows/gdi/mesa.def b/src/mesa/drivers/windows/gdi/mesa.def index f0b275730ca..8d654281215 100644 --- a/src/mesa/drivers/windows/gdi/mesa.def +++ b/src/mesa/drivers/windows/gdi/mesa.def @@ -859,9 +859,9 @@ EXPORTS wglGetExtensionsStringARB ; ; Mesa internals - mostly for OSMESA - _ac_CreateContext - _ac_DestroyContext - _ac_InvalidateState + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState _glapi_check_multithread _glapi_get_context _glapi_get_proc_address diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 8c3229ab14c..078b590af87 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -11,7 +11,7 @@ #include "framebuffer.h" #include "renderbuffer.h" #include "drivers/common/driverfuncs.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -1125,7 +1125,7 @@ static void wmesa_update_state(GLcontext *ctx, GLuint new_state) { _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); /* TODO - This code is not complete yet because I @@ -1242,7 +1242,7 @@ WMesaContext WMesaCreateContext(HDC hDC, /* Initialize the software rasterizer and helper modules. */ if (!_swrast_CreateContext(ctx) || - !_ac_CreateContext(ctx) || + !_vbo_CreateContext(ctx) || !_tnl_CreateContext(ctx) || !_swsetup_CreateContext(ctx)) { _mesa_free_context_data(ctx); @@ -1285,7 +1285,7 @@ void WMesaDestroyContext( WMesaContext pwc ) _swsetup_DestroyContext(ctx); _tnl_DestroyContext(ctx); - _ac_DestroyContext(ctx); + _vbo_DestroyContext(ctx); _swrast_DestroyContext(ctx); _mesa_free_context_data(ctx); diff --git a/src/mesa/drivers/windows/gldirect/dglcontext.c b/src/mesa/drivers/windows/gldirect/dglcontext.c index 5dafe14518d..4ad7a76e67f 100644 --- a/src/mesa/drivers/windows/gldirect/dglcontext.c +++ b/src/mesa/drivers/windows/gldirect/dglcontext.c @@ -1453,7 +1453,7 @@ SkipPrimaryCreate: #ifdef _USE_GLD3_WGL // Init Mesa internals _swrast_CreateContext( lpCtx->glCtx ); - _ac_CreateContext( lpCtx->glCtx ); + _vbo_CreateContext( lpCtx->glCtx ); _tnl_CreateContext( lpCtx->glCtx ); _swsetup_CreateContext( lpCtx->glCtx ); diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c index cad299540d7..d5fa6428006 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -868,7 +868,7 @@ void gld_update_state_DX7( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c index 6be41a80dd3..ba60980bbe8 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_ext_dx7.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c index 5da25003c08..c99ba0bba55 100644 --- a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c +++ b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c index 0a6d9f8555c..7afa9190cdf 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -850,7 +850,7 @@ void gld_update_state_DX8( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c index 108f12a9d16..b51bba9b3ca 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_ext_dx8.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c index 700b5200862..a5b5462f039 100644 --- a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c +++ b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c index 1b01cb1f7f3..c191564d6eb 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c @@ -52,7 +52,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" @@ -876,7 +876,7 @@ void gld_update_state_DX9( return; _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c index 745c987602b..e8c73a6ff80 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_ext_dx9.c @@ -58,7 +58,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c index 65fd821276e..403a9d5f86e 100644 --- a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c +++ b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c @@ -54,7 +54,7 @@ #include "mtypes.h" #include "texformat.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast_setup/ss_context.h" diff --git a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c index 0f11b4fe513..b590dc795a0 100644 --- a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c +++ b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c @@ -54,7 +54,7 @@ #include "texformat.h" #include "texstore.h" #include "teximage.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" @@ -1321,7 +1321,7 @@ static void wmesa_update_state( { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -1631,7 +1631,7 @@ BOOL gldInitialiseMesa_MesaSW( _mesa_enable_1_3_extensions(ctx); // _swrast_CreateContext( ctx ); -// _ac_CreateContext( ctx ); +// _vbo_CreateContext( ctx ); // _tnl_CreateContext( ctx ); // _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/windows/icd/mesa.def b/src/mesa/drivers/windows/icd/mesa.def index 1826192d307..465b380a0cb 100644 --- a/src/mesa/drivers/windows/icd/mesa.def +++ b/src/mesa/drivers/windows/icd/mesa.def @@ -24,9 +24,9 @@ EXPORTS ; ; Mesa internals - mostly for OSMESA - _ac_CreateContext - _ac_DestroyContext - _ac_InvalidateState + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState _glapi_get_context _glapi_get_proc_address _mesa_buffer_data diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c index 7945f1c5b06..973f3940451 100644 --- a/src/mesa/drivers/x11/glxapi.c +++ b/src/mesa/drivers/x11/glxapi.c @@ -241,7 +241,7 @@ glXGetCurrentContext(void) #if defined(GLX_USE_TLS) return CurrentContext; #elif defined(THREADS) - return _glthread_GetTSD(&ContextTSD); + return (GLXContext) _glthread_GetTSD(&ContextTSD); #else return CurrentContext; #endif diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index b50c4757afc..b0ef422de2e 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -74,7 +74,7 @@ #include "renderbuffer.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1545,6 +1545,13 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query"); #endif +#ifdef XFree86Server + /* If we're running in the X server, do bounds checking to prevent + * segfaults and server crashes! + */ + mesaCtx->Const.CheckArrayBounds = GL_TRUE; +#endif + /* finish up xmesa context initializations */ c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE; c->xm_visual = v; @@ -1555,7 +1562,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) /* Initialize the software rasterizer and helper modules. */ if (!_swrast_CreateContext( mesaCtx ) || - !_ac_CreateContext( mesaCtx ) || + !_vbo_CreateContext( mesaCtx ) || !_tnl_CreateContext( mesaCtx ) || !_swsetup_CreateContext( mesaCtx )) { _mesa_free_context_data(&c->mesa); @@ -1587,7 +1594,7 @@ void XMesaDestroyContext( XMesaContext c ) _swsetup_DestroyContext( mesaCtx ); _swrast_DestroyContext( mesaCtx ); _tnl_DestroyContext( mesaCtx ); - _ac_DestroyContext( mesaCtx ); + _vbo_DestroyContext( mesaCtx ); _mesa_free_context_data( mesaCtx ); _mesa_free( c ); } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index d272630d18a..dbac3b8cdb6 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -47,7 +47,6 @@ #include "texstore.h" #include "texformat.h" #include "xmesaP.h" -#include "array_cache/acache.h" #include "swrast/swrast.h" #include "swrast/s_context.h" #include "swrast_setup/swrast_setup.h" @@ -829,8 +828,8 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) * modules. The X11 driver has no internal GL-dependent state. */ _swrast_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); if (ctx->DrawBuffer->Name != 0) |