Merge branch 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / src / mesa / main / context.c
index 415e339cb8050721f1b994d0e1bf1d3673f6243f..87eae9663923920ff246ea67c8ce513f34a24dc5 100644 (file)
 #include "glheader.h"
 #include "mfeatures.h"
 #include "imports.h"
-#if FEATURE_accum
 #include "accum.h"
-#endif
 #include "api_exec.h"
 #include "arrayobj.h"
-#if FEATURE_attrib_stack
 #include "attrib.h"
-#endif
 #include "blend.h"
 #include "buffers.h"
 #include "bufferobj.h"
-#if FEATURE_colortable
 #include "colortab.h"
-#endif
 #include "context.h"
 #include "cpuinfo.h"
 #include "debug.h"
 #include "depth.h"
-#if FEATURE_dlist
 #include "dlist.h"
-#endif
-#if FEATURE_evaluators
 #include "eval.h"
-#endif
 #include "enums.h"
 #include "extensions.h"
 #include "fbobject.h"
-#if FEATURE_feedback
 #include "feedback.h"
-#endif
 #include "fog.h"
 #include "framebuffer.h"
 #include "get.h"
-#if FEATURE_histogram
 #include "histogram.h"
-#endif
 #include "hint.h"
 #include "hash.h"
 #include "light.h"
 #include "pixelstore.h"
 #include "points.h"
 #include "polygon.h"
-#if FEATURE_ARB_occlusion_query
 #include "queryobj.h"
+#if FEATURE_ARB_sync
+#include "syncobj.h"
 #endif
-#if FEATURE_drawpix
 #include "rastpos.h"
-#endif
+#include "remap.h"
 #include "scissor.h"
 #include "shared.h"
 #include "simple_list.h"
 #include "state.h"
 #include "stencil.h"
-#include "texcompress.h"
+#include "texcompress_s3tc.h"
 #include "teximage.h"
 #include "texobj.h"
 #include "texstate.h"
 #include "viewport.h"
 #include "vtxfmt.h"
 #include "glapi/glthread.h"
-#include "glapi/glapioffsets.h"
 #include "glapi/glapitable.h"
 #include "shader/program.h"
+#include "shader/prog_print.h"
 #include "shader/shader_api.h"
 #if FEATURE_ATI_fragment_shader
 #include "shader/atifragshader.h"
@@ -187,6 +173,8 @@ GLfloat _mesa_ubyte_to_float_color_tab[256];
 void
 _mesa_notifySwapBuffers(__GLcontext *ctx)
 {
+   if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
+      _mesa_debug(ctx, "SwapBuffers\n");
    FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Flush) {
       ctx->Driver.Flush(ctx);
@@ -419,6 +407,8 @@ one_time_init( GLcontext *ctx )
 
       _mesa_get_cpu_features();
 
+      _mesa_init_remap_table();
+
       _mesa_init_sqrt_table();
 
       for (i = 0; i < 256; i++) {
@@ -486,7 +476,7 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
    prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
 
    if (type == GL_VERTEX_PROGRAM_ARB) {
-      prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+      prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
       prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
    }
@@ -496,15 +486,17 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
       prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
    }
 
-   /* copy the above limits to init native limits */
-   prog->MaxNativeInstructions = prog->MaxInstructions;
-   prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
-   prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
-   prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
-   prog->MaxNativeAttribs = prog->MaxAttribs;
-   prog->MaxNativeTemps = prog->MaxTemps;
-   prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
-   prog->MaxNativeParameters = prog->MaxParameters;
+   /* Set the native limits to zero.  This implies that there is no native
+    * support for shaders.  Let the drivers fill in the actual values.
+    */
+   prog->MaxNativeInstructions = 0;
+   prog->MaxNativeAluInstructions = 0;
+   prog->MaxNativeTexInstructions = 0;
+   prog->MaxNativeTexIndirections = 0;
+   prog->MaxNativeAttribs = 0;
+   prog->MaxNativeTemps = 0;
+   prog->MaxNativeAddressRegs = 0;
+   prog->MaxNativeParameters = 0;
 }
 
 
@@ -572,10 +564,6 @@ _mesa_init_constants(GLcontext *ctx)
    /* GL_ARB_draw_buffers */
    ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
 
-   /* GL_OES_read_format */
-   ctx->Const.ColorReadFormat = GL_RGBA;
-   ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
-
 #if FEATURE_EXT_framebuffer_object
    ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
    ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
@@ -589,6 +577,9 @@ _mesa_init_constants(GLcontext *ctx)
    /* GL_ARB_framebuffer_object */
    ctx->Const.MaxSamples = 0;
 
+   /* GL_ARB_sync */
+   ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0;
+
    /* GL_ATI_envmap_bumpmap */
    ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
 
@@ -606,9 +597,11 @@ _mesa_init_constants(GLcontext *ctx)
    ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
    ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
 
-   /* check that we don't exceed various 32-bit bitfields */
-   ASSERT(VERT_RESULT_MAX <= 32);
-   ASSERT(FRAG_ATTRIB_MAX <= 32);
+   /* check that we don't exceed the size of various bitfields */
+   ASSERT(VERT_RESULT_MAX <=
+         (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
+   ASSERT(FRAG_ATTRIB_MAX <=
+         (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
 }
 
 
@@ -669,36 +662,20 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_extensions( ctx );
 
    /* Attribute Groups */
-#if FEATURE_accum
    _mesa_init_accum( ctx );
-#endif
-#if FEATURE_attrib_stack
    _mesa_init_attrib( ctx );
-#endif
    _mesa_init_buffer_objects( ctx );
    _mesa_init_color( ctx );
-#if FEATURE_colortable
    _mesa_init_colortables( ctx );
-#endif
    _mesa_init_current( ctx );
    _mesa_init_depth( ctx );
    _mesa_init_debug( ctx );
-#if FEATURE_dlist
    _mesa_init_display_list( ctx );
-#endif
-#if FEATURE_evaluators
    _mesa_init_eval( ctx );
-#endif
    _mesa_init_fbobjects( ctx );
-#if FEATURE_feedback
    _mesa_init_feedback( ctx );
-#else
-   ctx->RenderMode = GL_RENDER;
-#endif
    _mesa_init_fog( ctx );
-#if FEATURE_histogram
    _mesa_init_histogram( ctx );
-#endif
    _mesa_init_hint( ctx );
    _mesa_init_line( ctx );
    _mesa_init_lighting( ctx );
@@ -709,12 +686,11 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_point( ctx );
    _mesa_init_polygon( ctx );
    _mesa_init_program( ctx );
-#if FEATURE_ARB_occlusion_query
-   _mesa_init_query( ctx );
+   _mesa_init_queryobj( ctx );
+#if FEATURE_ARB_sync
+   _mesa_init_sync( ctx );
 #endif
-#if FEATURE_drawpix
    _mesa_init_rastpos( ctx );
-#endif
    _mesa_init_scissor( ctx );
    _mesa_init_shader_state( ctx );
    _mesa_init_stencil( ctx );
@@ -725,12 +701,7 @@ init_attrib_groups(GLcontext *ctx)
    if (!_mesa_init_texture( ctx ))
       return GL_FALSE;
 
-#if FEATURE_texture_s3tc
    _mesa_init_texture_s3tc( ctx );
-#endif
-#if FEATURE_texture_fxt1
-   _mesa_init_texture_fxt1( ctx );
-#endif
 
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
@@ -886,15 +857,18 @@ _mesa_initialize_context(GLcontext *ctx,
       _mesa_free_shared_state(ctx, ctx->Shared);
       if (ctx->Exec)
          _mesa_free(ctx->Exec);
+      return GL_FALSE;
    }
 #if FEATURE_dispatch
    _mesa_init_exec_table(ctx->Exec);
 #endif
    ctx->CurrentDispatch = ctx->Exec;
+
 #if FEATURE_dlist
-   _mesa_init_dlist_table(ctx->Save);
+   _mesa_init_save_table(ctx->Save);
    _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
 #endif
+
    /* Neutral tnl module stuff */
    _mesa_init_exec_vtxfmt( ctx ); 
    ctx->TnlModule.Current = NULL;
@@ -993,23 +967,18 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
 
-#if FEATURE_attrib_stack
    _mesa_free_attrib_data(ctx);
-#endif
    _mesa_free_lighting_data( ctx );
-#if FEATURE_evaluators
    _mesa_free_eval_data( ctx );
-#endif
    _mesa_free_texture_data( ctx );
    _mesa_free_matrix_data( ctx );
    _mesa_free_viewport_data( ctx );
-#if FEATURE_colortable
    _mesa_free_colortables_data( ctx );
-#endif
    _mesa_free_program_data(ctx);
    _mesa_free_shader_state(ctx);
-#if FEATURE_ARB_occlusion_query
-   _mesa_free_query_data(ctx);
+   _mesa_free_queryobj_data(ctx);
+#if FEATURE_ARB_sync
+   _mesa_free_sync_data(ctx);
 #endif
    _mesa_free_varray_data(ctx);
 
@@ -1039,6 +1008,9 @@ _mesa_free_context_data( GLcontext *ctx )
       _mesa_free_shared_state( ctx, ctx->Shared );
    }
 
+   /* needs to be after freeing shared state */
+   _mesa_free_display_list_data(ctx);
+
    if (ctx->Extensions.String)
       _mesa_free((void *) ctx->Extensions.String);
 
@@ -1527,6 +1499,33 @@ _mesa_record_error(GLcontext *ctx, GLenum error)
 }
 
 
+/**
+ * Flush commands and wait for completion.
+ */
+void
+_mesa_finish(GLcontext *ctx)
+{
+   FLUSH_CURRENT( ctx, 0 );
+   if (ctx->Driver.Finish) {
+      ctx->Driver.Finish(ctx);
+   }
+}
+
+
+/**
+ * Flush commands.
+ */
+void
+_mesa_flush(GLcontext *ctx)
+{
+   FLUSH_CURRENT( ctx, 0 );
+   if (ctx->Driver.Flush) {
+      ctx->Driver.Flush(ctx);
+   }
+}
+
+
+
 /**
  * Execute glFinish().
  *
@@ -1538,10 +1537,7 @@ _mesa_Finish(void)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   FLUSH_CURRENT( ctx, 0 );
-   if (ctx->Driver.Finish) {
-      ctx->Driver.Finish(ctx);
-   }
+   _mesa_finish(ctx);
 }
 
 
@@ -1556,10 +1552,7 @@ _mesa_Flush(void)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   FLUSH_CURRENT( ctx, 0 );
-   if (ctx->Driver.Flush) {
-      ctx->Driver.Flush(ctx);
-   }
+   _mesa_flush(ctx);
 }
 
 
@@ -1576,4 +1569,82 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
 }
 
 
+
+/**
+ * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
+ * is called to see if it's valid to render.  This involves checking that
+ * the current shader is valid and the framebuffer is complete.
+ * If an error is detected it'll be recorded here.
+ * \return GL_TRUE if OK to render, GL_FALSE if not
+ */
+GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where)
+{
+   if (ctx->Shader.CurrentProgram) {
+      /* using shaders */
+      if (!ctx->Shader.CurrentProgram->LinkStatus) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s(shader not linked), where");
+         return GL_FALSE;
+      }
+#if 0 /* not normally enabled */
+      {
+         char errMsg[100];
+         if (!_mesa_validate_shader_program(ctx, ctx->Shader.CurrentProgram,
+                                            errMsg)) {
+            _mesa_warning(ctx, "Shader program %u is invalid: %s",
+                          ctx->Shader.CurrentProgram->Name, errMsg);
+         }
+      }
+#endif
+   }
+   else {
+      if (ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s(vertex program not valid)", where);
+         return GL_FALSE;
+      }
+      if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "%s(fragment program not valid)", where);
+         return GL_FALSE;
+      }
+   }
+
+   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+                  "%s(incomplete framebuffer)", where);
+      return GL_FALSE;
+   }
+
+#ifdef DEBUG
+   if (ctx->Shader.Flags & GLSL_LOG) {
+      struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+      if (shProg) {
+         if (!shProg->_Used) {
+            /* This is the first time this shader is being used.
+             * Append shader's constants/uniforms to log file.
+             */
+            GLuint i;
+            for (i = 0; i < shProg->NumShaders; i++) {
+               struct gl_shader *sh = shProg->Shaders[i];
+               if (sh->Type == GL_VERTEX_SHADER) {
+                  _mesa_append_uniforms_to_file(sh,
+                                                &shProg->VertexProgram->Base);
+               }
+               else if (sh->Type == GL_FRAGMENT_SHADER) {
+                  _mesa_append_uniforms_to_file(sh,
+                                                &shProg->FragmentProgram->Base);
+               }
+            }
+            shProg->_Used = GL_TRUE;
+         }
+      }
+   }
+#endif
+
+   return GL_TRUE;
+}
+
+
 /*@}*/