summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/common/meta.c1249
-rw-r--r--src/mesa/drivers/common/meta.h80
-rw-r--r--src/mesa/drivers/dri/common/.gitignore1
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.c7
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c2
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h74
-rw-r--r--src/mesa/drivers/dri/fb/fb_egl.c4
-rw-r--r--src/mesa/drivers/dri/i915/i830_context.h8
-rw-r--r--src/mesa/drivers/dri/i915/i830_reg.h3
-rw-r--r--src/mesa/drivers/dri/i915/i830_state.c32
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c27
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h7
-rw-r--r--src/mesa/drivers/dri/i915/i915_reg.h2
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c35
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c19
-rw-r--r--src/mesa/drivers/dri/i965/Makefile1
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h19
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_disasm.c903
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c55
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c141
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_emit.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c21
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h15
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c13
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c73
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c48
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c112
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c154
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_iz.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c33
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c10
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c31
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h9
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c71
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_copy.c167
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c21
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c65
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c42
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c12
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c10
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c19
-rw-r--r--src/mesa/drivers/dri/r300/r300_draw.c8
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.c3
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c2
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.h11
-rw-r--r--src/mesa/drivers/dri/r600/r600_texstate.c12
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c3
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c64
-rw-r--r--src/mesa/drivers/dri/r600/r700_clear.c1
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.c105
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c2
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c27
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.c126
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.h4
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.c20
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_drm.h16
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c63
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h7
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c28
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c30
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.c53
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.h12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c7
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c25
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c124
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c37
-rw-r--r--src/mesa/glapi/EXT_framebuffer_object.xml38
-rw-r--r--src/mesa/glapi/EXT_texture_array.xml41
-rw-r--r--src/mesa/glapi/gl_API.xml59
-rw-r--r--src/mesa/main/api_arrayelt.c3
-rw-r--r--src/mesa/main/api_exec.c1
-rw-r--r--src/mesa/main/api_validate.c21
-rw-r--r--src/mesa/main/attrib.c146
-rw-r--r--src/mesa/main/bufferobj.c64
-rw-r--r--src/mesa/main/bufferobj.h20
-rw-r--r--src/mesa/main/colortab.c8
-rw-r--r--src/mesa/main/config.h9
-rw-r--r--src/mesa/main/context.c69
-rw-r--r--src/mesa/main/context.h6
-rw-r--r--src/mesa/main/convolve.c20
-rw-r--r--src/mesa/main/debug.c97
-rw-r--r--src/mesa/main/dlist.c304
-rw-r--r--src/mesa/main/drawpix.c142
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/fbobject.c20
-rw-r--r--src/mesa/main/fog.c2
-rw-r--r--src/mesa/main/framebuffer.c26
-rw-r--r--src/mesa/main/getstring.c1
-rw-r--r--src/mesa/main/histogram.c8
-rw-r--r--src/mesa/main/image.c382
-rw-r--r--src/mesa/main/image.h24
-rw-r--r--src/mesa/main/imports.c85
-rw-r--r--src/mesa/main/imports.h3
-rw-r--r--src/mesa/main/light.c8
-rw-r--r--src/mesa/main/mtypes.h14
-rw-r--r--src/mesa/main/pixel.c24
-rw-r--r--src/mesa/main/polygon.c4
-rw-r--r--src/mesa/main/readpix.c55
-rw-r--r--src/mesa/main/shared.c2
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/texenv.c69
-rw-r--r--src/mesa/main/texenvprogram.c15
-rw-r--r--src/mesa/main/texgetimage.c233
-rw-r--r--src/mesa/main/texgetimage.h9
-rw-r--r--src/mesa/main/teximage.c525
-rw-r--r--src/mesa/main/teximage.h16
-rw-r--r--src/mesa/main/texobj.c56
-rw-r--r--src/mesa/main/texobj.h8
-rw-r--r--src/mesa/main/texparam.c58
-rw-r--r--src/mesa/main/texstate.h18
-rw-r--r--src/mesa/main/texstore.c6
-rw-r--r--src/mesa/main/varray.c41
-rw-r--r--src/mesa/main/varray.h6
-rw-r--r--src/mesa/main/viewport.c4
-rw-r--r--src/mesa/shader/arbprogparse.c7
-rw-r--r--src/mesa/shader/prog_print.c34
-rw-r--r--src/mesa/shader/prog_print.h4
-rw-r--r--src/mesa/shader/programopt.c1
-rw-r--r--src/mesa/shader/shader_api.c12
-rw-r--r--src/mesa/shader/slang/slang_builtin.c183
-rw-r--r--src/mesa/shader/slang/slang_builtin.h14
-rw-r--r--src/mesa/shader/slang/slang_codegen.c104
-rw-r--r--src/mesa/shader/slang/slang_link.c34
-rw-r--r--src/mesa/sources.mak3
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c17
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c97
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c2
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c6
-rw-r--r--src/mesa/state_tracker/st_draw.c5
-rw-r--r--src/mesa/state_tracker/st_draw.h2
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c4
-rw-r--r--src/mesa/state_tracker/st_extensions.c4
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c21
-rw-r--r--src/mesa/state_tracker/st_program.c42
-rw-r--r--src/mesa/state_tracker/st_public.h4
-rw-r--r--src/mesa/state_tracker/st_texture.c108
-rw-r--r--src/mesa/state_tracker/st_texture.h5
-rw-r--r--src/mesa/swrast/s_blit.c189
-rw-r--r--src/mesa/swrast/s_fragprog.c5
-rw-r--r--src/mesa/swrast/s_points.c28
-rw-r--r--src/mesa/tnl/t_context.c2
-rw-r--r--src/mesa/tnl/t_draw.c18
-rw-r--r--src/mesa/tnl/t_vb_program.c3
-rw-r--r--src/mesa/tnl/tnl.h10
-rw-r--r--src/mesa/vbo/vbo.h6
-rw-r--r--src/mesa/vbo/vbo_exec_api.c21
-rw-r--r--src/mesa/vbo/vbo_exec_array.c172
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c13
-rw-r--r--src/mesa/vbo/vbo_rebase.c1
-rw-r--r--src/mesa/vbo/vbo_save_api.c2
-rw-r--r--src/mesa/vbo/vbo_save_draw.c1
-rw-r--r--src/mesa/vbo/vbo_split_copy.c12
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c1
171 files changed, 5871 insertions, 2580 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
new file mode 100644
index 0000000000..e42beabc9b
--- /dev/null
+++ b/src/mesa/drivers/common/meta.c
@@ -0,0 +1,1249 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 2009 VMware, Inc. 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.
+ */
+
+/**
+ * Meta operations. Some GL operations can be expressed in terms of
+ * other GL operations. For example, glBlitFramebuffer() can be done
+ * with texture mapping and glClear() can be done with polygon rendering.
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "main/arrayobj.h"
+#include "main/blend.h"
+#include "main/bufferobj.h"
+#include "main/depth.h"
+#include "main/enable.h"
+#include "main/image.h"
+#include "main/macros.h"
+#include "main/matrix.h"
+#include "main/polygon.h"
+#include "main/scissor.h"
+#include "main/shaders.h"
+#include "main/stencil.h"
+#include "main/texobj.h"
+#include "main/texenv.h"
+#include "main/teximage.h"
+#include "main/texparam.h"
+#include "main/texstate.h"
+#include "main/varray.h"
+#include "main/viewport.h"
+#include "shader/program.h"
+#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
+
+
+/**
+ * State which we may save/restore across meta ops.
+ * XXX this may be incomplete...
+ */
+struct save_state
+{
+ GLbitfield SavedState; /**< bitmask of META_* flags */
+
+ /** META_ALPHA_TEST */
+ GLboolean AlphaEnabled;
+
+ /** META_BLEND */
+ GLboolean BlendEnabled;
+ GLboolean ColorLogicOpEnabled;
+
+ /** META_COLOR_MASK */
+ GLubyte ColorMask[4];
+
+ /** META_DEPTH_TEST */
+ struct gl_depthbuffer_attrib Depth;
+
+ /** META_FOG */
+ GLboolean Fog;
+
+ /** META_PIXELSTORE */
+ /* XXX / TO-DO */
+
+ /** META_RASTERIZATION */
+ GLenum FrontPolygonMode, BackPolygonMode;
+ GLboolean PolygonOffset;
+ GLboolean PolygonSmooth;
+ GLboolean PolygonStipple;
+ GLboolean PolygonCull;
+
+ /** META_SCISSOR */
+ struct gl_scissor_attrib Scissor;
+
+ /** META_SHADER */
+ GLboolean VertexProgramEnabled;
+ struct gl_vertex_program *VertexProgram;
+ GLboolean FragmentProgramEnabled;
+ struct gl_fragment_program *FragmentProgram;
+ GLuint Shader;
+
+ /** META_STENCIL_TEST */
+ struct gl_stencil_attrib Stencil;
+
+ /** META_TRANSFORM */
+ GLenum MatrixMode;
+ GLfloat ModelviewMatrix[16];
+ GLfloat ProjectionMatrix[16];
+ GLfloat TextureMatrix[16];
+ GLbitfield ClipPlanesEnabled;
+
+ /** META_TEXTURE */
+ GLuint ActiveUnit;
+ GLuint ClientActiveUnit;
+ /** for unit[0] only */
+ struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
+ /** mask of TEXTURE_2D_BIT, etc */
+ GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
+ GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
+ GLuint EnvMode; /* unit[0] only */
+
+ /** META_VERTEX */
+ struct gl_array_object *ArrayObj;
+ struct gl_buffer_object *ArrayBufferObj;
+
+ /** META_VIEWPORT */
+ GLint ViewportX, ViewportY, ViewportW, ViewportH;
+ GLclampd DepthNear, DepthFar;
+
+ /** Miscellaneous (always disabled) */
+ GLboolean Lighting;
+};
+
+
+/**
+ * State for glBlitFramebufer()
+ */
+struct blit_state
+{
+ GLuint TexObj;
+ GLsizei TexWidth, TexHeight;
+ GLenum TexType;
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLfloat verts[4][4]; /** four verts of X,Y,S,T */
+};
+
+
+/**
+ * State for glClear()
+ */
+struct clear_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLfloat verts[4][7]; /** four verts of X,Y,Z,R,G,B,A */
+};
+
+
+/**
+ * State for glCopyPixels()
+ */
+struct copypix_state
+{
+ GLuint TexObj;
+ GLsizei TexWidth, TexHeight;
+ GLenum TexType;
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLfloat verts[4][5]; /** four verts of X,Y,Z,S,T */
+};
+
+
+/**
+ * State for glDrawPixels()
+ */
+struct drawpix_state
+{
+ GLuint TexObj;
+ GLsizei TexWidth, TexHeight;
+ GLenum TexIntFormat;
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLfloat verts[4][5]; /** four verts of X,Y,Z,S,T */
+};
+
+
+
+/**
+ * All per-context meta state.
+ */
+struct gl_meta_state
+{
+ struct save_state Save; /**< state saved during meta-ops */
+
+ struct blit_state Blit; /**< For _mesa_meta_blit_framebuffer() */
+ struct clear_state Clear; /**< For _mesa_meta_clear() */
+ struct copypix_state CopyPix; /**< For _mesa_meta_copy_pixels() */
+ struct drawpix_state DrawPix; /**< For _mesa_meta_draw_pixels() */
+
+ /* other possible meta-ops:
+ * glDrawPixels()
+ * glBitmap()
+ * glGenerateMipmap()
+ */
+};
+
+
+/**
+ * Initialize meta-ops for a context.
+ * To be called once during context creation.
+ */
+void
+_mesa_meta_init(GLcontext *ctx)
+{
+ ASSERT(!ctx->Meta);
+
+ ctx->Meta = CALLOC_STRUCT(gl_meta_state);
+}
+
+
+/**
+ * Free context meta-op state.
+ * To be called once during context destruction.
+ */
+void
+_mesa_meta_free(GLcontext *ctx)
+{
+ struct gl_meta_state *meta = ctx->Meta;
+
+ if (meta->Blit.TexObj) {
+ _mesa_DeleteTextures(1, &meta->Blit.TexObj);
+ _mesa_DeleteBuffersARB(1, & meta->Blit.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj);
+ }
+
+ if (meta->Clear.VBO) {
+ _mesa_DeleteBuffersARB(1, & meta->Clear.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj);
+ }
+
+ if (meta->CopyPix.TexObj) {
+ _mesa_DeleteTextures(1, &meta->CopyPix.TexObj);
+ _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
+ }
+
+ if (meta->DrawPix.TexObj) {
+ _mesa_DeleteTextures(1, &meta->DrawPix.TexObj);
+ _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
+ }
+
+ _mesa_free(ctx->Meta);
+ ctx->Meta = NULL;
+}
+
+
+/**
+ * Enter meta state. This is like a light-weight version of glPushAttrib
+ * but it also resets most GL state back to default values.
+ *
+ * \param state bitmask of META_* flags indicating which attribute groups
+ * to save and reset to their defaults
+ */
+static void
+_mesa_meta_begin(GLcontext *ctx, GLbitfield state)
+{
+ struct save_state *save = &ctx->Meta->Save;
+
+ save->SavedState = state;
+
+ if (state & META_ALPHA_TEST) {
+ save->AlphaEnabled = ctx->Color.AlphaEnabled;
+ if (ctx->Color.AlphaEnabled)
+ _mesa_Disable(GL_ALPHA_TEST);
+ }
+
+ if (state & META_BLEND) {
+ save->BlendEnabled = ctx->Color.BlendEnabled;
+ if (ctx->Color.BlendEnabled)
+ _mesa_Disable(GL_BLEND);
+ save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
+ if (ctx->Color.ColorLogicOpEnabled)
+ _mesa_Disable(GL_COLOR_LOGIC_OP);
+ }
+
+ if (state & META_COLOR_MASK) {
+ COPY_4V(save->ColorMask, ctx->Color.ColorMask);
+ if (!ctx->Color.ColorMask[0] ||
+ !ctx->Color.ColorMask[1] ||
+ !ctx->Color.ColorMask[2] ||
+ !ctx->Color.ColorMask[3])
+ _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
+
+ if (state & META_DEPTH_TEST) {
+ save->Depth = ctx->Depth; /* struct copy */
+ if (ctx->Depth.Test)
+ _mesa_Disable(GL_DEPTH_TEST);
+ }
+
+ if (state & META_FOG) {
+ save->Fog = ctx->Fog.Enabled;
+ if (ctx->Fog.Enabled)
+ _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
+ }
+
+ if (state & META_RASTERIZATION) {
+ save->FrontPolygonMode = ctx->Polygon.FrontMode;
+ save->BackPolygonMode = ctx->Polygon.BackMode;
+ save->PolygonOffset = ctx->Polygon.OffsetFill;
+ save->PolygonSmooth = ctx->Polygon.SmoothFlag;
+ save->PolygonStipple = ctx->Polygon.StippleFlag;
+ save->PolygonCull = ctx->Polygon.CullFlag;
+ _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
+ _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
+ _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
+ _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
+ }
+
+ if (state & META_SCISSOR) {
+ save->Scissor = ctx->Scissor; /* struct copy */
+ }
+
+ if (state & META_SHADER) {
+ if (ctx->Extensions.ARB_vertex_program) {
+ save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
+ save->VertexProgram = ctx->VertexProgram.Current;
+ _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
+ }
+
+ if (ctx->Extensions.ARB_fragment_program) {
+ save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
+ save->FragmentProgram = ctx->FragmentProgram.Current;
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
+ }
+
+ if (ctx->Extensions.ARB_shader_objects) {
+ save->Shader = ctx->Shader.CurrentProgram ?
+ ctx->Shader.CurrentProgram->Name : 0;
+ _mesa_UseProgramObjectARB(0);
+ }
+ }
+
+ if (state & META_STENCIL_TEST) {
+ save->Stencil = ctx->Stencil; /* struct copy */
+ if (ctx->Stencil.Enabled)
+ _mesa_Disable(GL_STENCIL_TEST);
+ /* NOTE: other stencil state not reset */
+ }
+
+ if (state & META_TEXTURE) {
+ GLuint u, tgt;
+
+ save->ActiveUnit = ctx->Texture.CurrentUnit;
+ save->ClientActiveUnit = ctx->Array.ActiveTexture;
+ save->EnvMode = ctx->Texture.Unit[0].EnvMode;
+
+ /* Disable all texture units */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
+ save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
+ if (ctx->Texture.Unit[u].Enabled ||
+ ctx->Texture.Unit[u].TexGenEnabled) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+ _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
+ }
+ }
+
+ /* save current texture objects for unit[0] only */
+ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
+ _mesa_reference_texobj(&save->CurrentTexture[tgt],
+ ctx->Texture.Unit[0].CurrentTex[tgt]);
+ }
+
+ /* set defaults for unit[0] */
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ }
+
+ if (state & META_TRANSFORM) {
+ GLuint activeTexture = ctx->Texture.CurrentUnit;
+ _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
+ 16 * sizeof(GLfloat));
+ _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
+ 16 * sizeof(GLfloat));
+ _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
+ 16 * sizeof(GLfloat));
+ save->MatrixMode = ctx->Transform.MatrixMode;
+ /* set 1:1 vertex:pixel coordinate transform */
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_MatrixMode(GL_TEXTURE);
+ _mesa_LoadIdentity();
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_LoadIdentity();
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_LoadIdentity();
+ _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
+ 0.0F, ctx->DrawBuffer->Height,
+ -1.0F, 1.0F);
+ save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
+ if (ctx->Transform.ClipPlanesEnabled) {
+ GLuint i;
+ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
+ }
+ }
+ }
+
+ if (state & META_VERTEX) {
+ /* save vertex array object state */
+ _mesa_reference_array_object(ctx, &save->ArrayObj,
+ ctx->Array.ArrayObj);
+ _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
+ ctx->Array.ArrayBufferObj);
+ /* set some default state? */
+ }
+
+ if (state & META_VIEWPORT) {
+ save->ViewportX = ctx->Viewport.X;
+ save->ViewportY = ctx->Viewport.Y;
+ save->ViewportW = ctx->Viewport.Width;
+ save->ViewportH = ctx->Viewport.Height;
+ _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
+ save->DepthNear = ctx->Viewport.Near;
+ save->DepthFar = ctx->Viewport.Far;
+ _mesa_DepthRange(0.0, 1.0);
+ }
+
+ /* misc */
+ {
+ save->Lighting = ctx->Light.Enabled;
+ if (ctx->Light.Enabled)
+ _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
+ }
+}
+
+
+/**
+ * Leave meta state. This is like a light-weight version of glPopAttrib().
+ */
+static void
+_mesa_meta_end(GLcontext *ctx)
+{
+ struct save_state *save = &ctx->Meta->Save;
+ const GLbitfield state = save->SavedState;
+
+ if (state & META_ALPHA_TEST) {
+ if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
+ _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
+ }
+
+ if (state & META_BLEND) {
+ if (ctx->Color.BlendEnabled != save->BlendEnabled)
+ _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
+ if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
+ _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
+ }
+
+ if (state & META_COLOR_MASK) {
+ if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
+ _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
+ save->ColorMask[2], save->ColorMask[3]);
+ }
+
+ if (state & META_DEPTH_TEST) {
+ if (ctx->Depth.Test != save->Depth.Test)
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
+ _mesa_DepthFunc(save->Depth.Func);
+ _mesa_DepthMask(save->Depth.Mask);
+ }
+
+ if (state & META_FOG) {
+ _mesa_set_enable(ctx, GL_FOG, save->Fog);
+ }
+
+ if (state & META_RASTERIZATION) {
+ _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
+ _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
+ _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
+ _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
+ _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
+ }
+
+ if (state & META_SCISSOR) {
+ _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
+ _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
+ save->Scissor.Width, save->Scissor.Height);
+ }
+
+ if (state & META_SHADER) {
+ if (ctx->Extensions.ARB_vertex_program) {
+ _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
+ save->VertexProgramEnabled);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ save->VertexProgram);
+ }
+
+ if (ctx->Extensions.ARB_fragment_program) {
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ save->FragmentProgramEnabled);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ save->FragmentProgram);
+ }
+
+ if (ctx->Extensions.ARB_shader_objects) {
+ _mesa_UseProgramObjectARB(save->Shader);
+ }
+ }
+
+ if (state & META_STENCIL_TEST) {
+ const struct gl_stencil_attrib *stencil = &save->Stencil;
+
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
+ _mesa_ClearStencil(stencil->Clear);
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
+ stencil->TestTwoSide);
+ _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
+ ? GL_BACK : GL_FRONT);
+ }
+ /* front state */
+ _mesa_StencilFuncSeparate(GL_FRONT,
+ stencil->Function[0],
+ stencil->Ref[0],
+ stencil->ValueMask[0]);
+ _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
+ _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
+ stencil->ZFailFunc[0],
+ stencil->ZPassFunc[0]);
+ /* back state */
+ _mesa_StencilFuncSeparate(GL_BACK,
+ stencil->Function[1],
+ stencil->Ref[1],
+ stencil->ValueMask[1]);
+ _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
+ _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
+ stencil->ZFailFunc[1],
+ stencil->ZPassFunc[1]);
+ }
+
+ if (state & META_TEXTURE) {
+ GLuint u, tgt;
+
+ ASSERT(ctx->Texture.CurrentUnit == 0);
+
+ /* restore texenv for unit[0] */
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
+
+ /* restore texture objects for unit[0] only */
+ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
+ _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
+ save->CurrentTexture[tgt]);
+ }
+
+ /* Re-enable textures, texgen */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (save->TexEnabled[u]) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+
+ if (save->TexEnabled[u] & TEXTURE_1D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_2D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_3D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
+ }
+
+ if (save->TexGenEnabled[u]) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+
+ if (save->TexGenEnabled[u] & S_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
+ if (save->TexGenEnabled[u] & T_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
+ if (save->TexGenEnabled[u] & R_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
+ if (save->TexGenEnabled[u] & Q_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
+ }
+ }
+
+ /* restore current unit state */
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
+ }
+
+ if (state & META_TRANSFORM) {
+ GLuint activeTexture = ctx->Texture.CurrentUnit;
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_MatrixMode(GL_TEXTURE);
+ _mesa_LoadMatrixf(save->TextureMatrix);
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
+
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_LoadMatrixf(save->ModelviewMatrix);
+
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_LoadMatrixf(save->ProjectionMatrix);
+
+ _mesa_MatrixMode(save->MatrixMode);
+
+ save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
+ if (save->ClipPlanesEnabled) {
+ GLuint i;
+ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
+ if (save->ClipPlanesEnabled & (1 << i)) {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
+ }
+ }
+ }
+ }
+
+ if (state & META_VERTEX) {
+ /* restore vertex buffer object */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
+ _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
+
+ /* restore vertex array object */
+ _mesa_BindVertexArray(save->ArrayObj->Name);
+ _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
+ }
+
+ if (state & META_VIEWPORT) {
+ _mesa_Viewport(save->ViewportX, save->ViewportY,
+ save->ViewportW, save->ViewportH);
+ _mesa_DepthRange(save->DepthNear, save->DepthFar);
+ }
+
+ /* misc */
+ if (save->Lighting) {
+ _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
+ }
+ if (save->Fog) {
+ _mesa_set_enable(ctx, GL_FOG, GL_TRUE);
+ }
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
+ * of texture mapping and polygon rendering.
+ * Note: this function requires GL_ARB_texture_rectangle support.
+ */
+void
+_mesa_meta_blit_framebuffer(GLcontext *ctx,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ struct blit_state *blit = &ctx->Meta->Blit;
+ const GLint srcX = MIN2(srcX0, srcX1);
+ const GLint srcY = MIN2(srcY0, srcY1);
+ const GLint srcW = abs(srcX1 - srcX0);
+ const GLint srcH = abs(srcY1 - srcY0);
+ GLboolean srcFlipX = srcX1 < srcX0;
+ GLboolean srcFlipY = srcY1 < srcY0;
+
+ ASSERT(ctx->Extensions.NV_texture_rectangle);
+
+ if (srcW > ctx->Const.MaxTextureRectSize ||
+ srcH > ctx->Const.MaxTextureRectSize) {
+ /* XXX avoid this fallback */
+ _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+ return;
+ }
+
+
+ if (srcFlipX) {
+ GLint tmp = dstX0;
+ dstX0 = dstX1;
+ dstX1 = tmp;
+ }
+
+ if (srcFlipY) {
+ GLint tmp = dstY0;
+ dstY0 = dstY1;
+ dstY1 = tmp;
+ }
+
+ /* only scissor effects blit so save/clear all other relevant state */
+ _mesa_meta_begin(ctx, ~META_SCISSOR);
+
+ if (blit->TexObj == 0) {
+ /* one-time setup */
+
+ /* create texture object */
+ _mesa_GenTextures(1, &blit->TexObj);
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, blit->TexObj);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ }
+ else {
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, blit->TexObj);
+ }
+
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, filter);
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, filter);
+
+ if (blit->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &blit->ArrayObj);
+ _mesa_BindVertexArray(blit->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &blit->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(blit->verts),
+ blit->verts, GL_STREAM_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _mesa_VertexPointer(2, GL_FLOAT, 4 * sizeof(GLfloat),
+ (void*) (0 * sizeof(GLfloat)));
+ _mesa_TexCoordPointer(2, GL_FLOAT, 4 * sizeof(GLfloat),
+ (void *) (2 * sizeof(GLfloat)));
+ _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ else {
+ _mesa_BindVertexArray(blit->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+ }
+
+ /* vertex positions */
+ blit->verts[0][0] = (GLfloat) dstX0;
+ blit->verts[0][1] = (GLfloat) dstY0;
+ blit->verts[1][0] = (GLfloat) dstX1;
+ blit->verts[1][1] = (GLfloat) dstY0;
+ blit->verts[2][0] = (GLfloat) dstX1;
+ blit->verts[2][1] = (GLfloat) dstY1;
+ blit->verts[3][0] = (GLfloat) dstX0;
+ blit->verts[3][1] = (GLfloat) dstY1;
+
+ /* texcoords */
+ blit->verts[0][2] = 0.0F;
+ blit->verts[0][3] = 0.0F;
+ blit->verts[1][2] = (GLfloat) srcW;
+ blit->verts[1][3] = 0.0F;
+ blit->verts[2][2] = (GLfloat) srcW;
+ blit->verts[2][3] = (GLfloat) srcH;
+ blit->verts[3][2] = 0.0F;
+ blit->verts[3][3] = (GLfloat) srcH;
+
+ /* upload new vertex data */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0,
+ sizeof(blit->verts), blit->verts);
+
+ /* copy framebuffer image to texture */
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ if (blit->TexWidth == srcW &&
+ blit->TexHeight == srcH &&
+ blit->TexType == GL_RGBA) {
+ /* replace existing tex image */
+ _mesa_CopyTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
+ 0, 0, srcX, srcY, srcW, srcH);
+ }
+ else {
+ /* create new tex image */
+ _mesa_CopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA,
+ srcX, srcY, srcW, srcH, 0);
+ blit->TexWidth = srcW;
+ blit->TexHeight = srcH;
+ blit->TexType = GL_RGBA;
+ }
+
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ _mesa_Enable(GL_TEXTURE_RECTANGLE);
+
+ /* draw textured quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_Disable(GL_TEXTURE_RECTANGLE);
+
+ _mesa_meta_end(ctx);
+
+ /* XXX, TO-DO: try to handle these cases above! */
+ if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+ _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
+ */
+void
+_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
+{
+ struct clear_state *clear = &ctx->Meta->Clear;
+ GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
+ GLuint i;
+
+ /* only scissor and color mask effects clearing */
+ _mesa_meta_begin(ctx, ~(META_SCISSOR | META_COLOR_MASK));
+
+ if (clear->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &clear->ArrayObj);
+ _mesa_BindVertexArray(clear->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &clear->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(clear->verts),
+ clear->verts, GL_STREAM_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _mesa_VertexPointer(3, GL_FLOAT, 7 * sizeof(GLfloat), (void *) 0);
+ _mesa_ColorPointer(4, GL_FLOAT, 7 * sizeof(GLfloat),
+ (void *) (3 * sizeof(GLfloat)));
+ _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_EnableClientState(GL_COLOR_ARRAY);
+ }
+ else {
+ _mesa_BindVertexArray(clear->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
+ }
+
+ /* GL_COLOR_BUFFER_BIT */
+ if (buffers & BUFFER_BITS_COLOR) {
+ /* leave colormask, glDrawBuffer state as-is */
+ }
+ else {
+ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ }
+
+ /* GL_DEPTH_BUFFER_BIT */
+ if (buffers & BUFFER_BIT_DEPTH) {
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+ _mesa_DepthFunc(GL_ALWAYS);
+ _mesa_DepthMask(GL_TRUE);
+ }
+ else {
+ assert(!ctx->Depth.Test);
+ }
+
+ /* GL_STENCIL_BUFFER_BIT */
+ if (buffers & BUFFER_BIT_STENCIL) {
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
+ _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
+ GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
+ ctx->Stencil.Clear & 0x7fffffff,
+ ctx->Stencil.WriteMask[0]);
+ }
+ else {
+ assert(!ctx->Stencil.Enabled);
+ }
+
+ /* vertex positions */
+ clear->verts[0][0] = (GLfloat) ctx->DrawBuffer->_Xmin;
+ clear->verts[0][1] = (GLfloat) ctx->DrawBuffer->_Ymin;
+ clear->verts[0][2] = z;
+ clear->verts[1][0] = (GLfloat) ctx->DrawBuffer->_Xmax;
+ clear->verts[1][1] = (GLfloat) ctx->DrawBuffer->_Ymin;
+ clear->verts[1][2] = z;
+ clear->verts[2][0] = (GLfloat) ctx->DrawBuffer->_Xmax;
+ clear->verts[2][1] = (GLfloat) ctx->DrawBuffer->_Ymax;
+ clear->verts[2][2] = z;
+ clear->verts[3][0] = (GLfloat) ctx->DrawBuffer->_Xmin;
+ clear->verts[3][1] = (GLfloat) ctx->DrawBuffer->_Ymax;
+ clear->verts[3][2] = z;
+
+ /* vertex colors */
+ for (i = 0; i < 4; i++) {
+ COPY_4FV(&clear->verts[i][3], ctx->Color.ClearColor);
+ }
+
+ /* upload new vertex data */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0,
+ sizeof(clear->verts), clear->verts);
+
+ /* draw quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_meta_end(ctx);
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.CopyPixels() in terms
+ * of texture mapping and polygon rendering.
+ * Note: this function requires GL_ARB_texture_rectangle support.
+ */
+void
+_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height,
+ GLint dstX, GLint dstY, GLenum type)
+{
+ const GLenum filter = GL_NEAREST;
+ struct copypix_state *copypix = &ctx->Meta->CopyPix;
+ const GLfloat z = ctx->Current.RasterPos[2];
+ const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
+ const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
+
+ ASSERT(ctx->Extensions.NV_texture_rectangle);
+
+ if (type != GL_COLOR ||
+ ctx->_ImageTransferState ||
+ ctx->Fog.Enabled ||
+ width > ctx->Const.MaxTextureRectSize ||
+ height > ctx->Const.MaxTextureRectSize) {
+ /* XXX avoid this fallback */
+ _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
+ return;
+ }
+
+ /* Most GL state applies to glCopyPixels, but a there's a few things
+ * we need to override:
+ */
+ _mesa_meta_begin(ctx, (META_RASTERIZATION |
+ META_SHADER |
+ META_TEXTURE |
+ META_TRANSFORM |
+ META_VERTEX |
+ META_VIEWPORT));
+
+ if (copypix->TexObj == 0) {
+ /* one-time setup */
+
+ /* create texture object */
+ _mesa_GenTextures(1, &copypix->TexObj);
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, copypix->TexObj);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, filter);
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, filter);
+ }
+ else {
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, copypix->TexObj);
+ }
+
+ if (copypix->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &copypix->ArrayObj);
+ _mesa_BindVertexArray(copypix->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &copypix->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(copypix->verts),
+ copypix->verts, GL_STREAM_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(copypix->verts[0]),
+ (void*) (0 * sizeof(GLfloat)));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(copypix->verts[0]),
+ (void *) (3 * sizeof(GLfloat)));
+ _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ else {
+ _mesa_BindVertexArray(copypix->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
+ }
+
+ /* vertex positions, texcoords */
+ copypix->verts[0][0] = (GLfloat) dstX;
+ copypix->verts[0][1] = (GLfloat) dstY;
+ copypix->verts[0][2] = z;
+ copypix->verts[0][3] = 0.0F;
+ copypix->verts[0][4] = 0.0F;
+ copypix->verts[1][0] = (GLfloat) dstX1;
+ copypix->verts[1][1] = (GLfloat) dstY;
+ copypix->verts[1][2] = z;
+ copypix->verts[1][3] = (GLfloat) width;
+ copypix->verts[1][4] = 0.0F;
+ copypix->verts[2][0] = (GLfloat) dstX1;
+ copypix->verts[2][1] = (GLfloat) dstY1;
+ copypix->verts[2][2] = z;
+ copypix->verts[2][3] = (GLfloat) width;
+ copypix->verts[2][4] = (GLfloat) height;
+ copypix->verts[3][0] = (GLfloat) dstX;
+ copypix->verts[3][1] = (GLfloat) dstY1;
+ copypix->verts[3][2] = z;
+ copypix->verts[3][3] = 0.0F;
+ copypix->verts[3][4] = (GLfloat) height;
+
+ /* upload new vertex data */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0,
+ sizeof(copypix->verts), copypix->verts);
+
+ /* copy framebuffer image to texture */
+ if (type == GL_COLOR) {
+ if (copypix->TexWidth == width &&
+ copypix->TexHeight == height &&
+ copypix->TexType == type) {
+ /* replace existing tex image */
+ _mesa_CopyTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
+ 0, 0, srcX, srcY, width, height);
+ }
+ else {
+ /* create new tex image */
+ _mesa_CopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA,
+ srcX, srcY, width, height, 0);
+ copypix->TexWidth = width;
+ copypix->TexHeight = height;
+ copypix->TexType = type;
+ }
+ }
+ else if (type == GL_DEPTH) {
+ /* TO-DO: Use a GL_DEPTH_COMPONENT texture and a fragment program/shader
+ * that replaces the fragment.z value.
+ */
+ }
+ else {
+ ASSERT(type == GL_STENCIL);
+ /* have to use sw fallback */
+ }
+
+ _mesa_Enable(GL_TEXTURE_RECTANGLE);
+
+ /* draw textured quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_Disable(GL_TEXTURE_RECTANGLE);
+
+ _mesa_meta_end(ctx);
+}
+
+
+
+/**
+ * When the glDrawPixels() image size is greater than the max rectangle
+ * texture size we use this function to break the glDrawPixels() image
+ * into tiles which fit into the max texture size.
+ */
+static void
+tiled_draw_pixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ const GLint maxSize = ctx->Const.MaxTextureRectSize;
+ struct gl_pixelstore_attrib tileUnpack = *unpack;
+ GLint i, j;
+
+ for (i = 0; i < width; i += maxSize) {
+ const GLint tileWidth = MIN2(maxSize, width - i);
+ const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
+
+ tileUnpack.SkipPixels = unpack->SkipPixels + i;
+
+ for (j = 0; j < height; j += maxSize) {
+ const GLint tileHeight = MIN2(maxSize, height - j);
+ const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
+
+ tileUnpack.SkipRows = unpack->SkipRows + j;
+
+ _mesa_meta_draw_pixels(ctx, tileX, tileY,
+ tileWidth, tileHeight,
+ format, type, &tileUnpack, pixels);
+ }
+ }
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.DrawPixels() in terms
+ * of texture mapping and polygon rendering.
+ * Note: this function requires GL_ARB_texture_rectangle support.
+ */
+void
+_mesa_meta_draw_pixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ const GLenum filter = GL_NEAREST;
+ struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
+ const GLfloat z = ctx->Current.RasterPos[2];
+ const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
+ const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
+ const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
+ GLenum texIntFormat;
+ GLboolean fallback;
+
+ ASSERT(ctx->Extensions.NV_texture_rectangle);
+
+ /*
+ * Determine if we can do the glDrawPixels with texture mapping.
+ */
+ fallback = GL_FALSE;
+ if (ctx->_ImageTransferState ||
+ ctx->Fog.Enabled) {
+ fallback = GL_TRUE;
+ }
+
+ if (_mesa_is_color_format(format)) {
+ texIntFormat = GL_RGBA;
+ }
+ else {
+ fallback = GL_TRUE;
+ }
+
+ if (fallback) {
+ _swrast_DrawPixels(ctx, x, y, width, height,
+ format, type, unpack, pixels);
+ return;
+ }
+
+ /*
+ * Check image size against max texture size, draw as tiles if needed.
+ */
+ if (width > ctx->Const.MaxTextureRectSize ||
+ height > ctx->Const.MaxTextureRectSize) {
+ tiled_draw_pixels(ctx, x, y, width, height,
+ format, type, unpack, pixels);
+ return;
+ }
+
+ /* Most GL state applies to glDrawPixels, but a there's a few things
+ * we need to override:
+ */
+ _mesa_meta_begin(ctx, (META_RASTERIZATION |
+ META_SHADER |
+ META_TEXTURE |
+ META_TRANSFORM |
+ META_VERTEX |
+ META_VIEWPORT));
+
+ if (drawpix->TexObj == 0) {
+ /* one-time setup */
+
+ /* create texture object */
+ _mesa_GenTextures(1, &drawpix->TexObj);
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, drawpix->TexObj);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, filter);
+ _mesa_TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, filter);
+ }
+ else {
+ _mesa_BindTexture(GL_TEXTURE_RECTANGLE, drawpix->TexObj);
+ }
+
+ if (drawpix->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
+ _mesa_BindVertexArray(drawpix->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &drawpix->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(drawpix->verts),
+ drawpix->verts, GL_STREAM_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(drawpix->verts[0]),
+ (void*) (0 * sizeof(GLfloat)));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(drawpix->verts[0]),
+ (void *) (3 * sizeof(GLfloat)));
+ _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ else {
+ _mesa_BindVertexArray(drawpix->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
+ }
+
+ /* vertex positions, texcoords */
+ drawpix->verts[0][0] = (GLfloat) x;
+ drawpix->verts[0][1] = (GLfloat) y;
+ drawpix->verts[0][2] = z;
+ drawpix->verts[0][3] = 0.0F;
+ drawpix->verts[0][4] = 0.0F;
+ drawpix->verts[1][0] = (GLfloat) x1;
+ drawpix->verts[1][1] = (GLfloat) y;
+ drawpix->verts[1][2] = z;
+ drawpix->verts[1][3] = (GLfloat) width;
+ drawpix->verts[1][4] = 0.0F;
+ drawpix->verts[2][0] = (GLfloat) x1;
+ drawpix->verts[2][1] = (GLfloat) y1;
+ drawpix->verts[2][2] = z;
+ drawpix->verts[2][3] = (GLfloat) width;
+ drawpix->verts[2][4] = (GLfloat) height;
+ drawpix->verts[3][0] = (GLfloat) x;
+ drawpix->verts[3][1] = (GLfloat) y1;
+ drawpix->verts[3][2] = z;
+ drawpix->verts[3][3] = 0.0F;
+ drawpix->verts[3][4] = (GLfloat) height;
+
+ /* upload new vertex data */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0,
+ sizeof(drawpix->verts), drawpix->verts);
+
+ /* set given unpack params */
+ ctx->Unpack = *unpack; /* XXX bufobj */
+
+ /* copy pixel data to texture */
+ if (drawpix->TexWidth == width &&
+ drawpix->TexHeight == height &&
+ drawpix->TexIntFormat == texIntFormat) {
+ /* replace existing tex image */
+ _mesa_TexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
+ 0, 0, width, height, format, type, pixels);
+ }
+ else {
+ /* create new tex image */
+ _mesa_TexImage2D(GL_TEXTURE_RECTANGLE, 0, texIntFormat,
+ width, height, 0, format, type, pixels);
+ drawpix->TexWidth = width;
+ drawpix->TexHeight = height;
+ drawpix->TexIntFormat = texIntFormat;
+ }
+
+ /* restore unpack params */
+ ctx->Unpack = unpackSave; /* XXX bufobj */
+
+ _mesa_Enable(GL_TEXTURE_RECTANGLE);
+
+ /* draw textured quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_Disable(GL_TEXTURE_RECTANGLE);
+
+ _mesa_meta_end(ctx);
+}
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
new file mode 100644
index 0000000000..a9c5f98043
--- /dev/null
+++ b/src/mesa/drivers/common/meta.h
@@ -0,0 +1,80 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 2009 VMware, Inc. 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.
+ */
+
+
+#ifndef META_H
+#define META_H
+
+
+/**
+ * Flags passed to _mesa_meta_begin().
+ * XXX these flags may evolve...
+ */
+/*@{*/
+#define META_ALPHA_TEST 0x1
+#define META_BLEND 0x2 /**< includes logicop */
+#define META_COLOR_MASK 0x4
+#define META_DEPTH_TEST 0x8
+#define META_FOG 0x10
+#define META_RASTERIZATION 0x20
+#define META_SCISSOR 0x40
+#define META_SHADER 0x80
+#define META_STENCIL_TEST 0x100
+#define META_TRANSFORM 0x200 /**< modelview, projection */
+#define META_TEXTURE 0x400
+#define META_VERTEX 0x800
+#define META_VIEWPORT 0x1000
+#define META_ALL ~0x0
+/*@}*/
+
+
+extern void
+_mesa_meta_init(GLcontext *ctx);
+
+extern void
+_mesa_meta_free(GLcontext *ctx);
+
+extern void
+_mesa_meta_blit_framebuffer(GLcontext *ctx,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+
+extern void
+_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers);
+
+extern void
+_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type);
+
+extern void
+_mesa_meta_draw_pixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels);
+
+
+#endif /* META_H */
diff --git a/src/mesa/drivers/dri/common/.gitignore b/src/mesa/drivers/dri/common/.gitignore
new file mode 100644
index 0000000000..1edeb79fd1
--- /dev/null
+++ b/src/mesa/drivers/dri/common/.gitignore
@@ -0,0 +1 @@
+*.os
diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c
index fe183c2e87..cdbea34495 100644
--- a/src/mesa/drivers/dri/common/dri_metaops.c
+++ b/src/mesa/drivers/dri/common/dri_metaops.c
@@ -357,6 +357,7 @@ meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
GLuint saved_shader_program = 0;
unsigned int saved_active_texture;
struct gl_array_object *arraySave = NULL;
+ GLfloat saved_near, saved_far;
if (!meta->clear.arrayObj)
meta_init_clear(meta);
@@ -370,8 +371,7 @@ meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
GL_POLYGON_BIT |
GL_STENCIL_BUFFER_BIT |
GL_TRANSFORM_BIT |
- GL_CURRENT_BIT |
- GL_VIEWPORT_BIT);
+ GL_CURRENT_BIT);
saved_active_texture = ctx->Texture.CurrentUnit;
/* Disable existing GL state we don't want to apply to a clear. */
@@ -440,6 +440,8 @@ meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
/* The ClearDepth value is unaffected by DepthRange, so do a default
* mapping.
*/
+ saved_near = ctx->Viewport.Near;
+ saved_far = ctx->Viewport.Far;
_mesa_DepthRange(0.0, 1.0);
/* Prepare the vertices, which are the same regardless of which buffer we're
@@ -519,6 +521,7 @@ meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
if (saved_shader_program)
_mesa_UseProgramObjectARB(saved_shader_program);
+ _mesa_DepthRange(saved_near, saved_far);
_mesa_PopAttrib();
/* restore current array object */
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 1d940603fa..e48e10d7c0 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -778,7 +778,7 @@ dri2CreateNewScreen(int scrn, int fd,
if (driDriverAPI.InitScreen2 == NULL)
return NULL;
- psp = _mesa_malloc(sizeof(*psp));
+ psp = _mesa_calloc(sizeof(*psp));
if (!psp)
return NULL;
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index 62801494ce..08a97bb111 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -752,6 +752,13 @@ static const char VertexAttrib4ubNV_names[] =
"";
#endif
+#if defined(need_GL_APPLE_texture_range)
+static const char TextureRangeAPPLE_names[] =
+ "iip\0" /* Parameter signature */
+ "glTextureRangeAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_vertex)
static const char TexCoord2fColor4fNormal3fVertex3fSUN_names[] =
"ffffffffffff\0" /* Parameter signature */
@@ -1567,6 +1574,13 @@ static const char FragmentLightivSGIX_names[] =
"";
#endif
+#if defined(need_GL_APPLE_texture_range)
+static const char GetTexParameterPointervAPPLE_names[] =
+ "iip\0" /* Parameter signature */
+ "glGetTexParameterPointervAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_pixel_transform)
static const char PixelTransformParameterfvEXT_names[] =
"iip\0" /* Parameter signature */
@@ -1771,6 +1785,13 @@ static const char DeleteFencesNV_names[] =
"";
#endif
+#if defined(need_GL_SGIX_polynomial_ffd)
+static const char DeformationMap3dSGIX_names[] =
+ "iddiiddiiddiip\0" /* Parameter signature */
+ "glDeformationMap3dSGIX\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0)
static const char IsShader_names[] =
"i\0" /* Parameter signature */
@@ -1997,13 +2018,6 @@ static const char GetCombinerOutputParameterivNV_names[] =
"";
#endif
-#if defined(need_GL_IBM_multimode_draw_arrays)
-static const char MultiModeDrawArraysIBM_names[] =
- "pppii\0" /* Parameter signature */
- "glMultiModeDrawArraysIBM\0"
- "";
-#endif
-
#if defined(need_GL_SGIS_pixel_texture)
static const char PixelTexGenParameterivSGIS_names[] =
"ip\0" /* Parameter signature */
@@ -2079,6 +2093,13 @@ static const char Uniform2fvARB_names[] =
"";
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const char BufferParameteriAPPLE_names[] =
+ "iii\0" /* Parameter signature */
+ "glBufferParameteriAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_3)
static const char MultiTexCoord3dvARB_names[] =
"ip\0" /* Parameter signature */
@@ -2803,6 +2824,13 @@ static const char IsProgramNV_names[] =
"";
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const char FlushMappedBufferRangeAPPLE_names[] =
+ "iii\0" /* Parameter signature */
+ "glFlushMappedBufferRangeAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_triangle_list)
static const char ReplacementCodePointerSUN_names[] =
"iip\0" /* Parameter signature */
@@ -3920,6 +3948,13 @@ static const char VertexAttribs4dvNV_names[] =
"";
#endif
+#if defined(need_GL_IBM_multimode_draw_arrays)
+static const char MultiModeDrawArraysIBM_names[] =
+ "pppii\0" /* Parameter signature */
+ "glMultiModeDrawArraysIBM\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
static const char VertexAttrib4dARB_names[] =
"idddd\0" /* Parameter signature */
@@ -4604,13 +4639,6 @@ static const char Minmax_names[] =
"";
#endif
-#if defined(need_GL_SGIX_polynomial_ffd)
-static const char DeformationMap3dSGIX_names[] =
- "iddiiddiiddiip\0" /* Parameter signature */
- "glDeformationMap3dSGIX\0"
- "";
-#endif
-
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
static const char FogCoorddvEXT_names[] =
"p\0" /* Parameter signature */
@@ -4973,6 +5001,22 @@ static const struct dri_extension_function GL_3DFX_tbuffer_functions[] = {
};
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const struct dri_extension_function GL_APPLE_flush_buffer_range_functions[] = {
+ { BufferParameteriAPPLE_names, BufferParameteriAPPLE_remap_index, -1 },
+ { FlushMappedBufferRangeAPPLE_names, FlushMappedBufferRangeAPPLE_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
+#if defined(need_GL_APPLE_texture_range)
+static const struct dri_extension_function GL_APPLE_texture_range_functions[] = {
+ { TextureRangeAPPLE_names, TextureRangeAPPLE_remap_index, -1 },
+ { GetTexParameterPointervAPPLE_names, GetTexParameterPointervAPPLE_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_APPLE_vertex_array_object)
static const struct dri_extension_function GL_APPLE_vertex_array_object_functions[] = {
{ DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 },
@@ -6131,9 +6175,9 @@ static const struct dri_extension_function GL_SGIX_pixel_texture_functions[] = {
#if defined(need_GL_SGIX_polynomial_ffd)
static const struct dri_extension_function GL_SGIX_polynomial_ffd_functions[] = {
{ LoadIdentityDeformationMapSGIX_names, LoadIdentityDeformationMapSGIX_remap_index, -1 },
+ { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 },
{ DeformSGIX_names, DeformSGIX_remap_index, -1 },
{ DeformationMap3fSGIX_names, DeformationMap3fSGIX_remap_index, -1 },
- { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c
index dee67feb5a..4e41860d8c 100644
--- a/src/mesa/drivers/dri/fb/fb_egl.c
+++ b/src/mesa/drivers/dri/fb/fb_egl.c
@@ -605,7 +605,7 @@ fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
fbSurface *fs = Lookup_fbSurface(surface);
_eglUnlinkSurface(&fs->Base);
- if (!fs->Base.IsBound)
+ if (!_eglIsSurfaceBound(&fs->Base))
free(fs);
return EGL_TRUE;
}
@@ -616,7 +616,7 @@ fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
fbContext *fc = Lookup_fbContext(context);
_eglUnlinkContext(&fc->Base);
- if (!fc->Base.IsBound)
+ if (!_eglIsContextBound(&fc->Base))
free(fc);
return EGL_TRUE;
}
diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h
index 1bdb32049d..f73cbbf88b 100644
--- a/src/mesa/drivers/dri/i915/i830_context.h
+++ b/src/mesa/drivers/dri/i915/i830_context.h
@@ -40,6 +40,7 @@
#define I830_UPLOAD_BUFFERS 0x2
#define I830_UPLOAD_STIPPLE 0x4
#define I830_UPLOAD_INVARIENT 0x8
+#define I830_UPLOAD_RASTER_RULES 0x10
#define I830_UPLOAD_TEX(i) (0x10<<(i))
#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i))
#define I830_UPLOAD_TEX_ALL (0x0f0)
@@ -99,6 +100,11 @@
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
+enum {
+ I830_RASTER_RULES,
+ I830_RASTER_RULES_SIZE
+};
+
struct i830_texture_object
{
struct intel_texture_object intel;
@@ -112,6 +118,7 @@ struct i830_hw_state
GLuint Ctx[I830_CTX_SETUP_SIZE];
GLuint Buffer[I830_DEST_SETUP_SIZE];
GLuint Stipple[I830_STP_SETUP_SIZE];
+ GLuint RasterRules[I830_RASTER_RULES_SIZE];
GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE];
GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE];
GLuint TexBlendWordsUsed[I830_TEX_UNITS];
@@ -197,6 +204,7 @@ extern void i830InitStateFuncs(struct dd_function_table *functions);
extern void i830EmitState(struct i830_context *i830);
extern void i830InitState(struct i830_context *i830);
+extern void i830_update_provoking_vertex(GLcontext *ctx);
/* i830_metaops.c
*/
diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h
index db16871001..ae1317029a 100644
--- a/src/mesa/drivers/dri/i915/i830_reg.h
+++ b/src/mesa/drivers/dri/i915/i830_reg.h
@@ -420,8 +420,11 @@
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2)
+#define LINE_STRIP_PROVOKE_VRTX_MASK (3<<6)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK (3<<3)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
+#define TRI_STRIP_PROVOKE_VRTX_MASK (3<<0)
#define TRI_STRIP_PROVOKE_VRTX(x) (x)
/* _3DSTATE_SCISSOR_ENABLE, p200 */
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index 8ef6c9144f..645ebe3057 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -1047,6 +1047,16 @@ i830_init_packets(struct i830_context *i830)
TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
+ i830->state.RasterRules[I830_RASTER_RULES] = (_3DSTATE_RASTER_RULES_CMD |
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ ENABLE_TRI_STRIP_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ TRI_STRIP_PROVOKE_VRTX(2));
+
i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE;
@@ -1058,6 +1068,27 @@ i830_init_packets(struct i830_context *i830)
i830->state.Buffer[I830_DESTREG_SR2] = 0;
}
+void
+i830_update_provoking_vertex(GLcontext * ctx)
+{
+ struct i830_context *i830 = i830_context(ctx);
+
+ I830_STATECHANGE(i830, I830_UPLOAD_RASTER_RULES);
+ i830->state.RasterRules[I830_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+ TRI_FAN_PROVOKE_VRTX_MASK |
+ TRI_STRIP_PROVOKE_VRTX_MASK);
+
+ /* _NEW_LIGHT */
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+ i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ TRI_STRIP_PROVOKE_VRTX(2));
+ } else {
+ i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+ TRI_FAN_PROVOKE_VRTX(1) |
+ TRI_STRIP_PROVOKE_VRTX(0));
+ }
+}
void
i830InitStateFuncs(struct dd_function_table *functions)
@@ -1101,6 +1132,7 @@ i830InitState(struct i830_context *i830)
i830->current = &i830->state;
i830->state.emitted = 0;
i830->state.active = (I830_UPLOAD_INVARIENT |
+ I830_UPLOAD_RASTER_RULES |
I830_UPLOAD_TEXBLEND(0) |
I830_UPLOAD_STIPPLE |
I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS);
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 9c6f891dd3..983f6724c9 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -299,7 +299,7 @@ i830_emit_invarient_state(struct intel_context *intel)
{
BATCH_LOCALS;
- BEGIN_BATCH(30, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(29, IGNORE_CLIPRECTS);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
@@ -351,15 +351,6 @@ i830_emit_invarient_state(struct intel_context *intel)
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
- OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- ENABLE_TRI_STRIP_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
-
OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
@@ -394,6 +385,9 @@ get_state_size(struct i830_hw_state *state)
if (dirty & I830_UPLOAD_INVARIENT)
sz += 40 * sizeof(int);
+ if (dirty & I830_UPLOAD_RASTER_RULES)
+ sz += sizeof(state->RasterRules);
+
if (dirty & I830_UPLOAD_CTX)
sz += sizeof(state->Ctx);
@@ -486,6 +480,11 @@ i830_emit_state(struct intel_context *intel)
i830_emit_invarient_state(intel);
}
+ if (dirty & I830_UPLOAD_RASTER_RULES) {
+ DBG("I830_UPLOAD_RASTER_RULES:\n");
+ emit(intel, state->RasterRules, sizeof(state->RasterRules));
+ }
+
if (dirty & I830_UPLOAD_CTX) {
DBG("I830_UPLOAD_CTX:\n");
emit(intel, state->Ctx, sizeof(state->Ctx));
@@ -737,6 +736,13 @@ i830_assert_not_dirty( struct intel_context *intel )
assert(!get_dirty(state));
}
+static void
+i830_invalidate_state(struct intel_context *intel, GLuint new_state)
+{
+ if (new_state & _NEW_LIGHT)
+ i830_update_provoking_vertex(&intel->ctx);
+}
+
void
i830InitVtbl(struct i830_context *i830)
{
@@ -752,4 +758,5 @@ i830InitVtbl(struct i830_context *i830)
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
i830->intel.vtbl.finish_batch = intel_finish_vb;
+ i830->intel.vtbl.invalidate_state = i830_invalidate_state;
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 5aa41334b0..bb08cf8d18 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -77,6 +77,8 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
i915_update_fog(ctx);
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS | _NEW_POLYGON))
i915_update_stencil(ctx);
+ if (new_state & (_NEW_LIGHT))
+ i915_update_provoking_vertex(ctx);
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index c6b7377da8..8de4a9d0d3 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -48,6 +48,7 @@
#define I915_UPLOAD_FOG 0x20
#define I915_UPLOAD_INVARIENT 0x40
#define I915_UPLOAD_DEFAULTS 0x80
+#define I915_UPLOAD_RASTER_RULES 0x100
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
#define I915_UPLOAD_TEX_0_SHIFT 16
@@ -112,6 +113,10 @@
#define I915_DEFREG_Z1 5
#define I915_DEF_SETUP_SIZE 6
+enum {
+ I915_RASTER_RULES,
+ I915_RASTER_RULES_SETUP_SIZE,
+};
#define I915_MAX_CONSTANT 32
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT))
@@ -208,6 +213,7 @@ struct i915_hw_state
GLuint Stipple[I915_STP_SETUP_SIZE];
GLuint Fog[I915_FOG_SETUP_SIZE];
GLuint Defaults[I915_DEF_SETUP_SIZE];
+ GLuint RasterRules[I915_RASTER_RULES_SETUP_SIZE];
GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE];
GLuint Constant[I915_CONSTANT_SIZE];
GLuint ConstantSize;
@@ -324,6 +330,7 @@ extern void i915InitStateFunctions(struct dd_function_table *functions);
extern void i915InitState(struct i915_context *i915);
extern void i915_update_fog(GLcontext * ctx);
extern void i915_update_stencil(GLcontext * ctx);
+extern void i915_update_provoking_vertex(GLcontext *ctx);
/*======================================================================
diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h
index 80ec46190d..b5fa7fddb9 100644
--- a/src/mesa/drivers/dri/i915/i915_reg.h
+++ b/src/mesa/drivers/dri/i915/i915_reg.h
@@ -297,7 +297,9 @@
#define TEXKILL_4D (1<<9)
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
+#define LINE_STRIP_PROVOKE_VRTX_MASK (3 << 6)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK (3 << 3)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
/* _3DSTATE_SCISSOR_ENABLE, p256 */
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 670451bc83..b60efea75b 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -1033,6 +1033,13 @@ i915_init_packets(struct i915_context *i915)
i915->state.Buffer[I915_DESTREG_SR2] = 0;
}
+ i915->state.RasterRules[I915_RASTER_RULES] = _3DSTATE_RASTER_RULES_CMD |
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D;
#if 0
{
@@ -1053,7 +1060,33 @@ i915_init_packets(struct i915_context *i915)
i915->state.active = (I915_UPLOAD_PROGRAM |
I915_UPLOAD_STIPPLE |
I915_UPLOAD_CTX |
- I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT);
+ I915_UPLOAD_BUFFERS |
+ I915_UPLOAD_INVARIENT |
+ I915_UPLOAD_RASTER_RULES);
+}
+
+void
+i915_update_provoking_vertex(GLcontext * ctx)
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+ i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK);
+
+ I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES);
+ i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+ TRI_FAN_PROVOKE_VRTX_MASK);
+
+ /* _NEW_LIGHT */
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+ i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2));
+ i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT);
+ } else {
+ i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+ TRI_FAN_PROVOKE_VRTX(1));
+ i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT);
+ }
}
void
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 707864ebfd..9a723d3cd7 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -176,7 +176,7 @@ i915_emit_invarient_state(struct intel_context *intel)
{
BATCH_LOCALS;
- BEGIN_BATCH(18, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(17, IGNORE_CLIPRECTS);
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -200,14 +200,6 @@ i915_emit_invarient_state(struct intel_context *intel)
CSB_TCB(3, 3) |
CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7));
- OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D);
-
/* Need to initialize this to zero.
*/
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0));
@@ -258,6 +250,9 @@ get_state_size(struct i915_hw_state *state)
if (dirty & I915_UPLOAD_INVARIENT)
sz += 30 * 4;
+ if (dirty & I915_UPLOAD_RASTER_RULES)
+ sz += sizeof(state->RasterRules);
+
if (dirty & I915_UPLOAD_CTX)
sz += sizeof(state->Ctx);
@@ -366,6 +361,12 @@ i915_emit_state(struct intel_context *intel)
i915_emit_invarient_state(intel);
}
+ if (dirty & I915_UPLOAD_RASTER_RULES) {
+ if (INTEL_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "I915_UPLOAD_RASTER_RULES:\n");
+ emit(intel, state->RasterRules, sizeof(state->RasterRules));
+ }
+
if (dirty & I915_UPLOAD_CTX) {
if (INTEL_DEBUG & DEBUG_STATE)
fprintf(stderr, "I915_UPLOAD_CTX:\n");
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 00a42111da..128afb5686 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -43,6 +43,7 @@ DRIVER_SOURCES = \
brw_clip_util.c \
brw_context.c \
brw_curbe.c \
+ brw_disasm.c \
brw_draw.c \
brw_draw_upload.c \
brw_eu.c \
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 57ddf75413..847c44ed83 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -143,6 +143,7 @@ struct brw_context;
#define BRW_NEW_DEPTH_BUFFER 0x20000
#define BRW_NEW_NR_WM_SURFACES 0x40000
#define BRW_NEW_NR_VS_SURFACES 0x80000
+#define BRW_NEW_INDEX_BUFFER 0x100000
struct brw_state_flags {
/** State update flags signalled by mesa internals */
@@ -438,9 +439,13 @@ struct brw_query_object {
unsigned int count;
};
+
+/**
+ * brw_context is derived from intel_context.
+ */
struct brw_context
{
- struct intel_context intel;
+ struct intel_context intel; /**< base class, must be first field */
GLuint primitive;
GLboolean emit_state_always;
@@ -475,6 +480,9 @@ struct brw_context
struct {
struct brw_vertex_element inputs[VERT_ATTRIB_MAX];
+ struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
+ GLuint nr_enabled;
+
#define BRW_NR_UPLOAD_BUFS 17
#define BRW_UPLOAD_INIT_SIZE (128*1024)
@@ -498,8 +506,15 @@ struct brw_context
*/
const struct _mesa_index_buffer *ib;
+ /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */
dri_bo *bo;
unsigned int offset;
+ unsigned int size;
+ /* Offset to index buffer index to use in CMD_3D_PRIM so that we can
+ * avoid re-uploading the IB packet over and over if we're actually
+ * referencing the same index buffer.
+ */
+ unsigned int start_vertex_offset;
} ib;
/* Active vertex program:
@@ -706,6 +721,8 @@ void brw_upload_urb_fence(struct brw_context *brw);
*/
void brw_upload_cs_urb_state(struct brw_context *brw);
+/* brw_disasm.c */
+int brw_disasm (FILE *file, struct brw_instruction *inst);
/*======================================================================
* Inline conversion functions. These are better-typed than the
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index d166250b4f..78d457ad2b 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -471,8 +471,9 @@
#define BRW_CONDITIONAL_GE 4
#define BRW_CONDITIONAL_L 5
#define BRW_CONDITIONAL_LE 6
-#define BRW_CONDITIONAL_C 7
+#define BRW_CONDITIONAL_R 7
#define BRW_CONDITIONAL_O 8
+#define BRW_CONDITIONAL_U 9
#define BRW_DEBUG_NONE 0
#define BRW_DEBUG_BREAKPOINT 1
@@ -512,6 +513,7 @@
#define BRW_OPCODE_RSL 11
#define BRW_OPCODE_ASR 12
#define BRW_OPCODE_CMP 16
+#define BRW_OPCODE_CMPN 17
#define BRW_OPCODE_JMPI 32
#define BRW_OPCODE_IF 34
#define BRW_OPCODE_IFF 35
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
new file mode 100644
index 0000000000..9fef230507
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -0,0 +1,903 @@
+/*
+ * Copyright © 2008 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "main/mtypes.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+
+struct {
+ char *name;
+ int nsrc;
+ int ndst;
+} opcode[128] = {
+ [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
+
+ [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
+
+ [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
+
+ [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
+ [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 },
+ [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
+ [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
+};
+
+char *conditional_modifier[16] = {
+ [BRW_CONDITIONAL_NONE] = "",
+ [BRW_CONDITIONAL_Z] = ".e",
+ [BRW_CONDITIONAL_NZ] = ".ne",
+ [BRW_CONDITIONAL_G] = ".g",
+ [BRW_CONDITIONAL_GE] = ".ge",
+ [BRW_CONDITIONAL_L] = ".l",
+ [BRW_CONDITIONAL_LE] = ".le",
+ [BRW_CONDITIONAL_R] = ".r",
+ [BRW_CONDITIONAL_O] = ".o",
+ [BRW_CONDITIONAL_U] = ".u",
+};
+
+char *negate[2] = {
+ [0] = "",
+ [1] = "-",
+};
+
+char *_abs[2] = {
+ [0] = "",
+ [1] = "(abs)",
+};
+
+char *vert_stride[16] = {
+ [0] = "0",
+ [1] = "1",
+ [2] = "2",
+ [3] = "4",
+ [4] = "8",
+ [5] = "16",
+ [6] = "32",
+ [15] = "VxH",
+};
+
+char *width[8] = {
+ [0] = "1",
+ [1] = "2",
+ [2] = "4",
+ [3] = "8",
+ [4] = "16",
+};
+
+char *horiz_stride[4] = {
+ [0] = "0",
+ [1] = "1",
+ [2] = "2",
+ [3] = "4"
+};
+
+char *chan_sel[4] = {
+ [0] = "x",
+ [1] = "y",
+ [2] = "z",
+ [3] = "w",
+};
+
+char *dest_condmod[16] = {
+};
+
+char *debug_ctrl[2] = {
+ [0] = "",
+ [1] = ".breakpoint"
+};
+
+char *saturate[2] = {
+ [0] = "",
+ [1] = ".sat"
+};
+
+char *exec_size[8] = {
+ [0] = "1",
+ [1] = "2",
+ [2] = "4",
+ [3] = "8",
+ [4] = "16",
+ [5] = "32"
+};
+
+char *pred_inv[2] = {
+ [0] = "+",
+ [1] = "-"
+};
+
+char *pred_ctrl_align16[16] = {
+ [1] = "",
+ [2] = ".x",
+ [3] = ".y",
+ [4] = ".z",
+ [5] = ".w",
+ [6] = ".any4h",
+ [7] = ".all4h",
+};
+
+char *pred_ctrl_align1[16] = {
+ [1] = "",
+ [2] = ".anyv",
+ [3] = ".allv",
+ [4] = ".any2h",
+ [5] = ".all2h",
+ [6] = ".any4h",
+ [7] = ".all4h",
+ [8] = ".any8h",
+ [9] = ".all8h",
+ [10] = ".any16h",
+ [11] = ".all16h",
+};
+
+char *thread_ctrl[4] = {
+ [0] = "",
+ [2] = "switch"
+};
+
+char *compr_ctrl[4] = {
+ [0] = "",
+ [1] = "sechalf",
+ [2] = "compr",
+};
+
+char *dep_ctrl[4] = {
+ [0] = "",
+ [1] = "NoDDClr",
+ [2] = "NoDDChk",
+ [3] = "NoDDClr,NoDDChk",
+};
+
+char *mask_ctrl[4] = {
+ [0] = "",
+ [1] = "nomask",
+};
+
+char *access_mode[2] = {
+ [0] = "align1",
+ [1] = "align16",
+};
+
+char *reg_encoding[8] = {
+ [0] = "UD",
+ [1] = "D",
+ [2] = "UW",
+ [3] = "W",
+ [4] = "UB",
+ [5] = "B",
+ [7] = "F"
+};
+
+char *imm_encoding[8] = {
+ [0] = "UD",
+ [1] = "D",
+ [2] = "UW",
+ [3] = "W",
+ [5] = "VF",
+ [5] = "V",
+ [7] = "F"
+};
+
+char *reg_file[4] = {
+ [0] = "A",
+ [1] = "g",
+ [2] = "m",
+ [3] = "imm",
+};
+
+char *writemask[16] = {
+ [0x0] = ".",
+ [0x1] = ".x",
+ [0x2] = ".y",
+ [0x3] = ".xy",
+ [0x4] = ".z",
+ [0x5] = ".xz",
+ [0x6] = ".yz",
+ [0x7] = ".xyz",
+ [0x8] = ".w",
+ [0x9] = ".xw",
+ [0xa] = ".yw",
+ [0xb] = ".xyw",
+ [0xc] = ".zw",
+ [0xd] = ".xzw",
+ [0xe] = ".yzw",
+ [0xf] = "",
+};
+
+char *end_of_thread[2] = {
+ [0] = "",
+ [1] = "EOT"
+};
+
+char *target_function[16] = {
+ [BRW_MESSAGE_TARGET_NULL] = "null",
+ [BRW_MESSAGE_TARGET_MATH] = "math",
+ [BRW_MESSAGE_TARGET_SAMPLER] = "sampler",
+ [BRW_MESSAGE_TARGET_GATEWAY] = "gateway",
+ [BRW_MESSAGE_TARGET_DATAPORT_READ] = "read",
+ [BRW_MESSAGE_TARGET_DATAPORT_WRITE] = "write",
+ [BRW_MESSAGE_TARGET_URB] = "urb",
+ [BRW_MESSAGE_TARGET_THREAD_SPAWNER] = "thread_spawner"
+};
+
+char *math_function[16] = {
+ [BRW_MATH_FUNCTION_INV] = "inv",
+ [BRW_MATH_FUNCTION_LOG] = "log",
+ [BRW_MATH_FUNCTION_EXP] = "exp",
+ [BRW_MATH_FUNCTION_SQRT] = "sqrt",
+ [BRW_MATH_FUNCTION_RSQ] = "rsq",
+ [BRW_MATH_FUNCTION_SIN] = "sin",
+ [BRW_MATH_FUNCTION_COS] = "cos",
+ [BRW_MATH_FUNCTION_SINCOS] = "sincos",
+ [BRW_MATH_FUNCTION_TAN] = "tan",
+ [BRW_MATH_FUNCTION_POW] = "pow",
+ [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
+ [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intmod",
+ [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intdiv",
+};
+
+char *math_saturate[2] = {
+ [0] = "",
+ [1] = "sat"
+};
+
+char *math_signed[2] = {
+ [0] = "",
+ [1] = "signed"
+};
+
+char *math_scalar[2] = {
+ [0] = "",
+ [1] = "scalar"
+};
+
+char *math_precision[2] = {
+ [0] = "",
+ [1] = "partial_precision"
+};
+
+char *urb_swizzle[4] = {
+ [BRW_URB_SWIZZLE_NONE] = "",
+ [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
+ [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
+};
+
+char *urb_allocate[2] = {
+ [0] = "",
+ [1] = "allocate"
+};
+
+char *urb_used[2] = {
+ [0] = "",
+ [1] = "used"
+};
+
+char *urb_complete[2] = {
+ [0] = "",
+ [1] = "complete"
+};
+
+char *sampler_target_format[4] = {
+ [0] = "F",
+ [2] = "UD",
+ [3] = "D"
+};
+
+
+static int column;
+
+static int string (FILE *file, char *string)
+{
+ fputs (string, file);
+ column += strlen (string);
+ return 0;
+}
+
+static int format (FILE *f, char *format, ...)
+{
+ char buf[1024];
+ va_list args;
+ va_start (args, format);
+
+ vsnprintf (buf, sizeof (buf) - 1, format, args);
+ string (f, buf);
+ return 0;
+}
+
+static int newline (FILE *f)
+{
+ putc ('\n', f);
+ column = 0;
+ return 0;
+}
+
+static int pad (FILE *f, int c)
+{
+ do
+ string (f, " ");
+ while (column < c);
+ return 0;
+}
+
+static int control (FILE *file, char *name, char *ctrl[], GLuint id, int *space)
+{
+ if (!ctrl[id]) {
+ fprintf (file, "*** invalid %s value %d ",
+ name, id);
+ return 1;
+ }
+ if (ctrl[id][0])
+ {
+ if (space && *space)
+ string (file, " ");
+ string (file, ctrl[id]);
+ if (space)
+ *space = 1;
+ }
+ return 0;
+}
+
+static int print_opcode (FILE *file, int id)
+{
+ if (!opcode[id].name) {
+ format (file, "*** invalid opcode value %d ", id);
+ return 1;
+ }
+ string (file, opcode[id].name);
+ return 0;
+}
+
+static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
+{
+ int err = 0;
+ if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
+ switch (_reg_nr & 0xf0) {
+ case BRW_ARF_NULL:
+ string (file, "null");
+ return -1;
+ case BRW_ARF_ADDRESS:
+ format (file, "a%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_ACCUMULATOR:
+ format (file, "acc%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_MASK:
+ format (file, "mask%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_MASK_STACK:
+ format (file, "msd%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_STATE:
+ format (file, "sr%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_CONTROL:
+ format (file, "cr%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_NOTIFICATION_COUNT:
+ format (file, "n%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_IP:
+ string (file, "ip");
+ return -1;
+ break;
+ default:
+ format (file, "ARF%d", _reg_nr);
+ break;
+ }
+ } else {
+ err |= control (file, "src reg file", reg_file, _reg_file, NULL);
+ format (file, "%d", _reg_nr);
+ }
+ return err;
+}
+
+static int dest (FILE *file, struct brw_instruction *inst)
+{
+ int err = 0;
+
+ if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ err |= reg (file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr);
+ if (err == -1)
+ return 0;
+ if (inst->bits1.da1.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.da1.dest_subreg_nr);
+ format (file, "<%d>", inst->bits1.da1.dest_horiz_stride);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
+ }
+ else
+ {
+ string (file, "g[a0");
+ if (inst->bits1.ia1.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.ia1.dest_subreg_nr);
+ if (inst->bits1.ia1.dest_indirect_offset)
+ format (file, " %d", inst->bits1.ia1.dest_indirect_offset);
+ string (file, "]");
+ format (file, "<%d>", inst->bits1.ia1.dest_horiz_stride);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.ia1.dest_reg_type, NULL);
+ }
+ }
+ else
+ {
+ if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ err |= reg (file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr);
+ if (err == -1)
+ return 0;
+ if (inst->bits1.da16.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.da16.dest_subreg_nr);
+ string (file, "<1>");
+ err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL);
+ }
+ else
+ {
+ err = 1;
+ string (file, "Indirect align16 address mode not supported");
+ }
+ }
+
+ return 0;
+}
+
+static int src_align1_region (FILE *file,
+ GLuint _vert_stride, GLuint _width, GLuint _horiz_stride)
+{
+ int err = 0;
+ string (file, "<");
+ err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+ string (file, ",");
+ err |= control (file, "width", width, _width, NULL);
+ string (file, ",");
+ err |= control (file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
+ string (file, ">");
+ return err;
+}
+
+static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
+ GLuint _vert_stride, GLuint _width, GLuint _horiz_stride,
+ GLuint reg_num, GLuint sub_reg_num, GLuint __abs, GLuint _negate)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ err |= reg (file, _reg_file, reg_num);
+ if (err == -1)
+ return 0;
+ if (sub_reg_num)
+ format (file, ".%d", sub_reg_num);
+ src_align1_region (file, _vert_stride, _width, _horiz_stride);
+ err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+ return err;
+}
+
+static int src_ia1 (FILE *file,
+ GLuint type,
+ GLuint _reg_file,
+ GLint _addr_imm,
+ GLuint _addr_subreg_nr,
+ GLuint _negate,
+ GLuint __abs,
+ GLuint _addr_mode,
+ GLuint _horiz_stride,
+ GLuint _width,
+ GLuint _vert_stride)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ string (file, "g[a0");
+ if (_addr_subreg_nr)
+ format (file, ".%d", _addr_subreg_nr);
+ if (_addr_imm)
+ format (file, " %d", _addr_imm);
+ string (file, "]");
+ src_align1_region (file, _vert_stride, _width, _horiz_stride);
+ err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+ return err;
+}
+
+static int src_da16 (FILE *file,
+ GLuint _reg_type,
+ GLuint _reg_file,
+ GLuint _vert_stride,
+ GLuint _reg_nr,
+ GLuint _subreg_nr,
+ GLuint __abs,
+ GLuint _negate,
+ GLuint swz_x,
+ GLuint swz_y,
+ GLuint swz_z,
+ GLuint swz_w)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ err |= reg (file, _reg_file, _reg_nr);
+ if (err == -1)
+ return 0;
+ if (_subreg_nr)
+ format (file, ".%d", _subreg_nr);
+ string (file, "<");
+ err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+ string (file, ",1,1>");
+ err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
+ /*
+ * Three kinds of swizzle display:
+ * identity - nothing printed
+ * 1->all - print the single channel
+ * 1->1 - print the mapping
+ */
+ if (swz_x == BRW_CHANNEL_X &&
+ swz_y == BRW_CHANNEL_Y &&
+ swz_z == BRW_CHANNEL_Z &&
+ swz_w == BRW_CHANNEL_W)
+ {
+ ;
+ }
+ else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
+ {
+ string (file, ".");
+ err |= control (file, "channel select", chan_sel, swz_x, NULL);
+ }
+ else
+ {
+ string (file, ".");
+ err |= control (file, "channel select", chan_sel, swz_x, NULL);
+ err |= control (file, "channel select", chan_sel, swz_y, NULL);
+ err |= control (file, "channel select", chan_sel, swz_z, NULL);
+ err |= control (file, "channel select", chan_sel, swz_w, NULL);
+ }
+ return err;
+}
+
+
+static int imm (FILE *file, GLuint type, struct brw_instruction *inst) {
+ switch (type) {
+ case BRW_REGISTER_TYPE_UD:
+ format (file, "0x%08xUD", inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_D:
+ format (file, "%dD", inst->bits3.d);
+ break;
+ case BRW_REGISTER_TYPE_UW:
+ format (file, "0x%04xUW", (uint16_t) inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_W:
+ format (file, "%dW", (int16_t) inst->bits3.d);
+ break;
+ case BRW_REGISTER_TYPE_UB:
+ format (file, "0x%02xUB", (int8_t) inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_VF:
+ format (file, "Vector Float");
+ break;
+ case BRW_REGISTER_TYPE_V:
+ format (file, "0x%08xV", inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_F:
+ format (file, "%-gF", inst->bits3.f);
+ }
+ return 0;
+}
+
+static int src0 (FILE *file, struct brw_instruction *inst)
+{
+ if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE)
+ return imm (file, inst->bits1.da1.src0_reg_type,
+ inst);
+ else if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da1 (file,
+ inst->bits1.da1.src0_reg_type,
+ inst->bits1.da1.src0_reg_file,
+ inst->bits2.da1.src0_vert_stride,
+ inst->bits2.da1.src0_width,
+ inst->bits2.da1.src0_horiz_stride,
+ inst->bits2.da1.src0_reg_nr,
+ inst->bits2.da1.src0_subreg_nr,
+ inst->bits2.da1.src0_abs,
+ inst->bits2.da1.src0_negate);
+ }
+ else
+ {
+ return src_ia1 (file,
+ inst->bits1.ia1.src0_reg_type,
+ inst->bits1.ia1.src0_reg_file,
+ inst->bits2.ia1.src0_indirect_offset,
+ inst->bits2.ia1.src0_subreg_nr,
+ inst->bits2.ia1.src0_negate,
+ inst->bits2.ia1.src0_abs,
+ inst->bits2.ia1.src0_address_mode,
+ inst->bits2.ia1.src0_horiz_stride,
+ inst->bits2.ia1.src0_width,
+ inst->bits2.ia1.src0_vert_stride);
+ }
+ }
+ else
+ {
+ if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da16 (file,
+ inst->bits1.da16.src0_reg_type,
+ inst->bits1.da16.src0_reg_file,
+ inst->bits2.da16.src0_vert_stride,
+ inst->bits2.da16.src0_reg_nr,
+ inst->bits2.da16.src0_subreg_nr,
+ inst->bits2.da16.src0_abs,
+ inst->bits2.da16.src0_negate,
+ inst->bits2.da16.src0_swz_x,
+ inst->bits2.da16.src0_swz_y,
+ inst->bits2.da16.src0_swz_z,
+ inst->bits2.da16.src0_swz_w);
+ }
+ else
+ {
+ string (file, "Indirect align16 address mode not supported");
+ return 1;
+ }
+ }
+}
+
+static int src1 (FILE *file, struct brw_instruction *inst)
+{
+ if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
+ return imm (file, inst->bits1.da1.src1_reg_type,
+ inst);
+ else if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da1 (file,
+ inst->bits1.da1.src1_reg_type,
+ inst->bits1.da1.src1_reg_file,
+ inst->bits3.da1.src1_vert_stride,
+ inst->bits3.da1.src1_width,
+ inst->bits3.da1.src1_horiz_stride,
+ inst->bits3.da1.src1_reg_nr,
+ inst->bits3.da1.src1_subreg_nr,
+ inst->bits3.da1.src1_abs,
+ inst->bits3.da1.src1_negate);
+ }
+ else
+ {
+ return src_ia1 (file,
+ inst->bits1.ia1.src1_reg_type,
+ inst->bits1.ia1.src1_reg_file,
+ inst->bits3.ia1.src1_indirect_offset,
+ inst->bits3.ia1.src1_subreg_nr,
+ inst->bits3.ia1.src1_negate,
+ inst->bits3.ia1.src1_abs,
+ inst->bits3.ia1.src1_address_mode,
+ inst->bits3.ia1.src1_horiz_stride,
+ inst->bits3.ia1.src1_width,
+ inst->bits3.ia1.src1_vert_stride);
+ }
+ }
+ else
+ {
+ if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da16 (file,
+ inst->bits1.da16.src1_reg_type,
+ inst->bits1.da16.src1_reg_file,
+ inst->bits3.da16.src1_vert_stride,
+ inst->bits3.da16.src1_reg_nr,
+ inst->bits3.da16.src1_subreg_nr,
+ inst->bits3.da16.src1_abs,
+ inst->bits3.da16.src1_negate,
+ inst->bits3.da16.src1_swz_x,
+ inst->bits3.da16.src1_swz_y,
+ inst->bits3.da16.src1_swz_z,
+ inst->bits3.da16.src1_swz_w);
+ }
+ else
+ {
+ string (file, "Indirect align16 address mode not supported");
+ return 1;
+ }
+ }
+}
+
+int brw_disasm (FILE *file, struct brw_instruction *inst)
+{
+ int err = 0;
+ int space = 0;
+
+ if (inst->header.predicate_control) {
+ string (file, "(");
+ err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL);
+ string (file, "f0");
+ if (inst->bits2.da1.flag_reg_nr)
+ format (file, ".%d", inst->bits2.da1.flag_reg_nr);
+ if (inst->header.access_mode == BRW_ALIGN_1)
+ err |= control (file, "predicate control align1", pred_ctrl_align1,
+ inst->header.predicate_control, NULL);
+ else
+ err |= control (file, "predicate control align16", pred_ctrl_align16,
+ inst->header.predicate_control, NULL);
+ string (file, ") ");
+ }
+
+ err |= print_opcode (file, inst->header.opcode);
+ err |= control (file, "saturate", saturate, inst->header.saturate, NULL);
+ err |= control (file, "debug control", debug_ctrl, inst->header.debug_control, NULL);
+
+ if (inst->header.opcode != BRW_OPCODE_SEND)
+ err |= control (file, "conditional modifier", conditional_modifier,
+ inst->header.destreg__conditionalmod, NULL);
+
+ if (inst->header.opcode != BRW_OPCODE_NOP) {
+ string (file, "(");
+ err |= control (file, "execution size", exec_size, inst->header.execution_size, NULL);
+ string (file, ")");
+ }
+
+ if (inst->header.opcode == BRW_OPCODE_SEND)
+ format (file, " %d", inst->header.destreg__conditionalmod);
+
+ if (opcode[inst->header.opcode].ndst > 0) {
+ pad (file, 16);
+ err |= dest (file, inst);
+ }
+ if (opcode[inst->header.opcode].nsrc > 0) {
+ pad (file, 32);
+ err |= src0 (file, inst);
+ }
+ if (opcode[inst->header.opcode].nsrc > 1) {
+ pad (file, 48);
+ err |= src1 (file, inst);
+ }
+
+ if (inst->header.opcode == BRW_OPCODE_SEND) {
+ newline (file);
+ pad (file, 16);
+ space = 0;
+ err |= control (file, "target function", target_function,
+ inst->bits3.generic.msg_target, &space);
+ switch (inst->bits3.generic.msg_target) {
+ case BRW_MESSAGE_TARGET_MATH:
+ err |= control (file, "math function", math_function,
+ inst->bits3.math.function, &space);
+ err |= control (file, "math saturate", math_saturate,
+ inst->bits3.math.saturate, &space);
+ err |= control (file, "math signed", math_signed,
+ inst->bits3.math.int_type, &space);
+ err |= control (file, "math scalar", math_scalar,
+ inst->bits3.math.data_type, &space);
+ err |= control (file, "math precision", math_precision,
+ inst->bits3.math.precision, &space);
+ break;
+ case BRW_MESSAGE_TARGET_SAMPLER:
+ format (file, " (%d, %d, ",
+ inst->bits3.sampler.binding_table_index,
+ inst->bits3.sampler.sampler);
+ err |= control (file, "sampler target format", sampler_target_format,
+ inst->bits3.sampler.return_format, NULL);
+ string (file, ")");
+ break;
+ case BRW_MESSAGE_TARGET_DATAPORT_WRITE:
+ format (file, " (%d, %d, %d, %d)",
+ inst->bits3.dp_write.binding_table_index,
+ (inst->bits3.dp_write.pixel_scoreboard_clear << 3) |
+ inst->bits3.dp_write.msg_control,
+ inst->bits3.dp_write.msg_type,
+ inst->bits3.dp_write.send_commit_msg);
+ break;
+ case BRW_MESSAGE_TARGET_URB:
+ format (file, " %d", inst->bits3.urb.offset);
+ space = 1;
+ err |= control (file, "urb swizzle", urb_swizzle,
+ inst->bits3.urb.swizzle_control, &space);
+ err |= control (file, "urb allocate", urb_allocate,
+ inst->bits3.urb.allocate, &space);
+ err |= control (file, "urb used", urb_used,
+ inst->bits3.urb.used, &space);
+ err |= control (file, "urb complete", urb_complete,
+ inst->bits3.urb.complete, &space);
+ break;
+ case BRW_MESSAGE_TARGET_THREAD_SPAWNER:
+ break;
+ default:
+ format (file, "unsupported target %d", inst->bits3.generic.msg_target);
+ break;
+ }
+ if (space)
+ string (file, " ");
+ format (file, "mlen %d",
+ inst->bits3.generic.msg_length);
+ format (file, " rlen %d",
+ inst->bits3.generic.response_length);
+ }
+ pad (file, 64);
+ if (inst->header.opcode != BRW_OPCODE_NOP) {
+ string (file, "{");
+ space = 1;
+ err |= control(file, "access mode", access_mode, inst->header.access_mode, &space);
+ err |= control (file, "mask control", mask_ctrl, inst->header.mask_control, &space);
+ err |= control (file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
+ err |= control (file, "compression control", compr_ctrl, inst->header.compression_control, &space);
+ err |= control (file, "thread control", thread_ctrl, inst->header.thread_control, &space);
+ if (inst->header.opcode == BRW_OPCODE_SEND)
+ err |= control (file, "end of thread", end_of_thread,
+ inst->bits3.generic.end_of_thread, &space);
+ if (space)
+ string (file, " ");
+ string (file, "}");
+ }
+ string (file, ";");
+ newline (file);
+ return err;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 5152c3f3a5..682094ff13 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -141,6 +141,8 @@ static void brw_emit_prim(struct brw_context *brw,
prim_packet.verts_per_instance = trim(prim->mode, prim->count);
prim_packet.start_vert_location = prim->start;
+ if (prim->indexed)
+ prim_packet.start_vert_location += brw->ib.start_vertex_offset;
prim_packet.instance_count = 1;
prim_packet.start_instance_location = 0;
prim_packet.base_vert_location = 0;
@@ -422,54 +424,31 @@ 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;
-
- 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,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index )
{
GLboolean retval;
- /* 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 (!vbo_all_varyings_in_vbos(arrays)) {
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ /* Decide if we want to rebase. If so we end up recursing once
+ * only into this function.
+ */
+ if (min_index != 0) {
+ vbo_rebase_prims(ctx, arrays,
+ prim, nr_prims,
+ ib, min_index, max_index,
+ brw_draw_prims );
+ return;
+ }
}
/* Make a first attempt at drawing:
diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h
index 9aebbdb1b8..2a14db217f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.h
+++ b/src/mesa/drivers/dri/i965/brw_draw.h
@@ -39,6 +39,7 @@ void brw_draw_prims( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index c29f1dd5c0..ab6b62812f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -350,9 +350,6 @@ static void brw_prepare_vertices(struct brw_context *brw)
unsigned int min_index = brw->vb.min_index;
unsigned int max_index = brw->vb.max_index;
- struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
- GLuint nr_enabled = 0;
-
struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
GLuint nr_uploads = 0;
@@ -362,12 +359,13 @@ static void brw_prepare_vertices(struct brw_context *brw)
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
/* Accumulate the list of enabled arrays. */
+ brw->vb.nr_enabled = 0;
while (vs_inputs) {
GLuint i = _mesa_ffsll(vs_inputs) - 1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
vs_inputs &= ~(1 << i);
- enabled[nr_enabled++] = input;
+ brw->vb.enabled[brw->vb.nr_enabled++] = input;
}
/* XXX: In the rare cases where this happens we fallback all
@@ -376,16 +374,15 @@ static void brw_prepare_vertices(struct brw_context *brw)
* cases with > 17 vertex attributes enabled, so it probably
* isn't an issue at this point.
*/
- if (nr_enabled >= BRW_VEP_MAX) {
+ if (brw->vb.nr_enabled >= BRW_VEP_MAX) {
intel->Fallback = 1;
return;
}
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
input->element_size = get_size(input->glarray->Type) * input->glarray->Size;
- input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
if (input->glarray->BufferObj->Name != 0) {
struct intel_buffer_object *intel_buffer =
@@ -398,7 +395,23 @@ static void brw_prepare_vertices(struct brw_context *brw)
dri_bo_reference(input->bo);
input->offset = (unsigned long)input->glarray->Ptr;
input->stride = input->glarray->StrideB;
+ input->count = input->glarray->_MaxElement;
+
+ /* This is a common place to reach if the user mistakenly supplies
+ * a pointer in place of a VBO offset. If we just let it go through,
+ * we may end up dereferencing a pointer beyond the bounds of the
+ * GTT. We would hope that the VBO's max_index would save us, but
+ * Mesa appears to hand us min/max values not clipped to the
+ * array object's _MaxElement, and _MaxElement frequently appears
+ * to be wrong anyway.
+ *
+ * The VBO spec allows application termination in this case, and it's
+ * probably a service to the poor programmer to do so rather than
+ * trying to just not render.
+ */
+ assert(input->offset < input->bo->size);
} else {
+ input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
if (input->bo != NULL) {
/* Already-uploaded vertex data is present from a previous
* prepare_vertices, but we had to re-validate state due to
@@ -466,8 +479,8 @@ static void brw_prepare_vertices(struct brw_context *brw)
brw_prepare_query_begin(brw);
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
brw_add_validated_bo(brw, input->bo);
}
@@ -477,34 +490,44 @@ static void brw_emit_vertices(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
- struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
GLuint i;
- GLuint nr_enabled = 0;
- /* Accumulate the list of enabled arrays. */
- while (vs_inputs) {
- i = _mesa_ffsll(vs_inputs) - 1;
- struct brw_vertex_element *input = &brw->vb.inputs[i];
+ brw_emit_query_begin(brw);
- vs_inputs &= ~(1 << i);
- enabled[nr_enabled++] = input;
+ /* If the VS doesn't read any inputs (calculating vertex position from
+ * a state variable for some reason, for example), emit a single pad
+ * VERTEX_ELEMENT struct and bail.
+ *
+ * The stale VB state stays in place, but they don't do anything unless
+ * a VE loads from them.
+ */
+ if (brw->vb.nr_enabled == 0) {
+ BEGIN_BATCH(3, IGNORE_CLIPRECTS);
+ OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
+ OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
+ BRW_VE0_VALID |
+ (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
+ (0 << BRW_VE0_SRC_OFFSET_SHIFT));
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
+ ADVANCE_BATCH();
+ return;
}
- brw_emit_query_begin(brw);
-
/* Now emit VB and VEP state packets.
*
* This still defines a hardware VB for each input, even if they
* are interleaved or from the same VBO. TBD if this makes a
* performance difference.
*/
- BEGIN_BATCH(1 + nr_enabled * 4, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(1 + brw->vb.nr_enabled * 4, IGNORE_CLIPRECTS);
OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
- ((1 + nr_enabled * 4) - 2));
+ ((1 + brw->vb.nr_enabled * 4) - 2));
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) |
BRW_VB0_ACCESS_VERTEXDATA |
@@ -524,15 +547,15 @@ static void brw_emit_vertices(struct brw_context *brw)
input->offset + input->element_size);
}
} else
- OUT_BATCH(brw->vb.max_index);
+ OUT_BATCH(input->count);
OUT_BATCH(0); /* Instance data step rate */
}
ADVANCE_BATCH();
- BEGIN_BATCH(1 + nr_enabled * 2, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr_enabled * 2) - 2));
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ BEGIN_BATCH(1 + brw->vb.nr_enabled * 2, IGNORE_CLIPRECTS);
+ OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2));
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
uint32_t format = get_surface_type(input->glarray->Type,
input->glarray->Size,
input->glarray->Format,
@@ -589,17 +612,20 @@ static void brw_prepare_indices(struct brw_context *brw)
dri_bo *bo = NULL;
struct gl_buffer_object *bufferobj;
GLuint offset;
+ GLuint ib_type_size;
if (index_buffer == NULL)
return;
- ib_size = get_size(index_buffer->type) * index_buffer->count;
+ ib_type_size = get_size(index_buffer->type);
+ ib_size = ib_type_size * index_buffer->count;
bufferobj = index_buffer->obj;;
/* Turn into a proper VBO:
*/
if (!bufferobj->Name) {
-
+ brw->ib.start_vertex_offset = 0;
+
/* Get new bufferobj, offset:
*/
get_space(brw, ib_size, &bo, &offset);
@@ -615,6 +641,7 @@ static void brw_prepare_indices(struct brw_context *brw)
}
} else {
offset = (GLuint) (unsigned long) index_buffer->ptr;
+ brw->ib.start_vertex_offset = 0;
/* If the index buffer isn't aligned to its element size, we have to
* rebase it into a temporary.
@@ -635,39 +662,62 @@ static void brw_prepare_indices(struct brw_context *brw)
bo = intel_bufferobj_buffer(intel, intel_buffer_object(bufferobj),
INTEL_READ);
dri_bo_reference(bo);
+
+ /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading
+ * the index buffer state when we're just moving the start index
+ * of our drawing.
+ */
+ brw->ib.start_vertex_offset = offset / ib_type_size;
+ offset = 0;
+ ib_size = bo->size;
}
}
- dri_bo_unreference(brw->ib.bo);
- brw->ib.bo = bo;
- brw->ib.offset = offset;
+ if (brw->ib.bo != bo ||
+ brw->ib.offset != offset ||
+ brw->ib.size != ib_size)
+ {
+ drm_intel_bo_unreference(brw->ib.bo);
+ brw->ib.bo = bo;
+ brw->ib.offset = offset;
+ brw->ib.size = ib_size;
+
+ brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
+ } else {
+ drm_intel_bo_unreference(bo);
+ }
brw_add_validated_bo(brw, brw->ib.bo);
}
-static void brw_emit_indices(struct brw_context *brw)
+const struct brw_tracked_state brw_indices = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_INDICES,
+ .cache = 0,
+ },
+ .prepare = brw_prepare_indices,
+};
+
+static void brw_emit_index_buffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
const struct _mesa_index_buffer *index_buffer = brw->ib.ib;
- GLuint ib_size;
if (index_buffer == NULL)
return;
- ib_size = get_size(index_buffer->type) * index_buffer->count - 1;
-
/* Emit the indexbuffer packet:
*/
{
struct brw_indexbuffer ib;
memset(&ib, 0, sizeof(ib));
-
+
ib.header.bits.opcode = CMD_INDEX_BUFFER;
ib.header.bits.length = sizeof(ib)/4 - 2;
ib.header.bits.index_format = get_index_type(index_buffer->type);
ib.header.bits.cut_index_enable = 0;
-
BEGIN_BATCH(4, IGNORE_CLIPRECTS);
OUT_BATCH( ib.header.dword );
@@ -676,18 +726,17 @@ static void brw_emit_indices(struct brw_context *brw)
brw->ib.offset);
OUT_RELOC(brw->ib.bo,
I915_GEM_DOMAIN_VERTEX, 0,
- brw->ib.offset + ib_size);
+ brw->ib.offset + brw->ib.size);
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
}
-const struct brw_tracked_state brw_indices = {
+const struct brw_tracked_state brw_index_buffer = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH | BRW_NEW_INDICES,
+ .brw = BRW_NEW_BATCH | BRW_NEW_INDEX_BUFFER,
.cache = 0,
},
- .prepare = brw_prepare_indices,
- .emit = brw_emit_indices,
+ .emit = brw_emit_index_buffer,
};
diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c
index c53efba599..1df561386e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.c
+++ b/src/mesa/drivers/dri/i965/brw_eu.c
@@ -62,7 +62,7 @@ void brw_set_predicate_control( struct brw_compile *p, GLuint pc )
void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional )
{
- p->current->header.destreg__conditonalmod = conditional;
+ p->current->header.destreg__conditionalmod = conditional;
}
void brw_set_access_mode( struct brw_compile *p, GLuint access_mode )
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 2412014248..241cdc33f8 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -481,8 +481,8 @@ static struct brw_instruction *next_insn( struct brw_compile *p,
/* Reset this one-shot flag:
*/
- if (p->current->header.destreg__conditonalmod) {
- p->current->header.destreg__conditonalmod = 0;
+ if (p->current->header.destreg__conditionalmod) {
+ p->current->header.destreg__conditionalmod = 0;
p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
}
@@ -679,7 +679,7 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
assert(if_insn->header.opcode == BRW_OPCODE_IF);
if_insn->bits3.if_else.jump_count = br * (insn - if_insn);
- if_insn->bits3.if_else.pop_count = 1;
+ if_insn->bits3.if_else.pop_count = 0;
if_insn->bits3.if_else.pad0 = 0;
}
@@ -871,7 +871,7 @@ void brw_CMP(struct brw_compile *p,
{
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_CMP);
- insn->header.destreg__conditonalmod = conditional;
+ insn->header.destreg__conditionalmod = conditional;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_src1(insn, src1);
@@ -915,7 +915,7 @@ void brw_math( struct brw_compile *p,
* instructions.
*/
insn->header.predicate_control = 0;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -952,7 +952,7 @@ void brw_math_16( struct brw_compile *p,
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
insn = next_insn(p, BRW_OPCODE_SEND);
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -969,7 +969,7 @@ void brw_math_16( struct brw_compile *p,
*/
insn = next_insn(p, BRW_OPCODE_SEND);
insn->header.compression_control = BRW_COMPRESSION_2NDHALF;
- insn->header.destreg__conditonalmod = msg_reg_nr+1;
+ insn->header.destreg__conditionalmod = msg_reg_nr+1;
brw_set_dest(insn, offset(dest,1));
brw_set_src0(insn, src);
@@ -1016,7 +1016,7 @@ void brw_dp_WRITE_16( struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -1062,7 +1062,7 @@ void brw_dp_READ_16( struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest); /* UW? */
brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
@@ -1116,7 +1116,7 @@ void brw_dp_READ_4( struct brw_compile *p,
insn->header.predicate_control = BRW_PREDICATE_NONE;
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
insn->header.mask_control = BRW_MASK_DISABLE;
/* cast dest to a uword[8] vector */
@@ -1190,7 +1190,7 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
insn->header.predicate_control = BRW_PREDICATE_NONE;
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
insn->header.mask_control = BRW_MASK_DISABLE;
/*insn->header.access_mode = BRW_ALIGN_16;*/
@@ -1224,7 +1224,7 @@ void brw_fb_WRITE(struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
@@ -1322,7 +1322,7 @@ void brw_SAMPLE(struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
@@ -1375,7 +1375,7 @@ void brw_urb_WRITE(struct brw_compile *p,
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_urb_message(p->brw,
insn,
@@ -1410,7 +1410,7 @@ void brw_ff_sync(struct brw_compile *p,
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_ff_sync_message(p->brw,
insn,
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 980eac7646..a9b2aa2eac 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -101,7 +101,7 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c,
BRW_URB_SWIZZLE_NONE);
}
-void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
+static void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
{
struct brw_compile *p = &c->func;
brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index b5f6371c82..bc0f076073 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -113,7 +113,7 @@ struct brw_sf_unit_key {
unsigned int nr_urb_entries, urb_size, sfsize;
- GLenum front_face, cull_face;
+ GLenum front_face, cull_face, provoking_vertex;
unsigned scissor:1;
unsigned line_smooth:1;
unsigned point_sprite:1;
@@ -153,6 +153,9 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
key->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
key->point_attenuated = ctx->Point._Attenuated;
+ /* _NEW_LIGHT */
+ key->provoking_vertex = ctx->Light.ProvokingVertex;
+
key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
}
@@ -284,9 +287,15 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
/* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
*/
- sf.sf7.trifan_pv = 2;
- sf.sf7.linestrip_pv = 1;
- sf.sf7.tristrip_pv = 2;
+ if (key->provoking_vertex == GL_LAST_VERTEX_CONVENTION) {
+ sf.sf7.trifan_pv = 2;
+ sf.sf7.linestrip_pv = 1;
+ sf.sf7.tristrip_pv = 2;
+ } else {
+ sf.sf7.trifan_pv = 1;
+ sf.sf7.linestrip_pv = 0;
+ sf.sf7.tristrip_pv = 0;
+ }
sf.sf7.line_last_pixel_enable = 0;
/* Set bias for OpenGL rasterization rules:
@@ -300,6 +309,9 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
&sf, sizeof(sf),
NULL, NULL);
+ /* STATE_PREFETCH command description describes this state as being
+ * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
+ */
/* Emit SF program relocation */
dri_bo_emit_reloc(bo,
I915_GEM_DOMAIN_INSTRUCTION, 0,
@@ -340,6 +352,7 @@ static void upload_sf_unit( struct brw_context *brw )
const struct brw_tracked_state brw_sf_unit = {
.dirty = {
.mesa = (_NEW_POLYGON |
+ _NEW_LIGHT |
_NEW_LINE |
_NEW_POINT |
_NEW_SCISSOR |
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index bf9f6cae55..78572356a3 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -92,6 +92,7 @@ const struct brw_tracked_state brw_clear_batch_cache;
const struct brw_tracked_state brw_drawing_rect;
const struct brw_tracked_state brw_indices;
const struct brw_tracked_state brw_vertices;
+const struct brw_tracked_state brw_index_buffer;
/**
* Use same key for WM and VS surfaces.
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 38d9dd8991..95d42d2dcc 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -94,6 +94,7 @@ const struct brw_tracked_state *atoms[] =
&brw_drawing_rect,
&brw_indices,
+ &brw_index_buffer,
&brw_vertices,
&brw_constant_buffer
@@ -208,6 +209,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_PSP),
DEFINE_BIT(BRW_NEW_FENCE),
DEFINE_BIT(BRW_NEW_INDICES),
+ DEFINE_BIT(BRW_NEW_INDEX_BUFFER),
DEFINE_BIT(BRW_NEW_VERTICES),
DEFINE_BIT(BRW_NEW_BATCH),
DEFINE_BIT(BRW_NEW_DEPTH_BUFFER),
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 8ba7eb27b3..a6de09207b 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -1200,7 +1200,7 @@ struct brw_instruction
GLuint predicate_control:4;
GLuint predicate_inverse:1;
GLuint execution_size:3;
- GLuint destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
+ GLuint destreg__conditionalmod:4; /* destreg - send, conditionalmod - others */
GLuint pad0:2;
GLuint debug_control:1;
GLuint saturate:1;
@@ -1228,7 +1228,9 @@ struct brw_instruction
GLuint dest_reg_type:3;
GLuint src0_reg_file:2;
GLuint src0_reg_type:3;
- GLuint pad:6;
+ GLuint src1_reg_file:2; /* 0x00000c00 */
+ GLuint src1_reg_type:3; /* 0x00007000 */
+ GLuint pad:1;
GLint dest_indirect_offset:10; /* offset against the deref'd address reg */
GLuint dest_subreg_nr:3; /* subnr for the address reg a0.x */
GLuint dest_horiz_stride:2;
@@ -1243,7 +1245,7 @@ struct brw_instruction
GLuint src0_reg_type:3;
GLuint src1_reg_file:2;
GLuint src1_reg_type:3;
- GLuint pad0:1;
+ GLuint pad:1;
GLuint dest_writemask:4;
GLuint dest_subreg_nr:1;
GLuint dest_reg_nr:8;
@@ -1348,7 +1350,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad:1;
+ GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@@ -1363,7 +1365,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad0:1;
+ GLuint src1_address_mode:1;
GLuint src1_swz_z:2;
GLuint src1_swz_w:2;
GLuint pad1:1;
@@ -1377,7 +1379,7 @@ struct brw_instruction
GLuint src1_subreg_nr:3;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad0:1;
+ GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@@ -1565,6 +1567,7 @@ struct brw_instruction
GLint d;
GLuint ud;
+ float f;
} bits3;
};
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 7f9b253534..1d2e953eb1 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -65,11 +65,6 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
if (mt->compressed) {
mt->pitch = ALIGN(mt->width0, align_w);
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp;
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
- } else {
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp;
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
}
if (mt->first_level != mt->last_level) {
@@ -90,6 +85,14 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch);
+ if (mt->compressed) {
+ qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp;
+ mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
+ } else {
+ qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp;
+ mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
+ }
+
for (level = mt->first_level; level <= mt->last_level; level++) {
GLuint img_height;
GLuint nr_images = 6;
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 514f15d5e3..83167b9258 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -68,6 +68,7 @@ static void release_tmps( struct brw_vs_compile *c )
static void brw_vs_alloc_regs( struct brw_vs_compile *c )
{
GLuint i, reg = 0, mrf;
+ int attributes_in_vue;
/* Determine whether to use a real constant buffer or use a block
* of GRF registers for constants. The later is faster but only
@@ -128,6 +129,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
reg++;
}
}
+ /* If there are no inputs, we'll still be reading one attribute's worth
+ * because it's required -- see urb_read_length setting.
+ */
+ if (c->nr_inputs == 0)
+ reg++;
/* Allocate outputs. The non-position outputs go straight into message regs.
*/
@@ -220,11 +226,22 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
* vertex urb, so is half the amount:
*/
c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
+ /* Setting this field to 0 leads to undefined behavior according to the
+ * the VS_STATE docs. Our VUEs will always have at least one attribute
+ * sitting in them, even if it's padding.
+ */
+ if (c->prog_data.urb_read_length == 0)
+ c->prog_data.urb_read_length = 1;
+
+ /* The VS VUEs are shared by VF (outputting our inputs) and VS, so size
+ * them to fit the biggest thing they need to.
+ */
+ attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
if (BRW_IS_IGDNG(c->func.brw))
- c->prog_data.urb_entry_size = (c->nr_outputs + 6 + 3) / 4;
+ c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
else
- c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
+ c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
c->prog_data.total_grf = reg;
@@ -1245,9 +1262,30 @@ post_vs_emit( struct brw_vs_compile *c,
/* patch up the END code to jump past subroutines, etc */
offset = last_inst - end_inst;
- brw_set_src1(end_inst, brw_imm_d(offset * 16));
+ if (offset > 1) {
+ brw_set_src1(end_inst, brw_imm_d(offset * 16));
+ } else {
+ end_inst->header.opcode = BRW_OPCODE_NOP;
+ }
}
+static uint32_t
+get_predicate(uint32_t swizzle)
+{
+ switch (swizzle) {
+ case SWIZZLE_XXXX:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_X;
+ case SWIZZLE_YYYY:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_Y;
+ case SWIZZLE_ZZZZ:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_Z;
+ case SWIZZLE_WWWW:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_W;
+ default:
+ _mesa_problem(NULL, "Unexpected predicate: 0x%08x\n", swizzle);
+ return BRW_PREDICATE_NORMAL;
+ }
+}
/* Emit the vertex program instructions here.
*/
@@ -1266,7 +1304,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
GLuint file;
if (INTEL_DEBUG & DEBUG_VS) {
- _mesa_printf("vs-emit:\n");
+ _mesa_printf("vs-mesa:\n");
_mesa_print_program(&c->vp->program.Base);
_mesa_printf("\n");
}
@@ -1453,7 +1491,10 @@ void brw_vs_emit(struct brw_vs_compile *c )
break;
case OPCODE_IF:
assert(if_depth < MAX_IF_DEPTH);
- if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
+ if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
+ if_inst[if_depth]->header.predicate_control =
+ get_predicate(inst->DstReg.CondSwizzle);
+ if_depth++;
break;
case OPCODE_ELSE:
if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
@@ -1541,6 +1582,19 @@ void brw_vs_emit(struct brw_vs_compile *c )
"unknown");
}
+ /* Set the predication update on the last instruction of the native
+ * instruction sequence.
+ *
+ * This would be problematic if it was set on a math instruction,
+ * but that shouldn't be the case with the current GLSL compiler.
+ */
+ if (inst->CondUpdate) {
+ struct brw_instruction *hw_insn = &p->store[p->nr_insn - 1];
+
+ assert(hw_insn->header.destreg__conditionalmod == 0);
+ hw_insn->header.destreg__conditionalmod = BRW_CONDITIONAL_NZ;
+ }
+
if ((inst->DstReg.File == PROGRAM_OUTPUT)
&& (inst->DstReg.Index != VERT_RESULT_HPOS)
&& c->output_regs[inst->DstReg.Index].used_in_src) {
@@ -1578,4 +1632,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
emit_vertex_write(c);
post_vs_emit(c, end_inst, last_inst);
+
+ if (INTEL_DEBUG & DEBUG_VS) {
+ int i;
+
+ _mesa_printf("vs-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 14e05be4f6..2292de94c4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -41,13 +41,13 @@ GLuint brw_wm_nr_args( GLuint opcode )
{
switch (opcode) {
case WM_FRONTFACING:
- return 0;
case WM_PIXELXY:
+ return 0;
case WM_CINTERP:
case WM_WPOSXY:
+ case WM_DELTAXY:
return 1;
case WM_LINTERP:
- case WM_DELTAXY:
case WM_PIXELW:
return 2;
case WM_FB_WRITE:
@@ -171,9 +171,11 @@ static void do_wm_prog( struct brw_context *brw,
* differently from "simple" shaders.
*/
if (fp->isGLSL) {
+ c->dispatch_width = 8;
brw_wm_glsl_emit(brw, c);
}
else {
+ c->dispatch_width = 16;
brw_wm_non_glsl_emit(brw, c);
}
@@ -202,6 +204,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* BRW_NEW_FRAGMENT_PROGRAM */
const struct brw_fragment_program *fp =
(struct brw_fragment_program *)brw->fragment_program;
+ GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
GLuint lookup = 0;
GLuint line_aa;
GLuint i;
@@ -263,6 +266,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
brw_wm_lookup_iz(line_aa,
lookup,
+ uses_depth,
key);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ba497432c6..ae98b5492d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -260,6 +260,7 @@ struct brw_wm_compile {
GLuint tmp_index;
GLuint tmp_max;
GLuint subroutines[BRW_WM_MAX_SUBROUTINE];
+ GLuint dispatch_width;
/** we may need up to 3 constants per instruction (if use_const_buffer) */
struct {
@@ -292,6 +293,7 @@ void brw_wm_print_program( struct brw_wm_compile *c,
void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
+ GLboolean ps_uses_depth,
struct brw_wm_prog_key *key );
GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 9f82916c02..b3cf524c63 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -65,8 +65,7 @@ static INLINE struct brw_reg sechalf( struct brw_reg reg )
static void emit_pixel_xy(struct brw_compile *p,
const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0)
+ GLuint mask)
{
struct brw_reg r1 = brw_vec1_grf(1, 0);
struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
@@ -98,8 +97,7 @@ static void emit_pixel_xy(struct brw_compile *p,
static void emit_delta_xy(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1)
+ const struct brw_reg *arg0)
{
struct brw_reg r1 = brw_vec1_grf(1, 0);
@@ -545,16 +543,18 @@ static void emit_dp3( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
- brw_MAC(p, dst[0], arg0[2], arg1[2]);
+ brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
brw_set_saturate(p, 0);
}
@@ -565,17 +565,19 @@ static void emit_dp4( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
brw_MAC(p, brw_null_reg(), arg0[2], arg1[2]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
- brw_MAC(p, dst[0], arg0[3], arg1[3]);
+ brw_MAC(p, dst[dst_chan], arg0[3], arg1[3]);
brw_set_saturate(p, 0);
}
@@ -632,18 +634,19 @@ static void emit_math1( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
- // function == BRW_MATH_FUNCTION_SINCOS);
-
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
brw_MOV(p, brw_message_reg(2), arg0[0]);
/* Send two messages to perform all 16 operations:
*/
brw_math_16(p,
- dst[0],
+ dst[dst_chan],
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
@@ -659,10 +662,12 @@ static void emit_math2( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1)
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_push_insn_state(p);
@@ -681,7 +686,7 @@ static void emit_math2( struct brw_compile *p,
*/
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_math(p,
- dst[0],
+ dst[dst_chan],
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
@@ -691,7 +696,7 @@ static void emit_math2( struct brw_compile *p,
brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
brw_math(p,
- offset(dst[0],1),
+ offset(dst[dst_chan],1),
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
4,
@@ -1194,11 +1199,11 @@ void brw_wm_emit( struct brw_wm_compile *c )
/* Generated instructions for calculating triangle interpolants:
*/
case WM_PIXELXY:
- emit_pixel_xy(p, dst, dst_flags, args[0]);
+ emit_pixel_xy(p, dst, dst_flags);
break;
case WM_DELTAXY:
- emit_delta_xy(p, dst, dst_flags, args[0], args[1]);
+ emit_delta_xy(p, dst, dst_flags, args[0]);
break;
case WM_WPOSXY:
@@ -1385,4 +1390,13 @@ void brw_wm_emit( struct brw_wm_compile *c )
inst->dst[i]->hw_reg,
inst->dst[i]->spill_slot);
}
+
+ if (INTEL_DEBUG & DEBUG_WM) {
+ int i;
+
+ _mesa_printf("wm-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index b9e8dd2e96..5dc076a825 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -226,9 +226,42 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
0, 0, 0, /* tex unit, target, shadow */
src0, src1, src2);
}
-
+/* Many Mesa opcodes produce the same value across all the result channels.
+ * We'd rather not have to support that splatting in the opcode implementations,
+ * and brw_wm_pass*.c wants to optimize them out by shuffling references around
+ * anyway. We can easily get both by emitting the opcode to one channel, and
+ * then MOVing it to the others, which brw_wm_pass*.c already understands.
+ */
+static struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
+ const struct prog_instruction *inst0)
+{
+ struct prog_instruction *inst;
+ unsigned int dst_chan;
+ unsigned int other_channel_mask;
+
+ if (inst0->DstReg.WriteMask == 0)
+ return NULL;
+
+ dst_chan = _mesa_ffs(inst0->DstReg.WriteMask) - 1;
+ inst = get_fp_inst(c);
+ *inst = *inst0;
+ inst->DstReg.WriteMask = 1 << dst_chan;
+
+ other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
+ if (other_channel_mask != 0) {
+ inst = emit_op(c,
+ OPCODE_MOV,
+ dst_mask(inst0->DstReg, other_channel_mask),
+ 0,
+ src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
+ src_undef(),
+ src_undef());
+ }
+ return inst;
+}
+
/***********************************************************************
* Special instructions for interpolation and other tasks
@@ -376,14 +409,6 @@ static void emit_interp( struct brw_wm_compile *c,
}
break;
case FRAG_ATTRIB_FOGC:
- /* The FOGC input is really special. When a program uses glFogFragCoord,
- * the results returned are supposed to be (f,0,0,1). But for Mesa GLSL,
- * the glFrontFacing and glPointCoord values are also stashed in FOGC.
- * So, write the interpolated fog value to X, then either 0, 1, or the
- * stashed values to Y, Z, W. Note that this means that
- * glFogFragCoord.yzw can be wrong in those cases!
- */
-
/* Interpolate the fog coordinate */
emit_op(c,
WM_PINTERP,
@@ -393,26 +418,40 @@ static void emit_interp( struct brw_wm_compile *c,
deltas,
get_pixel_w(c));
- /* Move the front facing value into FOGC.y if it's needed. */
- if (c->fp->program.UsesFrontFacing) {
- emit_op(c,
- WM_FRONTFACING,
- dst_mask(dst, WRITEMASK_Y),
- 0,
- src_undef(),
- src_undef(),
- src_undef());
- } else {
- emit_op(c,
- OPCODE_MOV,
- dst_mask(dst, WRITEMASK_Y),
- 0,
- src_swizzle1(interp, SWIZZLE_ZERO),
- src_undef(),
- src_undef());
- }
+ emit_op(c,
+ OPCODE_MOV,
+ dst_mask(dst, WRITEMASK_YZW),
+ 0,
+ src_swizzle(interp,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ONE),
+ src_undef(),
+ src_undef());
+ break;
+
+ case FRAG_ATTRIB_FACE:
+ /* XXX review/test this case */
+ emit_op(c,
+ WM_FRONTFACING,
+ dst_mask(dst, WRITEMASK_X),
+ 0,
+ src_undef(),
+ src_undef(),
+ src_undef());
+ break;
+
+ case FRAG_ATTRIB_PNTC:
+ /* XXX review/test this case */
+ emit_op(c,
+ WM_PINTERP,
+ dst_mask(dst, WRITEMASK_XY),
+ 0,
+ interp,
+ deltas,
+ get_pixel_w(c));
- /* Should do the PointCoord thing here. */
emit_op(c,
OPCODE_MOV,
dst_mask(dst, WRITEMASK_ZW),
@@ -425,6 +464,7 @@ static void emit_interp( struct brw_wm_compile *c,
src_undef(),
src_undef());
break;
+
default:
emit_op(c,
WM_PINTERP,
@@ -683,7 +723,7 @@ static void precalc_tex( struct brw_wm_compile *c,
/* tmp0 = 1 / tmp1 */
emit_op(c, OPCODE_RCP,
- tmp0,
+ dst_mask(tmp0, WRITEMASK_X),
0,
tmp1src,
src_undef(),
@@ -694,7 +734,7 @@ static void precalc_tex( struct brw_wm_compile *c,
tmpcoord,
0,
src0,
- tmp0src,
+ src_swizzle1(tmp0src, SWIZZLE_X),
src_undef());
release_temp(c, tmp0);
@@ -717,7 +757,11 @@ static void precalc_tex( struct brw_wm_compile *c,
tmpcoord,
0,
inst->SrcReg[0],
- scale,
+ src_swizzle(scale,
+ SWIZZLE_X,
+ SWIZZLE_Y,
+ SWIZZLE_ONE,
+ SWIZZLE_ONE),
src_undef());
coord = src_reg_from_dst(tmpcoord);
@@ -1134,9 +1178,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
break;
case OPCODE_PRINT:
break;
-
default:
- emit_insn(c, inst);
+ if (brw_wm_is_scalar_result(inst->Opcode))
+ emit_scalar_insn(c, inst);
+ else
+ emit_insn(c, inst);
break;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 85a4237d5a..a5b18ec7d7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -10,6 +10,9 @@ enum _subroutine {
SUB_NOISE1, SUB_NOISE2, SUB_NOISE3, SUB_NOISE4
};
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
+ const struct prog_instruction *inst,
+ GLuint component);
/**
* Determine if the given fragment program uses GLSL features such
@@ -22,6 +25,7 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
for (i = 0; i < fp->Base.NumInstructions; i++) {
const struct prog_instruction *inst = &fp->Base.Instructions[i];
switch (inst->Opcode) {
+ case OPCODE_ARL:
case OPCODE_IF:
case OPCODE_ENDIF:
case OPCODE_CAL:
@@ -130,19 +134,6 @@ static void set_reg(struct brw_wm_compile *c, int file, int index,
c->wm_regs[file][index][component].inited = GL_TRUE;
}
-/**
- * Examine instruction's write mask to find index of first component
- * enabled for writing.
- */
-static int get_scalar_dst_index(const struct prog_instruction *inst)
-{
- int i;
- for (i = 0; i < 4; i++)
- if (inst->DstReg.WriteMask & (1<<i))
- break;
- return i;
-}
-
static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
{
struct brw_reg reg;
@@ -402,6 +393,27 @@ static void prealloc_reg(struct brw_wm_compile *c)
prealloc_grf(c, 126);
prealloc_grf(c, 127);
+ for (i = 0; i < c->nr_fp_insns; i++) {
+ const struct prog_instruction *inst = &c->prog_instructions[i];
+ struct brw_reg dst[4];
+
+ switch (inst->Opcode) {
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ /* Allocate the channels of texture results contiguously,
+ * since they are written out that way by the sampler unit.
+ */
+ for (j = 0; j < 4; j++) {
+ dst[j] = get_dst_reg(c, inst, j);
+ if (j != 0)
+ assert(dst[j].nr == dst[j - 1].nr + 1);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
/* An instruction may reference up to three constants.
* They'll be found in these registers.
* XXX alloc these on demand!
@@ -639,23 +651,6 @@ static void invoke_subroutine( struct brw_wm_compile *c,
}
}
-static void emit_abs( struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- int i;
- struct brw_compile *p = &c->func;
- brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
- for (i = 0; i < 4; i++) {
- if (inst->DstReg.WriteMask & (1<<i)) {
- struct brw_reg src, dst;
- dst = get_dst_reg(c, inst, i);
- src = get_src_reg(c, inst, 0, i);
- brw_MOV(p, dst, brw_abs(src));
- }
- }
- brw_set_saturate(p, 0);
-}
-
static void emit_trunc( struct brw_wm_compile *c,
const struct prog_instruction *inst)
{
@@ -1031,12 +1026,20 @@ static void emit_dp3(struct brw_wm_compile *c,
struct brw_reg src0[3], src1[3], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 3; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
@@ -1050,11 +1053,19 @@ static void emit_dp4(struct brw_wm_compile *c,
struct brw_reg src0[4], src1[4], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 4; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
@@ -1069,11 +1080,19 @@ static void emit_dph(struct brw_wm_compile *c,
struct brw_reg src0[4], src1[4], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 4; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_MAC(p, dst, src0[2], src1[2]);
@@ -1091,37 +1110,28 @@ static void emit_math1(struct brw_wm_compile *c,
const struct prog_instruction *inst, GLuint func)
{
struct brw_compile *p = &c->func;
- struct brw_reg src0, dst, tmp;
- const int mark = mark_tmps( c );
- int i;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
- tmp = alloc_tmp(c);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
/* Get first component of source register */
+ dst = get_dst_reg(c, inst, dst_chan);
src0 = get_src_reg(c, inst, 0, 0);
- /* tmp = func(src0) */
brw_MOV(p, brw_message_reg(2), src0);
brw_math(p,
- tmp,
+ dst,
func,
(inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
brw_null_reg(),
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
-
- /*tmp.dw1.bits.swizzle = SWIZZLE_XXXX;*/
-
- /* replicate tmp value across enabled dest channels */
- for (i = 0; i < 4; i++) {
- if (inst->DstReg.WriteMask & (1 << i)) {
- dst = get_dst_reg(c, inst, i);
- brw_MOV(p, dst, tmp);
- }
- }
-
- release_tmps(c, mark);
}
static void emit_rcp(struct brw_wm_compile *c,
@@ -1192,24 +1202,6 @@ static void emit_arl(struct brw_wm_compile *c,
brw_set_saturate(p, 0);
}
-static void emit_sub(struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- struct brw_compile *p = &c->func;
- struct brw_reg src0, src1, dst;
- GLuint mask = inst->DstReg.WriteMask;
- int i;
- brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
- for (i = 0 ; i < 4; i++) {
- if (mask & (1<<i)) {
- dst = get_dst_reg(c, inst, i);
- src0 = get_src_reg(c, inst, 0, i);
- src1 = get_src_reg_imm(c, inst, 1, i);
- brw_ADD(p, dst, src0, negate(src1));
- }
- }
- brw_set_saturate(p, 0);
-}
static void emit_mul(struct brw_wm_compile *c,
const struct prog_instruction *inst)
@@ -1321,7 +1313,15 @@ static void emit_pow(struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
struct brw_reg dst, src0, src1;
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+ dst = get_dst_reg(c, inst, dst_chan);
src0 = get_src_reg_imm(c, inst, 0, 0);
src1 = get_src_reg_imm(c, inst, 1, 0);
@@ -2828,18 +2828,12 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case WM_FRONTFACING:
emit_frontfacing(c, inst);
break;
- case OPCODE_ABS:
- emit_abs(c, inst);
- break;
case OPCODE_ADD:
emit_add(c, inst);
break;
case OPCODE_ARL:
emit_arl(c, inst);
break;
- case OPCODE_SUB:
- emit_sub(c, inst);
- break;
case OPCODE_FRC:
emit_frc(c, inst);
break;
@@ -3032,8 +3026,14 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
post_wm_emit(c);
-}
+ if (INTEL_DEBUG & DEBUG_WM) {
+ _mesa_printf("wm-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
+}
/**
* Do GPU code generation for shaders that use GLSL features such as
diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.c b/src/mesa/drivers/dri/i965/brw_wm_iz.c
index 8fd067abe7..5e399ac62a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_iz.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_iz.c
@@ -122,6 +122,7 @@ const struct {
*/
void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
+ GLboolean ps_uses_depth,
struct brw_wm_prog_key *key )
{
GLuint reg = 2;
@@ -131,7 +132,7 @@ void brw_wm_lookup_iz( GLuint line_aa,
if (lookup & IZ_PS_COMPUTES_DEPTH_BIT)
key->computes_depth = 1;
- if (wm_iz_table[lookup].sd_present) {
+ if (wm_iz_table[lookup].sd_present || ps_uses_depth) {
key->source_depth_reg = reg;
reg += 2;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 92142764f5..6279258339 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -257,34 +257,6 @@ static void pass0_set_dst( struct brw_wm_compile *c,
}
-static void pass0_set_dst_scalar( struct brw_wm_compile *c,
- struct brw_wm_instruction *out,
- const struct prog_instruction *inst,
- GLuint writemask )
-{
- if (writemask) {
- const struct prog_dst_register *dst = &inst->DstReg;
- GLuint i;
-
- /* Compute only the first (X) value:
- */
- out->writemask = WRITEMASK_X;
- out->dst[0] = get_value(c);
-
- /* Update our tracking register file for all the components in
- * writemask:
- */
- for (i = 0; i < 4; i++) {
- if (writemask & (1<<i)) {
- pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[0]);
- }
- }
- }
- else
- out->writemask = 0;
-}
-
-
static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
struct prog_src_register src,
GLuint i )
@@ -363,10 +335,7 @@ translate_insn(struct brw_wm_compile *c,
/* Dst:
*/
- if (brw_wm_is_scalar_result(out->opcode))
- pass0_set_dst_scalar(c, out, inst, writemask);
- else
- pass0_set_dst(c, out, inst, writemask);
+ pass0_set_dst(c, out, inst, writemask);
}
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 0f87fc46a4..6aa36d10b1 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -196,6 +196,16 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
if (used == 0) {
batch->cliprect_mode = IGNORE_CLIPRECTS;
return;
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 2e95bd1013..979f202584 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -477,6 +477,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
BR13 |= BR13_565;
}
+ assert(irb->region->tiling != I915_TILING_Y);
+
#ifndef I915
if (irb->region->tiling != I915_TILING_NONE) {
CMD |= XY_DST_TILED;
@@ -571,6 +573,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
+ assert(dst_pitch > 0);
if (w < 0 || h < 0)
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 4abb525f78..46f1a7f720 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -38,6 +38,7 @@
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "i830_dri.h"
@@ -513,7 +514,7 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
* each of N places that do rendering. This has worse performances,
* but it is much easier to get correct.
*/
- if (intel->is_front_buffer_rendering) {
+ if (!intel->is_front_buffer_rendering) {
intel->front_buffer_dirty = GL_FALSE;
}
}
@@ -529,7 +530,27 @@ intelFlush(GLcontext * ctx)
static void
intel_glFlush(GLcontext *ctx)
{
+ struct intel_context *intel = intel_context(ctx);
+
intel_flush(ctx, GL_TRUE);
+
+ /* We're using glFlush as an indicator that a frame is done, which is
+ * what DRI2 does before calling SwapBuffers (and means we should catch
+ * people doing front-buffer rendering, as well)..
+ *
+ * Wait for the swapbuffers before the one we just emitted, so we don't
+ * get too many swaps outstanding for apps that are GPU-heavy but not
+ * CPU-heavy.
+ *
+ * Unfortunately, we don't have a handle to the batch containing the swap,
+ * and getting our hands on that doesn't seem worth it, so we just us the
+ * first batch we emitted after the last swap.
+ */
+ if (intel->first_post_swapbuffers_batch != NULL) {
+ drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+ drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
+ }
}
void
@@ -692,6 +713,8 @@ intelInitContext(struct intel_context *intel,
_swrast_allow_pixel_fog(ctx, GL_FALSE);
_swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _mesa_meta_init(ctx);
+
intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
intel->hw_stipple = 1;
@@ -752,7 +775,7 @@ intelInitContext(struct intel_context *intel,
if (intel->use_texture_tiling &&
!intel->intelScreen->kernel_exec_fencing) {
fprintf(stderr, "No kernel support for execution fencing, "
- "disabling texture tiling");
+ "disabling texture tiling\n");
intel->use_texture_tiling = GL_FALSE;
}
intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
@@ -795,6 +818,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
INTEL_FIREVERTICES(intel);
+ _mesa_meta_free(&intel->ctx);
+
meta_destroy_metaops(&intel->meta);
intel->vtbl.destroy(intel);
@@ -814,6 +839,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb = NULL;
dri_bo_unreference(intel->prim.vb_bo);
intel->prim.vb_bo = NULL;
+ dri_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
if (release_texture_heaps) {
/* Nothing is currently done here to free texture heaps;
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 08bea88c95..0d9db5eb1d 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -80,9 +80,13 @@ extern void intelFallback(struct intel_context *intel, GLuint bit,
#define INTEL_MAX_FIXUP 64
+
+/**
+ * intel_context is derived from Mesa's context class: GLcontext.
+ */
struct intel_context
{
- GLcontext ctx; /* the parent class */
+ GLcontext ctx; /**< base class, must be first field */
struct
{
@@ -178,6 +182,7 @@ struct intel_context
GLboolean ttm;
struct intel_batchbuffer *batch;
+ drm_intel_bo *first_post_swapbuffers_batch;
GLboolean no_batch_wrap;
unsigned batch_id;
@@ -307,7 +312,7 @@ struct intel_context
__DRIdrawablePrivate *driReadDrawable;
__DRIscreenPrivate *driScreen;
intelScreenPrivate *intelScreen;
- volatile struct drm_i915_sarea *sarea;
+ volatile drm_i915_sarea_t *sarea;
GLuint lastStamp;
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 6a68021c69..aa3d704f29 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -48,6 +48,7 @@
#define need_GL_EXT_framebuffer_blit
#define need_GL_EXT_gpu_program_parameters
#define need_GL_EXT_point_parameters
+#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
#define need_GL_APPLE_vertex_array_object
@@ -93,6 +94,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
{ "GL_EXT_packed_depth_stencil", NULL },
+ { "GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
{ "GL_EXT_texture_edge_clamp", NULL },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 666893596e..804c034840 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -35,6 +35,7 @@
#include "main/context.h"
#include "main/texformat.h"
#include "main/texrender.h"
+#include "drivers/common/meta.h"
#include "intel_context.h"
#include "intel_buffers.h"
@@ -700,74 +701,6 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
/**
- * Called from glBlitFramebuffer().
- * For now, we're doing an approximation with glCopyPixels().
- * XXX we need to bypass all the per-fragment operations, except scissor.
- */
-static void
-intel_blit_framebuffer(GLcontext *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- const GLfloat xZoomSave = ctx->Pixel.ZoomX;
- const GLfloat yZoomSave = ctx->Pixel.ZoomY;
- GLsizei width, height;
- GLfloat xFlip = 1.0F, yFlip = 1.0F;
-
- if (srcX1 < srcX0) {
- GLint tmp = srcX1;
- srcX1 = srcX0;
- srcX0 = tmp;
- xFlip = -1.0F;
- }
-
- if (srcY1 < srcY0) {
- GLint tmp = srcY1;
- srcY1 = srcY0;
- srcY0 = tmp;
- yFlip = -1.0F;
- }
-
- width = srcX1 - srcX0;
- height = srcY1 - srcY0;
-
- ctx->Pixel.ZoomX = xFlip * (dstX1 - dstX0) / (srcX1 - srcY0);
- ctx->Pixel.ZoomY = yFlip * (dstY1 - dstY0) / (srcY1 - srcY0);
-
- if (ctx->Pixel.ZoomX < 0.0F) {
- dstX0 = MAX2(dstX0, dstX1);
- }
- else {
- dstX0 = MIN2(dstX0, dstX1);
- }
-
- if (ctx->Pixel.ZoomY < 0.0F) {
- dstY0 = MAX2(dstY0, dstY1);
- }
- else {
- dstY0 = MIN2(dstY0, dstY1);
- }
-
- if (mask & GL_COLOR_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_COLOR);
- }
- if (mask & GL_DEPTH_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_DEPTH);
- }
- if (mask & GL_STENCIL_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_STENCIL);
- }
-
- ctx->Pixel.ZoomX = xZoomSave;
- ctx->Pixel.ZoomY = yZoomSave;
-}
-
-
-/**
* Do one-time context initializations related to GL_EXT_framebuffer_object.
* Hook in device driver functions.
*/
@@ -782,5 +715,5 @@ intel_fbo_init(struct intel_context *intel)
intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
- intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
+ intel->ctx.Driver.BlitFramebuffer = _mesa_meta_blit_framebuffer;
}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
index 5d52335dee..ca796b3655 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
@@ -31,7 +31,7 @@
#include "main/state.h"
#include "main/mtypes.h"
#include "main/macros.h"
-#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
#include "intel_screen.h"
#include "intel_context.h"
@@ -97,162 +97,6 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
ctx->Color.BlendEnabled);
}
-#ifdef I915
-/* Doesn't work for overlapping regions. Could do a double copy or
- * just fallback.
- */
-static GLboolean
-do_texture_copypixels(GLcontext * ctx,
- GLint srcx, GLint srcy,
- GLsizei width, GLsizei height,
- GLint dstx, GLint dsty, GLenum type)
-{
- struct intel_context *intel = intel_context(ctx);
- struct intel_region *dst = intel_drawbuf_region(intel);
- struct intel_region *src = copypix_src_region(intel, type);
- GLenum src_format;
- GLenum src_type;
-
- DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__,
- srcx, srcy, width, height, dstx, dsty);
-
- if (!src || !dst || type != GL_COLOR)
- return GL_FALSE;
-
- if (ctx->_ImageTransferState) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- /* Can't handle overlapping regions. Don't have sufficient control
- * over rasterization to pull it off in-place. Punt on these for
- * now.
- *
- * XXX: do a copy to a temporary.
- */
- if (src->buffer == dst->buffer) {
- drm_clip_rect_t srcbox;
- drm_clip_rect_t dstbox;
- drm_clip_rect_t tmp;
-
- srcbox.x1 = srcx;
- srcbox.y1 = srcy;
- srcbox.x2 = srcx + width;
- srcbox.y2 = srcy + height;
-
- if (ctx->Pixel.ZoomX > 0) {
- dstbox.x1 = dstx;
- dstbox.x2 = dstx + width * ctx->Pixel.ZoomX;
- } else {
- dstbox.x1 = dstx + width * ctx->Pixel.ZoomX;
- dstbox.x2 = dstx;
- }
- if (ctx->Pixel.ZoomY > 0) {
- dstbox.y1 = dsty;
- dstbox.y2 = dsty + height * ctx->Pixel.ZoomY;
- } else {
- dstbox.y1 = dsty + height * ctx->Pixel.ZoomY;
- dstbox.y2 = dsty;
- }
-
- DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2);
- DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2,
- width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
-
- if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) {
- DBG("%s: regions overlap\n", __FUNCTION__);
- return GL_FALSE;
- }
- }
-
- intelFlush(&intel->ctx);
-
- intel->vtbl.install_meta_state(intel);
-
- /* Is this true? Also will need to turn depth testing on according
- * to state:
- */
- intel->vtbl.meta_no_stencil_write(intel);
- intel->vtbl.meta_no_depth_write(intel);
-
- /* Set the 3d engine to draw into the destination region:
- */
- intel->vtbl.meta_draw_region(intel, dst, intel->depth_region);
-
- intel->vtbl.meta_import_pixel_state(intel);
-
- if (src->cpp == 2) {
- src_format = GL_RGB;
- src_type = GL_UNSIGNED_SHORT_5_6_5;
- }
- else {
- src_format = GL_BGRA;
- src_type = GL_UNSIGNED_BYTE;
- }
-
- /* Set the frontbuffer up as a large rectangular texture.
- */
- if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0,
- src->pitch,
- src->height, src_format, src_type)) {
- intel->vtbl.leave_meta_state(intel);
- return GL_FALSE;
- }
-
-
- intel->vtbl.meta_texture_blend_replace(intel);
-
- LOCK_HARDWARE(intel);
-
- if (intel->driDrawable->numClipRects) {
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
-
-
- srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
-
- srcx += dPriv->x;
- srcy += dPriv->y;
-
- /* Clip against the source region. This is the only source
- * clipping we do. XXX: Just set the texcord wrap mode to clamp
- * or similar.
- *
- */
- if (0) {
- GLint orig_x = srcx;
- GLint orig_y = srcy;
-
- if (!_mesa_clip_to_region(0, 0, src->pitch, src->height,
- &srcx, &srcy, &width, &height))
- goto out;
-
- dstx += srcx - orig_x;
- dsty += (srcy - orig_y) * ctx->Pixel.ZoomY;
- }
-
- /* Just use the regular cliprect mechanism... Does this need to
- * even hold the lock???
- */
- intel->vtbl.meta_draw_quad(intel,
- dstx,
- dstx + width * ctx->Pixel.ZoomX,
- dPriv->h - (dsty + height * ctx->Pixel.ZoomY),
- dPriv->h - (dsty), 0, /* XXX: what z value? */
- 0x00ff00ff,
- srcx, srcx + width, srcy, srcy + height);
-
- out:
- intel->vtbl.leave_meta_state(intel);
- intel_batchbuffer_emit_mi_flush(intel->batch);
- }
- UNLOCK_HARDWARE(intel);
-
- DBG("%s: success\n", __FUNCTION__);
- return GL_TRUE;
-}
-#endif /* I915 */
-
/**
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
@@ -400,12 +244,5 @@ intelCopyPixels(GLcontext * ctx,
if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
return;
-#ifdef I915
- if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
- return;
-#endif
-
- DBG("fallback to _swrast_CopyPixels\n");
-
- _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
+ _mesa_meta_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type);
}
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 7525cd9c4d..497f796764 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -181,6 +181,11 @@ intel_region_alloc(struct intel_context *intel,
dri_bo *buffer;
struct intel_region *region;
+ if (tiling == I915_TILING_X)
+ height = ALIGN(height, 8);
+ else if (tiling == I915_TILING_Y)
+ height = ALIGN(height, 32);
+
if (expect_accelerated_upload) {
buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
pitch * cpp * height, 64);
@@ -452,6 +457,7 @@ void
intel_region_cow(struct intel_context *intel, struct intel_region *region)
{
struct intel_buffer_object *pbo = region->pbo;
+ GLboolean ok;
intel_region_release_pbo(intel, region);
@@ -463,13 +469,14 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region)
*/
LOCK_HARDWARE(intel);
- assert(intelEmitCopyBlit(intel,
- region->cpp,
- region->pitch, pbo->buffer, 0, region->tiling,
- region->pitch, region->buffer, 0, region->tiling,
- 0, 0, 0, 0,
- region->pitch, region->height,
- GL_COPY));
+ ok = intelEmitCopyBlit(intel,
+ region->cpp,
+ region->pitch, pbo->buffer, 0, region->tiling,
+ region->pitch, region->buffer, 0, region->tiling,
+ 0, 0, 0, 0,
+ region->pitch, region->height,
+ GL_COPY);
+ assert(ok);
UNLOCK_HARDWARE(intel);
}
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 14cc815139..1b8c56e68d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -69,7 +69,11 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_DESC_END
DRI_CONF_OPT_END
- DRI_CONF_TEXTURE_TILING(false)
+#ifdef I915
+ DRI_CONF_TEXTURE_TILING(false)
+#else
+ DRI_CONF_TEXTURE_TILING(true)
+#endif
DRI_CONF_OPT_BEGIN(early_z, bool, false)
DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 34b78ebc1a..8df4990880 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -501,7 +501,7 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
/**
- * Prepare for softare rendering. Map current read/draw framebuffers'
+ * Prepare for software rendering. Map current read/draw framebuffers'
* renderbuffes and all currently bound texture objects.
*
* Old note: Moved locking out to get reasonable span performance.
@@ -526,7 +526,7 @@ intelSpanRenderStart(GLcontext * ctx)
}
/**
- * Called when done softare rendering. Unmap the buffers we mapped in
+ * Called when done software rendering. Unmap the buffers we mapped in
* the above function.
*/
void
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index 1f27131dac..89037073f8 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -44,10 +44,12 @@ intelTexSubimage(GLcontext * ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
+ GLsizei imageSize,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage,
+ GLboolean compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
@@ -59,9 +61,14 @@ intelTexSubimage(GLcontext * ctx,
intelFlush(ctx);
- pixels =
- _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
- type, pixels, packing, "glTexSubImage2D");
+ if (compressed)
+ pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize,
+ pixels, packing,
+ "glCompressedTexImage");
+ else
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
+ format, type, pixels, packing,
+ "glTexSubImage");
if (!pixels)
return;
@@ -90,15 +97,28 @@ intelTexSubimage(GLcontext * ctx,
assert(dstRowStride);
- if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- xoffset, yoffset, zoffset,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+ if (compressed) {
+ if (intelImage->mt) {
+ struct intel_region *dst = intelImage->mt->region;
+
+ _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
+ xoffset, yoffset / 4,
+ (width + 3) & ~3, (height + 3) / 4,
+ pixels, (width + 3) & ~3, 0, 0);
+ } else
+ memcpy(texImage->Data, pixels, imageSize);
+ }
+ else {
+ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+ }
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -132,8 +152,8 @@ intelTexSubImage3D(GLcontext * ctx,
intelTexSubimage(ctx, 3,
target, level,
xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, packing, texObj, texImage);
+ width, height, depth, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
@@ -152,8 +172,8 @@ intelTexSubImage2D(GLcontext * ctx,
intelTexSubimage(ctx, 2,
target, level,
xoffset, yoffset, 0,
- width, height, 1,
- format, type, pixels, packing, texObj, texImage);
+ width, height, 1, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
@@ -172,8 +192,8 @@ intelTexSubImage1D(GLcontext * ctx,
intelTexSubimage(ctx, 1,
target, level,
xoffset, 0, 0,
- width, 1, 1,
- format, type, pixels, packing, texObj, texImage);
+ width, 1, 1, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
static void
@@ -187,8 +207,11 @@ intelCompressedTexSubImage2D(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- fprintf(stderr, "stubbed CompressedTexSubImage2D: %dx%d@%dx%d\n",
- width, height, xoffset, yoffset);
+ intelTexSubimage(ctx, 2,
+ target, level,
+ xoffset, yoffset, 0,
+ width, height, 1, imageSize,
+ format, 0, pixels, &ctx->Unpack, texObj, texImage, GL_TRUE);
}
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index d49f4fabe7..5d0f367b38 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -107,31 +107,37 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
void r200EmitScissor(r200ContextPtr rmesa)
{
+ unsigned x1, y1, x2, y2;
+ struct radeon_renderbuffer *rrb;
BATCH_LOCALS(&rmesa->radeon);
if (!rmesa->radeon.radeonScreen->kernel_mm) {
return;
}
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ if (!rrb || !rrb->bo)
+ return;
+
if (rmesa->radeon.state.scissor.enabled) {
- BEGIN_BATCH(8);
- OUT_BATCH(CP_PACKET0(R200_RE_CNTL, 0));
- OUT_BATCH(R200_SCISSOR_ENABLE | rmesa->hw.set.cmd[SET_RE_CNTL]);
- OUT_BATCH(CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0));
- OUT_BATCH(R200_SCISSOR_ENABLE_0);
- OUT_BATCH(CP_PACKET0(R200_RE_SCISSOR_TL_0, 0));
- OUT_BATCH((rmesa->radeon.state.scissor.rect.y1 << 16) |
- rmesa->radeon.state.scissor.rect.x1);
- OUT_BATCH(CP_PACKET0(R200_RE_SCISSOR_BR_0, 0));
- OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2 - 1) << 16) |
- (rmesa->radeon.state.scissor.rect.x2 - 1));
- END_BATCH();
+ x1 = rmesa->radeon.state.scissor.rect.x1;
+ y1 = rmesa->radeon.state.scissor.rect.y1;
+ x2 = rmesa->radeon.state.scissor.rect.x2 - 1;
+ y2 = rmesa->radeon.state.scissor.rect.y2 - 1;
} else {
- BEGIN_BATCH(4);
- OUT_BATCH(CP_PACKET0(R200_RE_CNTL, 0));
- OUT_BATCH(rmesa->hw.set.cmd[SET_RE_CNTL] & ~R200_SCISSOR_ENABLE);
- OUT_BATCH(CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0));
- OUT_BATCH(0);
- END_BATCH();
+ x1 = 0;
+ y1 = 0;
+ x2 = rrb->base.Width - 1;
+ y2 = rrb->base.Height - 1;
}
+ BEGIN_BATCH(8);
+ OUT_BATCH(CP_PACKET0(R200_RE_CNTL, 0));
+ OUT_BATCH(R200_SCISSOR_ENABLE | rmesa->hw.set.cmd[SET_RE_CNTL]);
+ OUT_BATCH(CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0));
+ OUT_BATCH(0);
+ OUT_BATCH(CP_PACKET0(R200_RE_TOP_LEFT, 0));
+ OUT_BATCH((y1 << 16) | x1);
+ OUT_BATCH(CP_PACKET0(R200_RE_WIDTH_HEIGHT, 0));
+ OUT_BATCH((y2 << 16) | x2);
+ END_BATCH();
}
/* Fire a section of the retained (indexed_verts) buffer as a regular
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 9a92a32079..8cb287de26 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -500,3 +500,15 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
}
+void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ int i;
+ r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
+ if (rmesa)
+ {
+ for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
+ _math_matrix_dtr( &rmesa->TexGenMatrix[i] );
+ }
+ }
+ radeonDestroyContext(driContextPriv);
+}
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index bc871d9904..78ad5baebb 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -515,7 +515,7 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
if (drb)
dwords += 6;
if (rrb)
- dwords += 6;
+ dwords += 8;
if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM)
dwords += 4;
@@ -546,7 +546,7 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
- OUT_BATCH(cbpitch);
+ OUT_BATCH_RELOC(cbpitch, rrb->bo, cbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
}
if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM) {
@@ -563,7 +563,6 @@ static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
uint32_t dwords = atom->cmd_size;
int i = atom->idx;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
- radeon_mipmap_level *lvl;
if (t && t->mt && !t->image_override)
dwords += 2;
@@ -591,7 +590,6 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
uint32_t dwords = atom->cmd_size;
int i = atom->idx;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
- radeon_mipmap_level *lvl;
int hastexture = 1;
if (!r200->state.texture.unit[i].unitneeded)
@@ -774,7 +772,7 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( afs[1], never, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
}
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
if (rmesa->radeon.radeonScreen->kernel_mm)
rmesa->hw.tex[i].emit = tex_emit_cs;
else
@@ -786,7 +784,7 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( cube[3], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-3", 3 );
ALLOC_STATE( cube[4], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-4", 4 );
ALLOC_STATE( cube[5], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-5", 5 );
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
if (rmesa->radeon.radeonScreen->kernel_mm)
rmesa->hw.cube[i].emit = cube_emit_cs;
else
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 7eb11aaf27..bd46f9acf2 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -177,14 +177,17 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
} else if (!t) {
/* Texture unit hasn't a texture bound.
* We assign the current color buffer as a fakery to make
- * KIL work. */
- struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&r300->radeon);
- if (rrb && rrb->bo) {
- BEGIN_BATCH_NO_AUTOSTATE(4);
- OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_BATCH_RELOC(0, rrb->bo, 0,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
- END_BATCH();
+ * KIL work on KMS (without it, the CS checker will complain).
+ */
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&r300->radeon);
+ if (rrb && rrb->bo) {
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+ OUT_BATCH_RELOC(0, rrb->bo, 0,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ }
}
} else { /* override cases */
if (t->bo) {
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index cebb9a10d8..ab2287a5e2 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -604,11 +604,19 @@ static void r300DrawPrims(GLcontext *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
GLboolean retval;
+ /* This check should get folded into just the places that
+ * min/max index are really needed.
+ */
+ if (!index_bounds_valid) {
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+ }
+
if (min_index) {
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
return;
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
index 8debecbab9..dc2fb0144a 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
@@ -457,6 +457,9 @@ void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
GLuint size;
rmesa->hw.max_state_size = 4000; /* rough estimate */
+ rmesa->hw.all_dirty = GL_TRUE;
+ rmesa->hw.is_dirty = GL_TRUE;
+
/* Initialize command buffer */
size = 256 * driQueryOptioni(&rmesa->optionCache,
"command_buffer_size");
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index eacf811282..7009374b0c 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -395,6 +395,8 @@ r600DestroyContext (__DRIcontextPrivate * driContextPriv)
if (context)
FREE(context->hw.pStateList);
+
+ radeonDestroyContext(driContextPriv);
}
diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h
index fbb8164af5..30ddce682c 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -158,6 +158,17 @@ extern GLboolean r700InitChipObject(context_t *context);
extern GLboolean r700SendContextStates(context_t *context);
extern GLboolean r700SendViewportState(context_t *context, int id);
extern GLboolean r700SendRenderTargetState(context_t *context, int id);
+extern GLboolean r700SendTextureState(context_t *context);
+extern GLboolean r700SendDepthTargetState(context_t *context);
+extern GLboolean r700SendUCPState(context_t *context);
+extern GLboolean r700SendFSState(context_t *context);
+extern void r700EmitState(GLcontext * ctx);
+
+extern GLboolean r700SyncSurf(context_t *context,
+ struct radeon_bo *pbo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t sync_type);
extern int r700SetupStreams(GLcontext * ctx);
extern void r700SetupVTXConstants(GLcontext * ctx,
diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c
index 4840586858..ee9b64ee43 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -568,9 +568,6 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
}
}
- if (t->image_override && t->bo)
- return;
-
switch (texObj->Target) {
case GL_TEXTURE_1D:
SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_1D, DIM_shift, DIM_mask);
@@ -701,7 +698,7 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
struct gl_texture_object *tObj =
_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
radeonTexObjPtr t = radeon_tex_obj(tObj);
- uint32_t pitch_val;
+ uint32_t pitch_val, size;
if (!tObj)
return;
@@ -711,7 +708,12 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
if (!offset)
return;
- t->bo = NULL;
+ size = pitch;//h * w * (depth / 8);
+ if (t->bo) {
+ radeon_bo_unref(t->bo);
+ t->bo = NULL;
+ }
+ t->bo = radeon_legacy_bo_alloc_fake(rmesa->radeon.radeonScreen->bom, size, offset);
t->override_offset = offset;
pitch_val = pitch;
switch (depth) {
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 0abf112b55..eaacd06113 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -3839,6 +3839,9 @@ GLboolean Process_Export(r700_AssemblerBase* pAsm,
if (export_count == 1)
{
ucWriteMask = pAsm->pucOutMask[starting_register_number - pAsm->starting_export_register_number];
+ /* exports Z as a float into Red channel */
+ if (GL_TRUE == is_depth_export)
+ ucWriteMask = 0x1;
if( (ucWriteMask & 0x1) != 0)
{
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index 78779e841d..0fb355a0b6 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -138,6 +138,19 @@ GLboolean r700InitChipObject(context_t *context)
LINK_STATES(CB_CLRCMP_MSK);
LINK_STATES(CB_BLEND_CONTROL);
+ //DB
+ LINK_STATES(DB_HTILE_DATA_BASE);
+ LINK_STATES(DB_STENCIL_CLEAR);
+ LINK_STATES(DB_DEPTH_CLEAR);
+ LINK_STATES(DB_STENCILREFMASK);
+ LINK_STATES(DB_STENCILREFMASK_BF);
+ LINK_STATES(DB_DEPTH_CONTROL);
+ LINK_STATES(DB_SHADER_CONTROL);
+ LINK_STATES(DB_RENDER_CONTROL);
+ LINK_STATES(DB_RENDER_OVERRIDE);
+ LINK_STATES(DB_HTILE_SURFACE);
+ LINK_STATES(DB_ALPHA_TO_MASK);
+
// SX
LINK_STATES(SX_MISC);
LINK_STATES(SX_ALPHA_TEST_CONTROL);
@@ -322,7 +335,7 @@ void r700SetupVTXConstants(GLcontext * ctx,
unsigned int uSQ_VTX_CONSTANT_WORD6_0 = 0;
if (!paos->bo)
- return GL_FALSE;
+ return;
if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
@@ -474,6 +487,18 @@ GLboolean r700SendContextStates(context_t *context)
for(ui = 0; ui < R700_MAX_SHADER_EXPORTS; ui++)
R600_OUT_BATCH(r700->SPI_PS_INPUT_CNTL[ui].u32All);
END_BATCH();
+
+ if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
+ for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
+ if (r700->render_target[ui].enabled) {
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * ui),
+ r700->render_target[ui].CB_BLEND0_CONTROL.u32All);
+ END_BATCH();
+ }
+ }
+ }
+
COMMIT_BATCH();
return GL_TRUE;
@@ -491,38 +516,25 @@ GLboolean r700SendDepthTargetState(context_t *context)
return GL_FALSE;
}
- BEGIN_BATCH_NO_AUTOSTATE(9);
+ BEGIN_BATCH_NO_AUTOSTATE(8);
R600_OUT_BATCH_REGSEQ(DB_DEPTH_SIZE, 2);
R600_OUT_BATCH(r700->DB_DEPTH_SIZE.u32All);
R600_OUT_BATCH(r700->DB_DEPTH_VIEW.u32All);
- R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 3);
+ R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 2);
R600_OUT_BATCH_RELOC(r700->DB_DEPTH_BASE.u32All,
rrb->bo,
r700->DB_DEPTH_BASE.u32All,
0, RADEON_GEM_DOMAIN_VRAM, 0);
R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All);
- R600_OUT_BATCH(r700->DB_HTILE_DATA_BASE.u32All);
END_BATCH();
- BEGIN_BATCH_NO_AUTOSTATE(24);
- R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
- R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
- R600_OUT_BATCH(r700->DB_DEPTH_CLEAR.u32All);
-
- R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
- R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
- R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
-
- R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, r700->DB_DEPTH_CONTROL.u32All);
- R600_OUT_BATCH_REGVAL(DB_SHADER_CONTROL, r700->DB_SHADER_CONTROL.u32All);
-
- R600_OUT_BATCH_REGSEQ(DB_RENDER_CONTROL, 2);
- R600_OUT_BATCH(r700->DB_RENDER_CONTROL.u32All);
- R600_OUT_BATCH(r700->DB_RENDER_OVERRIDE.u32All);
-
- R600_OUT_BATCH_REGVAL(DB_HTILE_SURFACE, r700->DB_HTILE_SURFACE.u32All);
- R600_OUT_BATCH_REGVAL(DB_ALPHA_TO_MASK, r700->DB_ALPHA_TO_MASK.u32All);
- END_BATCH();
+ if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) &&
+ (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) {
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
+ R600_OUT_BATCH(1 << 0);
+ END_BATCH();
+ }
COMMIT_BATCH();
@@ -575,12 +587,6 @@ GLboolean r700SendRenderTargetState(context_t *context, int id)
R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), r700->render_target[id].CB_COLOR0_MASK.u32All);
END_BATCH();
- if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
- BEGIN_BATCH_NO_AUTOSTATE(3);
- R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * id), r700->render_target[id].CB_BLEND0_CONTROL.u32All);
- END_BATCH();
- }
-
COMMIT_BATCH();
r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c
index e84be38622..05d4af331e 100644
--- a/src/mesa/drivers/dri/r600/r700_clear.c
+++ b/src/mesa/drivers/dri/r600/r700_clear.c
@@ -31,6 +31,7 @@
#include "main/imports.h"
#include "main/mtypes.h"
#include "main/enums.h"
+#include "swrast/swrast.h"
#include "radeon_lock.h"
#include "r600_context.h"
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c
index 4ac37f1dfe..6249bde6f1 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.c
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.c
@@ -55,6 +55,12 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm,
//Input mapping : mesa_fp->Base.InputsRead set the flag, set in
//The flags parsed in parse_attrib_binding. FRAG_ATTRIB_COLx, FRAG_ATTRIB_TEXx, ...
//MUST match order in Map_Vertex_Output
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++;
+ }
+
unBit = 1 << FRAG_ATTRIB_COL0;
if(mesa_fp->Base.InputsRead & unBit)
{
@@ -112,6 +118,7 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm,
pAsm->uiFP_OutputMap[FRAG_RESULT_DEPTH] = pAsm->number_used_registers++;
pAsm->number_of_exports++;
pAsm->number_of_colorandz_exports++;
+ pAsm->pR700Shader->depthIsExported = 1;
}
pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
@@ -263,11 +270,13 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
+ BATCH_LOCALS(&context->radeon);
struct r700_fragment_program *fp = (struct r700_fragment_program *)
(ctx->FragmentProgram._Current);
r700_AssemblerBase *pAsm = &(fp->r700AsmCode);
struct gl_fragment_program *mesa_fp = &(fp->mesa_program);
+ struct gl_program_parameter_list *paramList;
+ unsigned int unNumParamData;
unsigned int ui, i;
unsigned int unNumOfReg;
unsigned int unBit;
@@ -302,6 +311,16 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
ui = (r700->SPI_PS_IN_CONTROL_0.u32All & NUM_INTERP_mask) / (1 << NUM_INTERP_shift);
+ /* PS uses fragment.position */
+ if (mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS))
+ {
+ ui += 1;
+ SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+ SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, CENTERS_ONLY, BARYC_SAMPLE_CNTL_shift, BARYC_SAMPLE_CNTL_mask);
+ SETbit(r700->SPI_PS_IN_CONTROL_0.u32All, POSITION_ENA_bit);
+ SETbit(r700->SPI_INPUT_Z.u32All, PROVIDE_Z_TO_SPI_bit);
+ }
+
ui = (unNumOfReg < ui) ? ui : unNumOfReg;
SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
@@ -335,7 +354,49 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
}
+ /* sent out shader constants. */
+ paramList = fp->mesa_program.Base.Parameters;
+
+ if(NULL != paramList)
+ {
+ _mesa_load_state_parameters(ctx, paramList);
+
+ unNumParamData = paramList->NumParameters * 4;
+
+ BEGIN_BATCH_NO_AUTOSTATE(2 + unNumParamData);
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
+
+ /* assembler map const from very beginning. */
+ R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
+
+ unNumParamData = paramList->NumParameters;
+
+ for(ui=0; ui<unNumParamData; ui++)
+ {
+ R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
+ R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
+ R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
+ R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
+ }
+ END_BATCH();
+ COMMIT_BATCH();
+ }
+
// emit ps input map
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
unBit = 1 << FRAG_ATTRIB_COL0;
if(mesa_fp->Base.InputsRead & unBit)
{
@@ -391,45 +452,3 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
return GL_TRUE;
}
-GLboolean r700SendPSConstants(GLcontext * ctx)
-{
- context_t *context = R700_CONTEXT(ctx);
- BATCH_LOCALS(&context->radeon);
- struct r700_fragment_program *fp = (struct r700_fragment_program *)
- (ctx->FragmentProgram._Current);
- struct gl_program_parameter_list *paramList;
- unsigned int unNumParamData;
- unsigned int ui;
-
- /* sent out shader constants. */
- paramList = fp->mesa_program.Base.Parameters;
-
- if(NULL != paramList)
- {
- _mesa_load_state_parameters(ctx, paramList);
-
- unNumParamData = paramList->NumParameters * 4;
-
- BEGIN_BATCH_NO_AUTOSTATE(2 + unNumParamData);
-
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
-
- /* assembler map const from very beginning. */
- R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
-
- unNumParamData = paramList->NumParameters;
-
- for(ui=0; ui<unNumParamData; ui++)
- {
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
- }
- END_BATCH();
- COMMIT_BATCH();
- }
-
- return GL_TRUE;
-}
-
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 36de143b1a..c49b90c1cc 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -33,6 +33,7 @@
#include "tnl/tnl.h"
#include "r600_context.h"
+#include "r600_emit.h"
#include "r700_oglprog.h"
#include "r700_fragprog.h"
@@ -87,7 +88,6 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
struct r700_vertex_program * vp;
struct r700_fragment_program * fp;
- context_t *context = R700_CONTEXT(ctx);
switch (prog->Target)
{
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index 2592d7df14..6705dbcf4b 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -139,6 +139,13 @@ static GLboolean r700SetupShaders(GLcontext * ctx)
r600UpdateTextureState(ctx);
+ r700SendFSState(context); // FIXME just a place holder for now
+ r700SendPSState(context);
+ r700SendVSState(context);
+
+ r700SendTextureState(context);
+ r700SetupStreams(ctx);
+
return GL_TRUE;
}
@@ -274,20 +281,15 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
void r700EmitState(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
+ radeonContextPtr radeon = &context->radeon;
+
+ if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty)
+ return;
rcommonEnsureCmdBufSpace(&context->radeon,
context->radeon.hw.max_state_size, __FUNCTION__);
- r700Start3D(context);
r700SendSQConfig(context);
- r700SendFSState(context); // FIXME just a place holder for now
- r700SendPSState(context);
- r700SendVSState(context);
- r700SendVSConstants(ctx);
- r700SendPSConstants(ctx);
-
- r700SendTextureState(context);
- r700SetupStreams(ctx);
r700SendUCPState(context);
r700SendContextStates(context);
@@ -305,13 +307,12 @@ static GLboolean r700RunRender(GLcontext * ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
+ r700Start3D(context);
+
r700UpdateShaders(ctx);
r700SetScissor(context);
r700SetupShaders(ctx);
- r700SetRenderTarget(context, 0);
- r700SetDepthTarget(context);
-
r700EmitState(ctx);
/* richard test code */
@@ -327,8 +328,6 @@ static GLboolean r700RunRender(GLcontext * ctx,
radeonReleaseArrays(ctx, ~0);
- rcommonFlushCmdBuf( &context->radeon, __FUNCTION__ );
-
return GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index e0a5742591..835b5e18c2 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -60,6 +60,8 @@ static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state);
static void r700UpdatePolygonMode(GLcontext * ctx);
static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state);
static void r700SetStencilState(GLcontext * ctx, GLboolean state);
+static void r700SetRenderTarget(context_t *context, int id);
+static void r700SetDepthTarget(context_t *context);
void r700SetDefaultStates(context_t *context) //--------------------
{
@@ -158,29 +160,16 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
*/
void r700UpdateDrawBuffer(GLcontext * ctx) /* TODO */ //---------------------
{
-#if 0 /* to be enabled */
- context_t *context = R700_CONTEXT(ctx);
+ context_t *context = R700_CONTEXT(ctx);
- switch (ctx->DrawBuffer->_ColorDrawBufferIndexes[0])
- {
- case BUFFER_FRONT_LEFT:
- context->target.rt = context->screen->frontBuffer;
- break;
- case BUFFER_BACK_LEFT:
- context->target.rt = context->screen->backBuffer;
- break;
- default:
- memset (&context->target.rt, sizeof(context->target.rt), 0);
- }
-#endif /* to be enabled */
+ r700SetRenderTarget(context, 0);
+ r700SetDepthTarget(context);
}
static void r700FetchStateParameter(GLcontext * ctx,
const gl_state_index state[STATE_LENGTH],
GLfloat * value)
{
- context_t *context = R700_CONTEXT(ctx);
-
/* TODO */
}
@@ -600,14 +589,46 @@ static void r700BlendFuncSeparate(GLcontext * ctx,
/**
* Translate LogicOp enums into hardware representation.
- * Both use a very logical bit-wise layout, but unfortunately the order
- * of bits is reversed.
*/
static GLuint translate_logicop(GLenum logicop)
{
- GLuint bits = logicop - GL_CLEAR;
- bits = ((bits & 1) << 3) | ((bits & 2) << 1) | ((bits & 4) >> 1) | ((bits & 8) >> 3);
- return bits;
+ switch (logicop) {
+ case GL_CLEAR:
+ return 0x00;
+ case GL_SET:
+ return 0xff;
+ case GL_COPY:
+ return 0xcc;
+ case GL_COPY_INVERTED:
+ return 0x33;
+ case GL_NOOP:
+ return 0xaa;
+ case GL_INVERT:
+ return 0x55;
+ case GL_AND:
+ return 0x88;
+ case GL_NAND:
+ return 0x77;
+ case GL_OR:
+ return 0xee;
+ case GL_NOR:
+ return 0x11;
+ case GL_XOR:
+ return 0x66;
+ case GL_EQUIV:
+ return 0xaa;
+ case GL_AND_REVERSE:
+ return 0x44;
+ case GL_AND_INVERTED:
+ return 0x22;
+ case GL_OR_REVERSE:
+ return 0xdd;
+ case GL_OR_INVERTED:
+ return 0xbb;
+ default:
+ fprintf(stderr, "unknown blend logic operation %x\n", logicop);
+ return 0xcc;
+ }
}
/**
@@ -1327,22 +1348,22 @@ void r700SetScissor(context_t *context) //---------------
r700->viewport[id].enabled = GL_TRUE;
}
-void r700SetRenderTarget(context_t *context, int id)
+static void r700SetRenderTarget(context_t *context, int id)
{
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
struct radeon_renderbuffer *rrb;
unsigned int nPitchInPixel;
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (!rrb || !rrb->bo) {
+ fprintf(stderr, "no rrb\n");
+ return;
+ }
+
/* screen/window/view */
SETfield(r700->CB_TARGET_MASK.u32All, 0xF, (4 * id), TARGET0_ENABLE_mask);
- rrb = radeon_get_colorbuffer(&context->radeon);
- if (!rrb || !rrb->bo) {
- fprintf(stderr, "no rrb\n");
- return;
- }
-
/* color buffer */
r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset;
@@ -1375,39 +1396,22 @@ void r700SetRenderTarget(context_t *context, int id)
r700->render_target[id].enabled = GL_TRUE;
}
-void r700SetDepthTarget(context_t *context)
+static void r700SetDepthTarget(context_t *context)
{
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
struct radeon_renderbuffer *rrb;
unsigned int nPitchInPixel;
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if (!rrb)
+ return;
+
/* depth buf */
r700->DB_DEPTH_SIZE.u32All = 0;
r700->DB_DEPTH_BASE.u32All = 0;
r700->DB_DEPTH_INFO.u32All = 0;
-
- r700->DB_DEPTH_CLEAR.u32All = 0x3F800000;
- r700->DB_DEPTH_VIEW.u32All = 0;
- r700->DB_RENDER_CONTROL.u32All = 0;
- SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
- SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
- r700->DB_RENDER_OVERRIDE.u32All = 0;
- if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
- SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
-
- r700->DB_ALPHA_TO_MASK.u32All = 0;
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET1_shift, ALPHA_TO_MASK_OFFSET1_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET2_shift, ALPHA_TO_MASK_OFFSET2_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET3_shift, ALPHA_TO_MASK_OFFSET3_mask);
-
- rrb = radeon_get_depthbuffer(&context->radeon);
- if (!rrb)
- return;
+ r700->DB_DEPTH_VIEW.u32All = 0;
nPitchInPixel = rrb->pitch/rrb->cpp;
@@ -1757,6 +1761,24 @@ void r700InitState(GLcontext * ctx) //-------------------
r700DepthFunc(ctx, ctx->Depth.Func);
SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
+ r700->DB_DEPTH_CLEAR.u32All = 0x3F800000;
+
+ r700->DB_RENDER_CONTROL.u32All = 0;
+ SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
+ SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
+ r700->DB_RENDER_OVERRIDE.u32All = 0;
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+
+ r700->DB_ALPHA_TO_MASK.u32All = 0;
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET1_shift, ALPHA_TO_MASK_OFFSET1_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET2_shift, ALPHA_TO_MASK_OFFSET2_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET3_shift, ALPHA_TO_MASK_OFFSET3_mask);
+
/* stencil */
r700Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
r700StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
@@ -1822,6 +1844,8 @@ void r700InitState(GLcontext * ctx) //-------------------
/* Set up color compare mask */
r700->CB_CLRCMP_MSK.u32All = 0xFFFFFFFF;
+ context->radeon.hw.all_dirty = GL_TRUE;
+
}
void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
diff --git a/src/mesa/drivers/dri/r600/r700_state.h b/src/mesa/drivers/dri/r600/r700_state.h
index 23246367db..30eb54e8b0 100644
--- a/src/mesa/drivers/dri/r600/r700_state.h
+++ b/src/mesa/drivers/dri/r600/r700_state.h
@@ -42,10 +42,8 @@ extern void r700UpdateDrawBuffer (GLcontext * ctx);
extern void r700InitState (GLcontext * ctx);
extern void r700InitStateFuncs (struct dd_function_table *functions);
-extern void r700SetRenderTarget(context_t *context, int id);
extern void r700SetDefaultStates(context_t * context);
-void r700SetScissor(context_t *context);
-void r700SetDepthTarget(context_t *context);
+extern void r700SetScissor(context_t *context);
#endif /* _R600_SCREEN_H */
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index 1c5c20f66e..31e71cdfa3 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -336,10 +336,14 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
+ BATCH_LOCALS(&context->radeon);
struct r700_vertex_program *vp
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ struct gl_program_parameter_list *paramList;
+ unsigned int unNumParamData;
+ unsigned int ui;
+
if(GL_FALSE == vp->loaded)
{
if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
@@ -385,21 +389,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
CLEARbit(r700->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
*/
- return GL_TRUE;
-}
-
-GLboolean r700SendVSConstants(GLcontext * ctx)
-{
- context_t *context = R700_CONTEXT(ctx);
- BATCH_LOCALS(&context->radeon);
- struct r700_vertex_program *vp
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
- struct gl_program_parameter_list *paramList;
- unsigned int unNumParamData;
- unsigned int ui;
-
/* sent out shader constants. */
-
paramList = vp->mesa_program.Base.Parameters;
if(NULL != paramList)
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
index 8eeaea1cb2..d52fb017d8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
@@ -83,6 +83,10 @@ struct radeon_bo_funcs {
int (*bo_unmap)(struct radeon_bo *bo);
int (*bo_wait)(struct radeon_bo *bo);
int (*bo_is_static)(struct radeon_bo *bo);
+ int (*bo_set_tiling)(struct radeon_bo *bo, uint32_t tiling_flags,
+ uint32_t pitch);
+ int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags,
+ uint32_t *pitch);
};
struct radeon_bo_manager {
@@ -187,6 +191,18 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo,
return bo->bom->funcs->bo_wait(bo);
}
+static inline int radeon_bo_set_tiling(struct radeon_bo *bo,
+ uint32_t tiling_flags, uint32_t pitch)
+{
+ return bo->bom->funcs->bo_set_tiling(bo, tiling_flags, pitch);
+}
+
+static inline int radeon_bo_get_tiling(struct radeon_bo *bo,
+ uint32_t *tiling_flags, uint32_t *pitch)
+{
+ return bo->bom->funcs->bo_get_tiling(bo, tiling_flags, pitch);
+}
+
static inline int radeon_bo_is_static(struct radeon_bo *bo)
{
if (bo->bom->funcs->bo_is_static)
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index 992eb4611b..d6d22cb4c3 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -577,6 +577,8 @@ static struct radeon_bo_funcs bo_legacy_funcs = {
bo_unmap,
NULL,
bo_is_static,
+ NULL,
+ NULL,
};
static int bo_vram_validate(struct radeon_bo *bo,
@@ -622,12 +624,34 @@ static int bo_vram_validate(struct radeon_bo *bo,
if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) {
if (IS_R600_CLASS(boml->screen)) {
- char *src = bo_legacy->ptr;
- char *dst = (char *) boml->screen->driScreen->pFB +
- (bo_legacy->offset - boml->fb_location);
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t tmp;
+ int ret;
- /* FIXME: alignment, pitch, etc. */
- memcpy(dst, src, bo->size);
+ tex.offset = bo_legacy->offset;
+ tex.image = &tmp;
+ assert(!(tex.offset & 1023));
+
+ tmp.x = 0;
+ tmp.y = 0;
+ tmp.width = bo->size;
+ tmp.height = 1;
+ tmp.data = bo_legacy->ptr;
+ tex.format = RADEON_TXFORMAT_ARGB8888;
+ tex.width = tmp.width;
+ tex.height = tmp.height;
+ tex.pitch = bo->size;
+ do {
+ ret = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_TEXTURE,
+ &tex,
+ sizeof(drm_radeon_texture_t));
+ if (ret) {
+ if (RADEON_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
+ usleep(1);
+ }
+ } while (ret == -EAGAIN);
} else {
/* Copy to VRAM using a blit.
* All memory is 4K aligned. We're using 1024 pixels wide blits.
@@ -904,3 +928,32 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
return bo->size;
}
+/*
+ * Fake up a bo for things like texture image_override.
+ * bo->offset already includes fb_location
+ */
+struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
+ int size,
+ uint32_t offset)
+{
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
+ struct bo_legacy *bo;
+
+#ifdef RADEON_DEBUG_BO
+ bo = bo_allocate(boml, size, 0, RADEON_GEM_DOMAIN_VRAM, 0, "fake bo");
+#else
+ bo = bo_allocate(boml, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+#endif /* RADEON_DEBUG_BO */
+ if (bo == NULL)
+ return NULL;
+ bo->static_bo = 1;
+ bo->offset = offset;
+ bo->base.handle = bo->offset;
+ bo->ptr = boml->screen->driScreen->pFB + (offset - boml->fb_location);
+ if (bo->base.handle > boml->nhandle) {
+ boml->nhandle = bo->base.handle + 1;
+ }
+ radeon_bo_ref(&(bo->base));
+ return &(bo->base);
+}
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
index 0db817cab0..455adebc09 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
@@ -42,5 +42,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom);
void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom);
unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo);
+struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
+ int size,
+ uint32_t offset);
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
index e0c70dd9a1..a42870f4a9 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
@@ -15,6 +15,12 @@
#define RADEON_GEM_DOMAIN_GTT 0x2 // GTT or cache flushed
#define RADEON_GEM_DOMAIN_VRAM 0x4 // VRAM domain
+#define RADEON_TILING_MACRO 0x1
+#define RADEON_TILING_MICRO 0x2
+#define RADEON_TILING_SWAP 0x4
+#define RADEON_TILING_SURFACE 0x8 /* this object requires a surface
+ * when mapped - i.e. front buffer */
+
/* to be used to build locally in mesa with no libdrm bits */
#include "../radeon/radeon_bo_drm.h"
#include "../radeon/radeon_cs_drm.h"
diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h
index 0a6a2df35b..a275c8fb14 100644
--- a/src/mesa/drivers/dri/radeon/radeon_chipset.h
+++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h
@@ -356,11 +356,14 @@
#define PCI_CHIP_RV770_947A 0x947A
#define PCI_CHIP_RV770_947B 0x947B
+#define PCI_CHIP_RV730_9480 0x9480
#define PCI_CHIP_RV730_9487 0x9487
+#define PCI_CHIP_RV730_9488 0x9488
#define PCI_CHIP_RV730_9489 0x9489
#define PCI_CHIP_RV730_948F 0x948F
#define PCI_CHIP_RV730_9490 0x9490
#define PCI_CHIP_RV730_9491 0x9491
+#define PCI_CHIP_RV730_9495 0x9495
#define PCI_CHIP_RV730_9498 0x9498
#define PCI_CHIP_RV730_949C 0x949C
#define PCI_CHIP_RV730_949E 0x949E
@@ -374,12 +377,16 @@
#define PCI_CHIP_RV710_9552 0x9552
#define PCI_CHIP_RV710_9553 0x9553
#define PCI_CHIP_RV710_9555 0x9555
+#define PCI_CHIP_RV710_9557 0x9557
#define PCI_CHIP_RV740_94A0 0x94A0
#define PCI_CHIP_RV740_94A1 0x94A1
+#define PCI_CHIP_RV740_94A3 0x94A3
#define PCI_CHIP_RV740_94B1 0x94B1
#define PCI_CHIP_RV740_94B3 0x94B3
+#define PCI_CHIP_RV740_94B4 0x94B4
#define PCI_CHIP_RV740_94B5 0x94B5
+#define PCI_CHIP_RV740_94B9 0x94B9
enum {
CHIP_FAMILY_R100,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 7f503a9ff7..330c2c8a86 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -481,32 +481,6 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
if (!n)
continue;
- if (IS_R600_CLASS(rmesa->radeonScreen)) {
- int cpp = rmesa->radeonScreen->cpp;
- int src_pitch = rmesa->radeonScreen->backPitch * cpp;
- int dst_pitch = rmesa->radeonScreen->frontPitch * cpp;
- char *src = (char *)rmesa->radeonScreen->driScreen->pFB + rmesa->radeonScreen->backOffset;
- char *dst = (char *)rmesa->radeonScreen->driScreen->pFB + rmesa->radeonScreen->frontOffset;
- int j;
- drm_clip_rect_t *pb = rmesa->sarea->boxes;
-
- for (j = 0; j < n; j++) {
- int x = pb[j].x1;
- int y = pb[j].y1;
- int w = pb[j].x2 - x;
- int h = pb[j].y2 - y;
-
- src += (y * src_pitch) + (x * cpp);
- dst += (y * dst_pitch) + (x * cpp);
-
- while (h--) {
- memcpy(dst, src, w * cpp);
- src += src_pitch;
- dst += dst_pitch;
- }
- }
- }
-
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
if ( ret ) {
@@ -1093,7 +1067,7 @@ void radeonFlush(GLcontext *ctx)
* each of N places that do rendering. This has worse performances,
* but it is much easier to get correct.
*/
- if (radeon->is_front_buffer_rendering) {
+ if (!radeon->is_front_buffer_rendering) {
radeon->front_buffer_dirty = GL_FALSE;
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 2a017b59cf..f71dc1cb23 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -211,6 +211,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
radeon->dri.screen = sPriv;
radeon->dri.hwContext = driContextPriv->hHWContext;
radeon->dri.hwLock = &sPriv->pSAREA->lock;
+ radeon->dri.hwLockCount = 0;
radeon->dri.fd = sPriv->fd;
radeon->dri.drmMinor = sPriv->drm_version.minor;
@@ -294,11 +295,10 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
GET_CURRENT_CONTEXT(ctx);
radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
-
- /* +r6/r7 */
- __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
- /* --------- */
+#endif
if (radeon == current) {
radeon_firevertices(radeon);
@@ -306,16 +306,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
}
assert(radeon);
- if (radeon)
- {
-
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
- if (IS_R600_CLASS(screen))
- {
- r600DestroyContext(driContextPriv);
- }
-#endif
-
+ if (radeon) {
if (radeon->dma.current) {
rcommonFlushCmdBuf( radeon, __FUNCTION__ );
}
@@ -762,8 +753,10 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
bo = depth_bo;
radeon_bo_ref(bo);
} else {
+ uint32_t tiling_flags = 0, pitch = 0;
+ int ret;
#ifdef RADEON_DEBUG_BO
- bo = radeon_bo_open(radeon->radeonScreen->bom,
+ bo = radeon_bo_open(radeon->radeonScreen->bom,
buffers[i].name,
0,
0,
@@ -784,6 +777,13 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
regname, buffers[i].name);
}
+
+ ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
+ if (tiling_flags & RADEON_TILING_MACRO)
+ bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
+ if (tiling_flags & RADEON_TILING_MICRO)
+ bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
+
}
if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index d7e94a6894..f8e1a25c9f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -365,6 +365,7 @@ struct radeon_dri_mirror {
drm_context_t hwContext;
drm_hw_lock_t *hwLock;
+ int hwLockCount;
int fd;
int drmMinor;
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index f28efa33e9..f05b106aaf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -291,7 +291,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
rrb->base.RedBits = 8;
rrb->base.GreenBits = 8;
rrb->base.BlueBits = 8;
- rrb->base.AlphaBits = 8;
+ rrb->base.AlphaBits = 0;
rrb->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_RGBA8:
@@ -407,7 +407,7 @@ restart:
rrb->cpp = 2;
rrb->base._ActualFormat = GL_RGB5;
rrb->base._BaseFormat = GL_RGB;
- rrb->base.DataType = GL_UNSIGNED_SHORT;
+ rrb->base.DataType = GL_UNSIGNED_BYTE;
DBG("Render to RGB5 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_argb1555) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 2f0ed1cfce..6294b7e42b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -86,8 +86,34 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
rmesa->vtbl.get_lock(rmesa);
}
-
-void radeon_lock_hardware(radeonContextPtr radeon)
+#ifndef NDEBUG
+struct lock_debug {
+ const char* function;
+ const char* file;
+ int line;
+};
+
+static struct lock_debug ldebug = {0};
+#endif
+
+#if 0
+/** TODO: use atomic operations for reference counting **/
+/** gcc 4.2 has builtin functios for this **/
+#define ATOMIC_INC_AND_FETCH(atomic) __sync_add_and_fetch(&atomic, 1)
+#define ATOMIC_DEC_AND_FETCH(atomic) __sync_sub_and_fetch(&atomic, 1)
+#else
+#define ATOMIC_INC_AND_FETCH(atomic) (++atomic)
+#define ATOMIC_DEC_AND_FETCH(atomic) (--atomic)
+#endif
+
+
+void radeon_lock_hardware(radeonContextPtr radeon
+#ifndef NDEBUG
+ ,const char* function
+ ,const char* file
+ ,const int line
+#endif
+ )
{
char ret = 0;
struct radeon_framebuffer *rfb = NULL;
@@ -102,16 +128,39 @@ void radeon_lock_hardware(radeonContextPtr radeon)
}
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ if (ATOMIC_INC_AND_FETCH(radeon->dri.hwLockCount) > 1)
+ {
+#ifndef NDEBUG
+ if ( RADEON_DEBUG & DEBUG_SANITY )
+ fprintf(stderr, "*** %d times of recursive call to %s ***\n"
+ "Original call was from %s (file: %s line: %d)\n"
+ "Now call is coming from %s (file: %s line: %d)\n"
+ , radeon->dri.hwLockCount, __FUNCTION__
+ , ldebug.function, ldebug.file, ldebug.line
+ , function, file, line
+ );
+#endif
+ return;
+ }
DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext,
(DRM_LOCK_HELD | radeon->dri.hwContext), ret );
if (ret)
radeonGetLock(radeon, 0);
+#ifndef NDEBUG
+ ldebug.function = function;
+ ldebug.file = file;
+ ldebug.line = line;
+#endif
}
}
void radeon_unlock_hardware(radeonContextPtr radeon)
{
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ if (ATOMIC_DEC_AND_FETCH(radeon->dri.hwLockCount) > 0)
+ {
+ return;
+ }
DRM_UNLOCK( radeon->dri.fd,
radeon->dri.hwLock,
radeon->dri.hwContext );
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h
index 2817709eed..da5a5b4371 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.h
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.h
@@ -48,12 +48,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags);
-void radeon_lock_hardware(radeonContextPtr rmesa);
+void radeon_lock_hardware(radeonContextPtr rmesa
+#ifndef NDEBUG
+ ,const char* function
+ ,const char* file
+ ,const int line
+#endif
+ );
void radeon_unlock_hardware(radeonContextPtr rmesa);
/* Lock the hardware and validate our state.
*/
+#ifdef NDEBUG
#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa)
+#else
+#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa, __FUNCTION__, __FILE__, __LINE__)
+#endif
#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa)
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 071a18e7d8..d4082bf68f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -326,7 +326,8 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
return GL_FALSE;
- if (texImage->IsCompressed != mt->compressed)
+ if ((!texImage->IsCompressed && mt->compressed) ||
+ (texImage->IsCompressed && !mt->compressed))
return GL_FALSE;
if (!texImage->IsCompressed &&
@@ -366,8 +367,8 @@ GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_textu
mt->width0 == firstImage->Width &&
mt->height0 == firstImage->Height &&
mt->depth0 == firstImage->Depth &&
- mt->bpp == firstImage->TexFormat->TexelBytes &&
- mt->compressed == compressed);
+ mt->compressed == compressed &&
+ (!mt->compressed ? (mt->bpp == firstImage->TexFormat->TexelBytes) : 1));
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 5f1af5b0da..7b759661ca 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -878,11 +878,14 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
+ case PCI_CHIP_RV730_9480:
case PCI_CHIP_RV730_9487:
+ case PCI_CHIP_RV730_9488:
case PCI_CHIP_RV730_9489:
case PCI_CHIP_RV730_948F:
case PCI_CHIP_RV730_9490:
case PCI_CHIP_RV730_9491:
+ case PCI_CHIP_RV730_9495:
case PCI_CHIP_RV730_9498:
case PCI_CHIP_RV730_949C:
case PCI_CHIP_RV730_949E:
@@ -899,15 +902,19 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
case PCI_CHIP_RV710_9552:
case PCI_CHIP_RV710_9553:
case PCI_CHIP_RV710_9555:
+ case PCI_CHIP_RV710_9557:
screen->chip_family = CHIP_FAMILY_RV710;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
case PCI_CHIP_RV740_94A0:
case PCI_CHIP_RV740_94A1:
+ case PCI_CHIP_RV740_94A3:
case PCI_CHIP_RV740_94B1:
case PCI_CHIP_RV740_94B3:
+ case PCI_CHIP_RV740_94B4:
case PCI_CHIP_RV740_94B5:
+ case PCI_CHIP_RV740_94B9:
screen->chip_family = CHIP_FAMILY_RV740;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
@@ -1579,21 +1586,11 @@ static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
{
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
- if (IS_R600_CLASS(screen))
- return r600CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
-
#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
if (IS_R300_CLASS(screen))
return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
- if (IS_R200_CLASS(screen))
- return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
-
#if !RADEON_COMMON
(void)screen;
return r100CreateContext(glVisual, driContextPriv, sharedContextPriv);
@@ -1793,8 +1790,16 @@ getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = radeonInitScreen,
.DestroyScreen = radeonDestroyScreen,
+#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+ .CreateContext = r200CreateContext,
+ .DestroyContext = r200DestroyContext,
+#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+ .CreateContext = r600CreateContext,
+ .DestroyContext = r600DestroyContext,
+#else
.CreateContext = radeonCreateContext,
.DestroyContext = radeonDestroyContext,
+#endif
.CreateBuffer = radeonCreateBuffer,
.DestroyBuffer = radeonDestroyBuffer,
.SwapBuffers = radeonSwapBuffers,
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index b2a468b4fd..5e4bf00d7a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -51,6 +51,59 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
+
+/* r200 depth buffer is always tiled - this is the formula
+ according to the docs unless I typo'ed in it
+*/
+static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset;
+ if (rrb->has_surface) {
+ offset = x * rrb->cpp + y * rrb->pitch;
+ } else {
+ GLuint b;
+ offset = 0;
+ b = (((y >> 4) * (rrb->pitch >> 8) + (x >> 6)));
+ offset += (b >> 1) << 12;
+ offset += (((rrb->pitch >> 8) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+ offset += ((y >> 2) & 0x3) << 9;
+ offset += ((x >> 3) & 0x1) << 8;
+ offset += ((x >> 4) & 0x3) << 6;
+ offset += ((x >> 2) & 0x1) << 5;
+ offset += ((y >> 1) & 0x1) << 4;
+ offset += ((x >> 1) & 0x1) << 3;
+ offset += (y & 0x1) << 2;
+ offset += (x & 0x1) << 1;
+ }
+ return &ptr[offset];
+}
+
+static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset;
+ if (rrb->has_surface) {
+ offset = x * rrb->cpp + y * rrb->pitch;
+ } else {
+ GLuint b;
+ offset = 0;
+ b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
+ offset += (b >> 1) << 12;
+ offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+ offset += ((y >> 2) & 0x3) << 9;
+ offset += ((x >> 2) & 0x1) << 8;
+ offset += ((x >> 3) & 0x3) << 6;
+ offset += ((y >> 1) & 0x1) << 5;
+ offset += ((x >> 1) & 0x1) << 4;
+ offset += (y & 0x1) << 3;
+ offset += (x & 0x1) << 2;
+ }
+ return &ptr[offset];
+}
+
/* radeon tiling on r300-r500 has 4 states,
macro-linear/micro-linear
macro-linear/micro-tiled
@@ -61,7 +114,6 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
4 byte surface
8/16 byte (unused)
*/
-
static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
GLint x, GLint y)
{
@@ -285,11 +337,21 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLushort
+#if defined(RADEON_COMMON_FOR_R200)
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off) = d
+#else
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d
+#endif
+#if defined(RADEON_COMMON_FOR_R200)
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off)
+#else
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off)
+#endif
#define TAG(x) radeon##x##_z16
#include "depthtmp.h"
@@ -301,7 +363,7 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLuint
-#ifdef COMPILE_R300
+#if defined(COMPILE_R300)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
@@ -310,6 +372,15 @@ do { \
tmp |= ((d << 8) & 0xffffff00); \
*_ptr = tmp; \
} while (0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define WRITE_DEPTH( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0xff000000; \
+ tmp |= ((d) & 0x00ffffff); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
@@ -321,19 +392,21 @@ do { \
} while (0)
#endif
-#ifdef COMPILE_R300
+#if defined(COMPILE_R300)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
}while(0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define READ_DEPTH( d, _x, _y ) \
+ do { \
+ d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; \
+ }while(0)
#else
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff;
#endif
-/*
- fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\
- d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff;
-*/
+
#define TAG(x) radeon##x##_z24
#include "depthtmp.h"
@@ -345,12 +418,19 @@ do { \
*/
#define VALUE_TYPE GLuint
-#ifdef COMPILE_R300
+#if defined(COMPILE_R300)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define WRITE_DEPTH( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = z24s8_to_s8z24(d); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
@@ -360,20 +440,22 @@ do { \
} while (0)
#endif
-#ifdef COMPILE_R300
+#if defined(COMPILE_R300)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
}while(0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define READ_DEPTH( d, _x, _y ) \
+ do { \
+ d = s8z24_to_z24s8(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \
+ }while(0)
#else
#define READ_DEPTH( d, _x, _y ) do { \
d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off ))); \
} while (0)
#endif
-/*
- fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\
- d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff;
-*/
+
#define TAG(x) radeon##x##_z24_s8
#include "depthtmp.h"
@@ -392,6 +474,15 @@ do { \
tmp |= (d) & 0xff; \
*_ptr = tmp; \
} while (0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define WRITE_STENCIL( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0x00ffffff; \
+ tmp |= (((d) & 0xff) << 24); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_STENCIL( _x, _y, d ) \
do { \
@@ -410,6 +501,13 @@ do { \
GLuint tmp = *_ptr; \
d = tmp & 0x000000ff; \
} while (0)
+#elif defined(RADEON_COMMON_FOR_R200)
+#define READ_STENCIL( d, _x, _y ) \
+do { \
+ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = *_ptr; \
+ d = (tmp & 0xff000000) >> 24; \
+} while (0)
#else
#define READ_STENCIL( d, _x, _y ) \
do { \
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 6a065f0468..fa16f44c18 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -610,9 +610,17 @@ static void radeon_teximage(
if (pixels) {
radeon_teximage_map(image, GL_TRUE);
-
if (compressed) {
- memcpy(texImage->Data, pixels, imageSize);
+ if (image->mt) {
+ uint32_t srcRowStride, bytesPerRow, rows;
+ srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+ bytesPerRow = srcRowStride;
+ rows = (height + 3) / 4;
+ copy_rows(texImage->Data, image->mt->levels[level].rowstride,
+ pixels, srcRowStride, rows, bytesPerRow);
+ } else {
+ memcpy(texImage->Data, pixels, imageSize);
+ }
} else {
GLuint dstRowStride;
GLuint *dstImageOffsets;
@@ -756,14 +764,23 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
}
if (compressed) {
- uint32_t srcRowStride, bytesPerRow, rows;
- dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+ uint32_t srcRowStride, bytesPerRow, rows;
+ GLubyte *img_start;
+ if (!image->mt) {
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+ img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+ texImage->TexFormat->MesaFormat,
+ texImage->Width, texImage->Data);
+ }
+ else {
+ uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
+ img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
+ }
srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
bytesPerRow = srcRowStride;
- rows = height / 4;
+ rows = (height + 3) / 4;
- copy_rows(texImage->Data, dstRowStride, image->base.Data, srcRowStride, rows,
- bytesPerRow);
+ copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
} else {
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
@@ -884,8 +901,8 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
uint32_t height;
/* need to confirm this value is correct */
if (mt->compressed) {
- height = image->base.Height / 4;
- srcrowstride = image->base.RowStride * mt->bpp;
+ height = (image->base.Height + 3) / 4;
+ srcrowstride = _mesa_compressed_row_stride(image->base.TexFormat->MesaFormat, image->base.Width);
} else {
height = image->base.Height * image->base.Depth;
srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
@@ -1000,6 +1017,8 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
}
if (compressed) {
+ /* FIXME: this can't work for small textures (mips) which
+ use different hw stride */
_mesa_get_compressed_teximage(ctx, target, level, pixels,
texObj, texImage);
} else {
diff --git a/src/mesa/glapi/EXT_framebuffer_object.xml b/src/mesa/glapi/EXT_framebuffer_object.xml
index 1b0de2ad23..5559b48b11 100644
--- a/src/mesa/glapi/EXT_framebuffer_object.xml
+++ b/src/mesa/glapi/EXT_framebuffer_object.xml
@@ -192,42 +192,4 @@
</function>
</category>
-
-
-<category name="GL_EXT_texture_array" number="329">
- <enum name="TEXTURE_1D_ARRAY_EXT" value="0x8C18"/>
- <enum name="PROXY_TEXTURE_1D_ARRAY_EXT" value="0x8C19"/>
- <enum name="TEXTURE_2D_ARRAY_EXT" value="0x8C1A"/>
- <enum name="PROXY_TEXTURE_2D_ARRAY_EXT" value="0x8C1B"/>
-
- <enum name="TEXTURE_BINDING_1D_ARRAY_EXT" count="1" value="0x8C1C">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="TEXTURE_BINDING_2D_ARRAY_EXT" count="1" value="0x8C1D">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="MAX_ARRAY_TEXTURE_LAYERS_EXT" count="1" value="0x88FF">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="COMPARE_REF_DEPTH_TO_TEXTURE_EXT" count="1" value="0x884E">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" count="1" value="0x8CD4">
- <size name="GetFramebufferAttachmentParameterivEXT" mode="get"/>
- </enum>
-
- <function name="FramebufferTextureLayerEXT" offset="assign">
- <param name="target" type="GLenum"/>
- <param name="attachment" type="GLenum"/>
- <param name="texture" type="GLuint"/>
- <param name="level" type="GLint"/>
- <param name="layer" type="GLint"/>
- </function>
-</category>
-
-
</OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_texture_array.xml b/src/mesa/glapi/EXT_texture_array.xml
new file mode 100644
index 0000000000..e5bd9f3c69
--- /dev/null
+++ b/src/mesa/glapi/EXT_texture_array.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_EXT_texture_array" number="329">
+ <enum name="TEXTURE_1D_ARRAY_EXT" value="0x8C18"/>
+ <enum name="PROXY_TEXTURE_1D_ARRAY_EXT" value="0x8C19"/>
+ <enum name="TEXTURE_2D_ARRAY_EXT" value="0x8C1A"/>
+ <enum name="PROXY_TEXTURE_2D_ARRAY_EXT" value="0x8C1B"/>
+
+ <enum name="TEXTURE_BINDING_1D_ARRAY_EXT" count="1" value="0x8C1C">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="TEXTURE_BINDING_2D_ARRAY_EXT" count="1" value="0x8C1D">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="MAX_ARRAY_TEXTURE_LAYERS_EXT" count="1" value="0x88FF">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="COMPARE_REF_DEPTH_TO_TEXTURE_EXT" count="1" value="0x884E">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" count="1" value="0x8CD4">
+ <size name="GetFramebufferAttachmentParameterivEXT" mode="get"/>
+ </enum>
+
+ <function name="FramebufferTextureLayerEXT" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layer" type="GLint"/>
+ </function>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml
index 06560d175a..1703637c7b 100644
--- a/src/mesa/glapi/gl_API.xml
+++ b/src/mesa/glapi/gl_API.xml
@@ -12255,6 +12255,65 @@
</function>
</category>
+<category name="GL_APPLE_flush_buffer_range" number="321">
+ <enum name="BUFFER_SERIALIZED_MODIFY_APPLE" count="1" value="0x8A12">
+ <size name="GetBufferParameteriv" mode="get"/>
+ </enum>
+ <enum name="BUFFER_FLUSHING_UNMAP_APPLE" count="1" value="0x8A13">
+ <size name="GetBufferParameteriv" mode="get"/>
+ </enum>
+ <function name="BufferParameteriAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="param" type="GLint"/>
+ </function>
+ <function name="FlushMappedBufferRangeAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="size" type="GLsizeiptr"/>
+ </function>
+</category>
+
+<xi:include href="EXT_texture_array.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<category name="GL_APPLE_texture_range" number="367">
+ <enum name="TEXTURE_STORAGE_HINT_APPLE" count="1" value="0x85BC">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ <size name="GetTexParameteriv" mode="get"/>
+ <size name="GetTexParameterfv" mode="get"/>
+ </enum>
+ <enum name="STORAGE_PRIVATE_APPLE" count="1" value="0x85BD">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="STORAGE_CACHED_APPLE" count="1" value="0x85BE">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="STORAGE_SHARED_APPLE" count="1" value="0x85BF">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="TEXTURE_RANGE_LENGTH_APPLE" count="1" value="0x85B7">
+ <size name="GetTexParameteriv" mode="get"/>
+ <size name="GetTexParameterfv" mode="get"/>
+ </enum>
+ <enum name="TEXTURE_RANGE_POINTER_APPLE" count="1" value="0x85B8">
+ <size name="GetTexParameterPointervAPPLE" mode="get"/>
+ </enum>
+ <function name="TextureRangeAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="length" type="GLsizei"/>
+ <param name="pointer" type="GLvoid *"/>
+ </function>
+ <function name="GetTexParameterPointervAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLvoid **"/>
+ </function>
+</category>
+
<!-- Unnumbered extensions sorted by name. -->
<category name="GL_ATI_blend_equation_separate">
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
index f5b7d1e138..2462a1b003 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -28,6 +28,7 @@
#include "glheader.h"
#include "api_arrayelt.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
@@ -1071,7 +1072,7 @@ void _ae_destroy_context( GLcontext *ctx )
static void check_vbo( AEcontext *actx,
struct gl_buffer_object *vbo )
{
- if (vbo->Name && !vbo->Pointer) {
+ if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
GLuint i;
for (i = 0; i < actx->nr_vbos; i++)
if (actx->vbo[i] == vbo)
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index e49cd041a6..199550b35d 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -107,6 +107,7 @@
#include "state.h"
#include "stencil.h"
#include "texenv.h"
+#include "texgetimage.h"
#include "teximage.h"
#if FEATURE_texgen
#include "texgen.h"
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index b2f11ffbfe..2df4f17389 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "api_validate.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "mtypes.h"
@@ -62,7 +63,7 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
GLuint max = 0;
GLuint i;
- if (elementBuf->Name) {
+ if (_mesa_is_bufferobj(elementBuf)) {
/* elements are in a user-defined buffer object. need to map it */
map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER,
GL_READ_ONLY, elementBuf);
@@ -96,14 +97,12 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
/**
- * Check if OK to render by examining framebuffer status and vertex arrays.
+ * Check if OK to draw arrays/elements.
*/
static GLboolean
-check_valid_to_render(GLcontext *ctx, char *function)
+check_valid_to_render(GLcontext *ctx, const char *function)
{
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDraw%s(incomplete framebuffer)", function);
+ if (!_mesa_valid_to_render(ctx, function)) {
return GL_FALSE;
}
@@ -160,11 +159,11 @@ _mesa_validate_DrawElements(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Elements"))
+ if (!check_valid_to_render(ctx, "glDrawElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -233,11 +232,11 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "RangeElements"))
+ if (!check_valid_to_render(ctx, "glDrawRangeElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -289,7 +288,7 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Arrays"))
+ if (!check_valid_to_render(ctx, "glDrawArrays"))
return GL_FALSE;
if (ctx->Const.CheckArrayBounds) {
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index cb49c4cb07..ab99ca1c64 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -174,24 +174,30 @@ struct texture_state
/**
- * Allocate a new attribute state node. These nodes have a
- * "kind" value and a pointer to a struct of state data.
+ * Allocate new attribute node of given type/kind. Attach payload data.
+ * Insert it into the linked list named by 'head'.
*/
-static struct gl_attrib_node *
-new_attrib_node( GLbitfield kind )
+static void
+save_attrib_data(struct gl_attrib_node **head,
+ GLbitfield kind, void *payload)
{
- struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
- if (an) {
- an->kind = kind;
+ struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node);
+ if (n) {
+ n->kind = kind;
+ n->data = payload;
+ /* insert at head */
+ n->next = *head;
+ *head = n;
+ }
+ else {
+ /* out of memory! */
}
- return an;
}
void GLAPIENTRY
_mesa_PushAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -213,10 +219,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_accum_attrib *attr;
attr = MALLOC_STRUCT( gl_accum_attrib );
MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
- newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ACCUM_BUFFER_BIT, attr);
}
if (mask & GL_COLOR_BUFFER_BIT) {
@@ -227,10 +230,7 @@ _mesa_PushAttrib(GLbitfield mask)
/* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
- newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr);
}
if (mask & GL_CURRENT_BIT) {
@@ -238,20 +238,14 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT( ctx, 0 );
attr = MALLOC_STRUCT( gl_current_attrib );
MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
- newnode = new_attrib_node( GL_CURRENT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CURRENT_BIT, attr);
}
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_depthbuffer_attrib *attr;
attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
- newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_DEPTH_BUFFER_BIT, attr);
}
if (mask & GL_ENABLE_BIT) {
@@ -331,40 +325,28 @@ _mesa_PushAttrib(GLbitfield mask)
attr->VertexProgram = ctx->VertexProgram.Enabled;
attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
- newnode = new_attrib_node( GL_ENABLE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ENABLE_BIT, attr);
}
if (mask & GL_EVAL_BIT) {
struct gl_eval_attrib *attr;
attr = MALLOC_STRUCT( gl_eval_attrib );
MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
- newnode = new_attrib_node( GL_EVAL_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_EVAL_BIT, attr);
}
if (mask & GL_FOG_BIT) {
struct gl_fog_attrib *attr;
attr = MALLOC_STRUCT( gl_fog_attrib );
MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
- newnode = new_attrib_node( GL_FOG_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_FOG_BIT, attr);
}
if (mask & GL_HINT_BIT) {
struct gl_hint_attrib *attr;
attr = MALLOC_STRUCT( gl_hint_attrib );
MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
- newnode = new_attrib_node( GL_HINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_HINT_BIT, attr);
}
if (mask & GL_LIGHTING_BIT) {
@@ -372,30 +354,21 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT(ctx, 0); /* flush material changes */
attr = MALLOC_STRUCT( gl_light_attrib );
MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
- newnode = new_attrib_node( GL_LIGHTING_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIGHTING_BIT, attr);
}
if (mask & GL_LINE_BIT) {
struct gl_line_attrib *attr;
attr = MALLOC_STRUCT( gl_line_attrib );
MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
- newnode = new_attrib_node( GL_LINE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LINE_BIT, attr);
}
if (mask & GL_LIST_BIT) {
struct gl_list_attrib *attr;
attr = MALLOC_STRUCT( gl_list_attrib );
MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
- newnode = new_attrib_node( GL_LIST_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIST_BIT, attr);
}
if (mask & GL_PIXEL_MODE_BIT) {
@@ -404,60 +377,42 @@ _mesa_PushAttrib(GLbitfield mask)
MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
/* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
- newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr);
}
if (mask & GL_POINT_BIT) {
struct gl_point_attrib *attr;
attr = MALLOC_STRUCT( gl_point_attrib );
MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
- newnode = new_attrib_node( GL_POINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POINT_BIT, attr);
}
if (mask & GL_POLYGON_BIT) {
struct gl_polygon_attrib *attr;
attr = MALLOC_STRUCT( gl_polygon_attrib );
MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
- newnode = new_attrib_node( GL_POLYGON_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_BIT, attr);
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
GLuint *stipple;
stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
- newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
- newnode->data = stipple;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_STIPPLE_BIT, stipple);
}
if (mask & GL_SCISSOR_BIT) {
struct gl_scissor_attrib *attr;
attr = MALLOC_STRUCT( gl_scissor_attrib );
MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
- newnode = new_attrib_node( GL_SCISSOR_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_SCISSOR_BIT, attr);
}
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_stencil_attrib *attr;
attr = MALLOC_STRUCT( gl_stencil_attrib );
MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
- newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_STENCIL_BUFFER_BIT, attr);
}
if (mask & GL_TEXTURE_BIT) {
@@ -494,30 +449,21 @@ _mesa_PushAttrib(GLbitfield mask)
_mesa_unlock_context_textures(ctx);
- newnode = new_attrib_node( GL_TEXTURE_BIT );
- newnode->data = texstate;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TEXTURE_BIT, texstate);
}
if (mask & GL_TRANSFORM_BIT) {
struct gl_transform_attrib *attr;
attr = MALLOC_STRUCT( gl_transform_attrib );
MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
- newnode = new_attrib_node( GL_TRANSFORM_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TRANSFORM_BIT, attr);
}
if (mask & GL_VIEWPORT_BIT) {
struct gl_viewport_attrib *attr;
attr = MALLOC_STRUCT( gl_viewport_attrib );
MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
- newnode = new_attrib_node( GL_VIEWPORT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_VIEWPORT_BIT, attr);
}
/* GL_ARB_multisample */
@@ -525,10 +471,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_multisample_attrib *attr;
attr = MALLOC_STRUCT( gl_multisample_attrib );
MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
- newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_MULTISAMPLE_BIT_ARB, attr);
}
end:
@@ -1373,7 +1316,6 @@ copy_pixelstore(GLcontext *ctx,
void GLAPIENTRY
_mesa_PushClientAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -1394,17 +1336,11 @@ _mesa_PushClientAttrib(GLbitfield mask)
/* packing attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Pack);
- newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr);
/* unpacking attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Unpack);
- newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr);
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
@@ -1425,10 +1361,8 @@ _mesa_PushClientAttrib(GLbitfield mask)
attr->ArrayObj = obj;
- newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
+
/* bump reference counts on buffer objects */
adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
}
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index d640f5358e..f96185a4b5 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -156,7 +156,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
_mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller);
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
}
@@ -165,7 +165,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
"%s(size + offset > buffer size)", caller);
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Buffer is currently mapped */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
@@ -423,7 +423,7 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
(void) target;
(void) access;
/* Just return a direct pointer to the data */
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* already mapped! */
return NULL;
}
@@ -445,7 +445,7 @@ _mesa_buffer_map_range( GLcontext *ctx, GLenum target, GLintptr offset,
(void) target;
(void) access;
(void) length;
- assert(!bufObj->Pointer);
+ assert(!_mesa_bufferobj_mapped(bufObj));
/* Just return a direct pointer to the data */
return bufObj->Data + offset;
}
@@ -502,8 +502,8 @@ _mesa_copy_buffer_subdata(GLcontext *ctx,
GLubyte *srcPtr, *dstPtr;
/* buffer should not already be mapped */
- assert(!src->Pointer);
- assert(!dst->Pointer);
+ assert(!_mesa_bufferobj_mapped(src));
+ assert(!_mesa_bufferobj_mapped(dst));
srcPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_READ_BUFFER,
GL_READ_ONLY, src);
@@ -663,7 +663,7 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLvoid *start, *end;
const GLubyte *sizeAddr; /* buffer size, cast to a pointer */
- ASSERT(pack->BufferObj->Name != 0);
+ ASSERT(_mesa_is_bufferobj(pack->BufferObj));
if (pack->BufferObj->Size == 0)
/* no buffer! */
@@ -709,7 +709,7 @@ _mesa_map_bitmap_pbo(GLcontext *ctx,
{
const GLubyte *buf;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* unpack from PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
@@ -736,7 +736,7 @@ void
_mesa_unmap_bitmap_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -753,7 +753,7 @@ _mesa_map_drawpix_pbo(GLcontext *ctx,
{
const GLvoid *buf;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* unpack from PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
@@ -779,7 +779,7 @@ void
_mesa_unmap_drawpix_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -798,7 +798,7 @@ _mesa_map_readpix_pbo(GLcontext *ctx,
{
void *buf;
- if (pack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
/* pack into PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
GL_WRITE_ONLY_ARB,
@@ -824,7 +824,7 @@ void
_mesa_unmap_readpix_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *pack)
{
- if (pack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
}
}
@@ -932,7 +932,7 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
ASSERT(bufObj->Name == ids[i]);
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* if mapped, unmap it now */
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
@@ -1086,12 +1086,12 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
_mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB(buffer 0)" );
return;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, target, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
@@ -1187,18 +1187,18 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
_mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" );
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(buffer 0)" );
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
return NULL;
}
ASSERT(ctx->Driver.MapBuffer);
bufObj->Pointer = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
}
@@ -1248,11 +1248,11 @@ _mesa_UnmapBufferARB(GLenum target)
_mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" );
return GL_FALSE;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" );
return GL_FALSE;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
return GL_FALSE;
}
@@ -1315,7 +1315,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
_mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameterivARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" );
return;
}
@@ -1331,7 +1331,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
*params = simplified_access_mode(bufObj->AccessFlags);
break;
case GL_BUFFER_MAPPED_ARB:
- *params = (bufObj->Pointer != NULL);
+ *params = _mesa_bufferobj_mapped(bufObj);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)");
@@ -1357,7 +1357,7 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" );
return;
}
@@ -1376,26 +1376,26 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
ASSERT_OUTSIDE_BEGIN_END(ctx);
src = get_buffer(ctx, readTarget);
- if (!src || src->Name == 0) {
+ if (!src || !_mesa_is_bufferobj(src)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(readTarget = 0x%x)", readTarget);
return;
}
dst = get_buffer(ctx, writeTarget);
- if (!dst || dst->Name == 0) {
+ if (!dst || !_mesa_is_bufferobj(dst)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(writeTarget = 0x%x)", writeTarget);
return;
}
- if (src->Pointer) {
+ if (_mesa_bufferobj_mapped(src)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(readBuffer is mapped)");
return;
}
- if (dst->Pointer) {
+ if (_mesa_bufferobj_mapped(dst)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(writeBuffer is mapped)");
return;
@@ -1499,7 +1499,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
}
bufObj = get_buffer(ctx, target);
- if (!bufObj || bufObj->Name == 0) {
+ if (!bufObj || !_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glMapBufferRange(target = 0x%x)", target);
return NULL;
@@ -1511,7 +1511,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer already mapped)");
return NULL;
@@ -1564,13 +1564,13 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(current buffer is 0)");
return;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
/* buffer is not mapped */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer is not mapped)");
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index ef59ff83c8..decb44a65e 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -36,6 +36,26 @@
* Internal functions
*/
+
+/** Is the given buffer object currently mapped? */
+static INLINE GLboolean
+_mesa_bufferobj_mapped(const struct gl_buffer_object *obj)
+{
+ return obj->Pointer != NULL;
+}
+
+/**
+ * Is the given buffer object a user-created buffer object?
+ * Mesa uses default buffer objects in several places. Default buffers
+ * always have Name==0. User created buffers have Name!=0.
+ */
+static INLINE GLboolean
+_mesa_is_bufferobj(const struct gl_buffer_object *obj)
+{
+ return obj->Name != 0;
+}
+
+
extern void
_mesa_init_buffer_objects( GLcontext *ctx );
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index bd9cf438b4..36304065eb 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -179,7 +179,7 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
GLfloat bScale, GLfloat bBias,
GLfloat aScale, GLfloat aBias)
{
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* Get/unpack the color table data from a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, count, 1, 1,
@@ -279,7 +279,7 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -696,7 +696,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack color table into PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, table->Size, 1, 1,
@@ -720,7 +720,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
format, type, data, &ctx->Pack, 0x0);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index f77a29a43e..e4995c35c4 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -138,9 +138,14 @@
/**
* Maximum viewport/image width. Must accomodate all texture sizes too.
*/
-#define MAX_WIDTH 4096
+
+#ifndef MAX_WIDTH
+# define MAX_WIDTH 4096
+#endif
/** Maximum viewport/image height */
-#define MAX_HEIGHT 4096
+#ifndef MAX_HEIGHT
+# define MAX_HEIGHT 4096
+#endif
/** Maxmimum size for CVA. May be overridden by the drivers. */
#define MAX_ARRAY_LOCK_SIZE 3000
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 415e339cb8..38ec418809 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -150,6 +150,7 @@
#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"
@@ -1576,4 +1577,72 @@ _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;
+ }
+ }
+ 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;
+}
+
+
/*@}*/
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 0531ae8ee8..5587695fa0 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -159,6 +159,11 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
GLboolean flag );
+extern GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where);
+
+
+
/** \name Miscellaneous */
/*@{*/
@@ -174,7 +179,6 @@ _mesa_Flush( void );
/*@}*/
-
/**
* \name Macros for flushing buffered rendering commands before state changes,
* checking if inside glBegin/glEnd, etc.
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 814c6a0a5a..69dba72ed3 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -144,7 +144,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution1D.Width = width;
ctx->Convolution1D.Height = 1;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
@@ -173,7 +173,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
format, type, image, &ctx->Unpack,
0); /* transferOps */
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -242,7 +242,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution2D.Width = width;
ctx->Convolution2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
@@ -276,7 +276,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
0); /* transferOps */
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -598,7 +598,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack the filter into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Pack,
@@ -629,7 +629,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
format, type, dst, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -802,7 +802,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
filter = &ctx->Separable2D;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack filter into PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Width, 1, 1,
@@ -850,7 +850,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
(void) span; /* unused at this time */
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack filter into PBO */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
@@ -905,7 +905,7 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Separable2D.Width = width;
ctx->Separable2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
@@ -971,7 +971,7 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Pixel.ConvolutionFilterBias[2][3]);
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
index 1c8c44fcb9..8492c8561d 100644
--- a/src/mesa/main/debug.c
+++ b/src/mesa/main/debug.c
@@ -33,6 +33,7 @@
#include "get.h"
#include "pixelstore.h"
#include "readpix.h"
+#include "texgetimage.h"
#include "texobj.h"
#include "texformat.h"
@@ -234,11 +235,11 @@ _mesa_init_debug( GLcontext *ctx )
*/
static void
write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
- int comps, int rcomp, int gcomp, int bcomp)
+ int comps, int rcomp, int gcomp, int bcomp, GLboolean invert)
{
FILE *f = fopen( filename, "w" );
if (f) {
- int i, x, y;
+ int x, y;
const GLubyte *ptr = buffer;
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
@@ -246,10 +247,11 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
- for (y=height-1; y>=0; y--) {
- for (x=0; x<width; x++) {
- i = (y*width + x) * comps;
- fputc(ptr[i+rcomp], f); /* write red */
+ for (y=0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int yy = invert ? (height - 1 - y) : y;
+ int i = (yy * width + x) * comps;
+ fputc(ptr[i+rcomp], f); /* write red */
fputc(ptr[i+gcomp], f); /* write green */
fputc(ptr[i+bcomp], f); /* write blue */
}
@@ -263,47 +265,34 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
* Write level[0] image to a ppm file.
*/
static void
-write_texture_image(struct gl_texture_object *texObj)
+write_texture_image(struct gl_texture_object *texObj, GLuint face, GLuint level)
{
- const struct gl_texture_image *img = texObj->Image[0][0];
- if (img && img->Data) {
+ struct gl_texture_image *img = texObj->Image[face][level];
+ if (img) {
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pixelstore_attrib store;
+ GLubyte *buffer;
char s[100];
+ buffer = (GLubyte *) _mesa_malloc(img->Width * img->Height
+ * img->Depth * 4);
+
+ store = ctx->Pack; /* save */
+ ctx->Pack = ctx->DefaultPacking;
+
+ ctx->Driver.GetTexImage(ctx, texObj->Target, level,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer, texObj, img);
+
/* make filename */
- sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
-
- switch (img->TexFormat->MesaFormat) {
- case MESA_FORMAT_RGBA8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 3, 2, 1);
- break;
- case MESA_FORMAT_ARGB8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB888:
- write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB565:
- {
- GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3);
- GLuint i;
- for (i = 0; i < img->Width * img->Height; i++) {
- GLint r, g, b;
- GLushort s = ((GLushort *) img->Data)[i];
- r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
- g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
- b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
- buf2[i*3+1] = r;
- buf2[i*3+2] = g;
- buf2[i*3+3] = b;
- }
- write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0);
- _mesa_free(buf2);
- }
- break;
- default:
- printf("XXXX unsupported mesa tex format %d in %s\n",
- img->TexFormat->MesaFormat, __FUNCTION__);
- }
+ _mesa_sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
+
+ _mesa_printf(" Writing image level %u to %s\n", level, s);
+ write_ppm(s, buffer, img->Width, img->Height, 4, 0, 1, 2, GL_FALSE);
+
+ ctx->Pack = store; /* restore */
+
+ _mesa_free(buffer);
}
}
@@ -316,17 +305,21 @@ dump_texture_cb(GLuint id, void *data, void *userData)
{
struct gl_texture_object *texObj = (struct gl_texture_object *) data;
int i;
+ GLboolean written = GL_FALSE;
(void) userData;
- printf("Texture %u\n", texObj->Name);
- printf(" Target 0x%x\n", texObj->Target);
+ _mesa_printf("Texture %u\n", texObj->Name);
+ _mesa_printf(" Target 0x%x\n", texObj->Target);
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
struct gl_texture_image *texImg = texObj->Image[0][i];
if (texImg) {
- printf(" Image %u: %d x %d x %d at %p\n", i,
- texImg->Width, texImg->Height, texImg->Depth, texImg->Data);
- if (DumpImages && i == 0) {
- write_texture_image(texObj);
+ _mesa_printf(" Image %u: %d x %d x %d, format %u at %p\n", i,
+ texImg->Width, texImg->Height, texImg->Depth,
+ texImg->TexFormat->MesaFormat, texImg->Data);
+ if (DumpImages && !written) {
+ GLuint face = 0;
+ write_texture_image(texObj, face, i);
+ written = GL_TRUE;
}
}
}
@@ -368,7 +361,7 @@ _mesa_dump_color_buffer(const char *filename)
ctx->DrawBuffer->_ColorDrawBuffers[0],
ctx->DrawBuffer->ColorDrawBuffer[0]);
_mesa_printf("Writing %d x %d color buffer to %s\n", w, h, filename);
- write_ppm(filename, buf, w, h, 4, 0, 1, 2);
+ write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -403,7 +396,7 @@ _mesa_dump_depth_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d depth buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -438,7 +431,7 @@ _mesa_dump_stencil_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d stencil buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 49f202daa1..9b68b3e116 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -683,24 +683,48 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
/**
* Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
- * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
+ * If we run out of memory, GL_OUT_OF_MEMORY will be recorded.
*/
static GLvoid *
-unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth,
+unpack_image(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid * pixels,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, pixels, unpack);
+ GLvoid *image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, pixels, unpack);
+ if (pixels && !image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
- else
- if (_mesa_validate_pbo_access
- (dimensions, unpack, width, height, depth, format, type, pixels)) {
- const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels);
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, src, unpack);
+ else if (_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
+ format, type, pixels)) {
+ const GLubyte *map, *src;
+ GLvoid *image;
+
+ map = (GLubyte *)
+ ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, unpack->BufferObj);
+ if (!map) {
+ /* unable to map src buffer! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
+ return NULL;
+ }
+
+ src = ADD_POINTERS(map, pixels);
+ image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, src, unpack);
+
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
/* bad access! */
return NULL;
@@ -858,7 +882,6 @@ save_Bitmap(GLsizei width, GLsizei height,
GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_BITMAP, 7);
@@ -869,10 +892,7 @@ save_Bitmap(GLsizei width, GLsizei height,
n[4].f = yorig;
n[5].f = xmove;
n[6].f = ymove;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_Bitmap(ctx->Exec, (width, height,
@@ -999,7 +1019,7 @@ _mesa_save_CallList(GLuint list)
void GLAPIENTRY
-_mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+_mesa_save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
{
GET_CURRENT_CONTEXT(ctx);
GLint i;
@@ -1024,7 +1044,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
typeErrorFlag = GL_TRUE;
}
- for (i = 0; i < n; i++) {
+ for (i = 0; i < num; i++) {
GLint list = translate_id(i, type, lists);
Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
if (n) {
@@ -1039,7 +1059,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
invalidate_saved_current_state( ctx );
if (ctx->ExecuteFlag) {
- CALL_CallLists(ctx->Exec, (n, type, lists));
+ CALL_CallLists(ctx->Exec, (num, type, lists));
}
}
@@ -1217,8 +1237,6 @@ save_ColorTable(GLenum target, GLenum internalFormat,
format, type, table));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE, 6);
@@ -1228,10 +1246,8 @@ save_ColorTable(GLenum target, GLenum internalFormat,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
@@ -1307,8 +1323,6 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
GLenum format, GLenum type, const GLvoid * table)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, count, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_SUB_TABLE, 6);
@@ -1318,10 +1332,8 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
n[3].i = count;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorSubTable(ctx->Exec,
@@ -1379,10 +1391,10 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
GLenum format, GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
if (n) {
n[1].e = target;
@@ -1390,10 +1402,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
@@ -1408,10 +1418,10 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
if (n) {
n[1].e = target;
@@ -1420,10 +1430,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
n[4].i = height;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter2D(ctx->Exec,
@@ -1778,20 +1786,18 @@ save_DrawPixels(GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_PIXELS, 5);
if (n) {
n[1].i = width;
n[2].i = height;
n[3].e = format;
n[4].e = type;
- n[5].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
@@ -1880,7 +1886,10 @@ save_Fogfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_Fogf(GLenum pname, GLfloat param)
{
- save_Fogfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Fogfv(pname, parray);
}
@@ -1904,7 +1913,7 @@ save_Fogiv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_Fogfv(pname, p);
}
@@ -1913,7 +1922,10 @@ save_Fogiv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Fogi(GLenum pname, GLint param)
{
- save_Fogiv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Fogiv(pname, parray);
}
@@ -2077,9 +2089,12 @@ save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
-save_Lightf(GLenum light, GLenum pname, GLfloat params)
+save_Lightf(GLenum light, GLenum pname, GLfloat param)
{
- save_Lightfv(light, pname, &params);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Lightfv(light, pname, parray);
}
@@ -2125,7 +2140,10 @@ save_Lightiv(GLenum light, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Lighti(GLenum light, GLenum pname, GLint param)
{
- save_Lightiv(light, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Lightiv(light, pname, parray);
}
@@ -2152,7 +2170,10 @@ save_LightModelfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_LightModelf(GLenum pname, GLfloat param)
{
- save_LightModelfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_LightModelfv(pname, parray);
}
@@ -2174,7 +2195,7 @@ save_LightModeliv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_LightModelfv(pname, fparam);
}
@@ -2183,7 +2204,10 @@ save_LightModeliv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_LightModeli(GLenum pname, GLint param)
{
- save_LightModeliv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_LightModeliv(pname, parray);
}
@@ -2698,21 +2722,28 @@ save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_PointParameterfEXT(GLenum pname, GLfloat param)
{
- save_PointParameterfvEXT(pname, &param);
+ GLfloat parray[3];
+ parray[0] = param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameteriNV(GLenum pname, GLint param)
{
- GLfloat p = (GLfloat) param;
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameterivNV(GLenum pname, const GLint * param)
{
- GLfloat p = (GLfloat) param[0];
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param[0];
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
@@ -2753,16 +2784,14 @@ static void GLAPIENTRY
save_PolygonStipple(const GLubyte * pattern)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
- pattern, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1);
if (n) {
- n[1].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
+ pattern, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
@@ -3386,7 +3415,10 @@ save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexEnvfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexEnvfv(target, pname, parray);
}
@@ -3454,8 +3486,10 @@ save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_TexGend(GLenum coord, GLenum pname, GLdouble param)
{
- GLfloat p = (GLfloat) param;
- save_TexGenfv(coord, pname, &p);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
@@ -3474,14 +3508,20 @@ save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
static void GLAPIENTRY
save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
{
- save_TexGenfv(coord, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
static void GLAPIENTRY
save_TexGeni(GLenum coord, GLenum pname, GLint param)
{
- save_TexGeniv(coord, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_TexGeniv(coord, pname, parray);
}
@@ -3509,7 +3549,10 @@ save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexParameterfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexParameterfv(target, pname, parray);
}
@@ -3546,8 +3589,6 @@ save_TexImage1D(GLenum target,
border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE1D, 8);
@@ -3559,10 +3600,8 @@ save_TexImage1D(GLenum target,
n[5].i = border;
n[6].e = format;
n[7].e = type;
- n[8].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage1D(ctx->Exec, (target, level, components, width,
@@ -3585,8 +3624,6 @@ save_TexImage2D(GLenum target,
height, border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE2D, 9);
@@ -3599,10 +3636,8 @@ save_TexImage2D(GLenum target,
n[6].i = border;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage2D(ctx->Exec, (target, level, components, width,
@@ -3628,8 +3663,6 @@ save_TexImage3D(GLenum target,
}
else {
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE3D, 10);
if (n) {
@@ -3642,10 +3675,8 @@ save_TexImage3D(GLenum target,
n[7].i = border;
n[8].e = format;
n[9].e = type;
- n[10].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[10].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
@@ -3663,9 +3694,9 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
if (n) {
n[1].e = target;
@@ -3674,10 +3705,8 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
n[4].i = (GLint) width;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
@@ -3694,9 +3723,9 @@ save_TexSubImage2D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
if (n) {
n[1].e = target;
@@ -3707,10 +3736,8 @@ save_TexSubImage2D(GLenum target, GLint level,
n[6].i = (GLint) height;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
@@ -3727,9 +3754,9 @@ save_TexSubImage3D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE3D, 11);
if (n) {
n[1].e = target;
@@ -3742,10 +3769,8 @@ save_TexSubImage3D(GLenum target, GLint level,
n[8].i = (GLint) depth;
n[9].e = format;
n[10].e = type;
- n[11].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[11].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage3D(ctx->Exec, (target, level,
@@ -4458,18 +4483,17 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- return;
- }
- _mesa_memcpy(programCopy, program, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ return;
+ }
+ _mesa_memcpy(programCopy, program, len);
n[1].e = target;
n[2].ui = id;
n[3].i = len;
@@ -4486,15 +4510,17 @@ save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
- if (!idCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
- return;
- }
- _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 2);
if (n) {
+ GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
+ if (!idCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
+ return;
+ }
+ _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
n[1].i = num;
n[2].data = idCopy;
}
@@ -4655,16 +4681,17 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
- if (!nameCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
- return;
- }
- _mesa_memcpy(nameCopy, name, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
if (n) {
+ GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
+ if (!nameCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
+ return;
+ }
+ _mesa_memcpy(nameCopy, name, len);
n[1].ui = id;
n[2].i = len;
n[3].data = nameCopy;
@@ -4753,18 +4780,17 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
- return;
- }
- _mesa_memcpy(programCopy, string, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(programCopy, string, len);
n[1].e = target;
n[2].e = format;
n[3].i = len;
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index 6682b5e725..6d31f32443 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -27,6 +27,7 @@
#include "bufferobj.h"
#include "context.h"
#include "drawpix.h"
+#include "enums.h"
#include "feedback.h"
#include "framebuffer.h"
#include "image.h"
@@ -34,6 +35,18 @@
#include "state.h"
+
+/**
+ * If a fragment program is enabled, check that it's valid.
+ * \return GL_TRUE if valid, GL_FALSE otherwise
+ */
+static GLboolean
+valid_fragment_program(GLcontext *ctx)
+{
+ return !(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled);
+}
+
+
#if _HAVE_FULL_GL
/*
@@ -51,29 +64,34 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
return;
}
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels (invalid fragment program)");
- return;
+ goto end;
}
if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) {
- /* found an error */
- return;
+ /* the error was already recorded */
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glDrawPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -88,13 +106,13 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(invalid PBO access)");
- return;
+ goto end;
}
- if (ctx->Unpack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(PBO is mapped)");
- return;
+ goto end;
}
}
@@ -116,6 +134,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
@@ -126,37 +147,48 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (width < 0 || height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
+ return;
+ }
+
+ if (type != GL_COLOR && type != GL_DEPTH && type != GL_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
+ return;
+ }
+
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels (invalid fragment program)");
- return;
- }
-
- if (width < 0 || height < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
- return;
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glCopyPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!_mesa_source_buffer_exists(ctx, type) ||
!_mesa_dest_buffer_exists(ctx, type)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels(missing source or dest buffer)");
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid || width ==0 || height == 0) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -181,6 +213,9 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
#endif /* _HAVE_FULL_GL */
@@ -208,7 +243,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBitmap (invalid fragment program)");
return;
@@ -235,7 +270,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
"glBitmap(invalid PBO access)");
return;
}
- if (ctx->Unpack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
return;
@@ -264,68 +299,3 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
}
-
-
-
-#if 0 /* experimental */
-/*
- * Execute glDrawDepthPixelsMESA(). This function accepts both a color
- * image and depth (Z) image. Rasterization produces fragments with
- * color and Z taken from these images. This function is intended for
- * Z-compositing. Normally, this operation requires two glDrawPixels
- * calls with stencil testing.
- */
-void GLAPIENTRY
-_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
- GLenum colorFormat, GLenum colorType,
- const GLvoid *colors,
- GLenum depthType, const GLvoid *depths )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (width < 0 || height < 0) {
- _mesa_error( ctx, GL_INVALID_VALUE,
- "glDrawDepthPixelsMESA(width or height < 0" );
- return;
- }
-
- if (!ctx->Current.RasterPosValid) {
- return;
- }
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDrawDepthPixelsMESA(incomplete framebuffer)");
- return;
- }
-
- if (ctx->RenderMode == GL_RENDER) {
- /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
- GLint x = IROUND(ctx->Current.RasterPos[0]);
- GLint y = IROUND(ctx->Current.RasterPos[1]);
- ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
- colorFormat, colorType, colors,
- depthType, depths, &ctx->Unpack);
- }
- else if (ctx->RenderMode == GL_FEEDBACK) {
- /* Feedback the current raster pos info */
- FLUSH_CURRENT( ctx, 0 );
- _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
- _mesa_feedback_vertex( ctx,
- ctx->Current.RasterPos,
- ctx->Current.RasterColor,
- ctx->Current.RasterIndex,
- ctx->Current.RasterTexCoords[0] );
- }
- else {
- ASSERT(ctx->RenderMode == GL_SELECT);
- /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
- }
-}
-
-#endif
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index c60b58a492..8870a20d0e 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -78,6 +78,7 @@ static const struct {
{ OFF, "GL_ARB_texture_non_power_of_two", F(ARB_texture_non_power_of_two)},
{ OFF, "GL_ARB_texture_rectangle", F(NV_texture_rectangle) },
{ ON, "GL_ARB_transpose_matrix", F(ARB_transpose_matrix) },
+ { OFF, "GL_ARB_vertex_array_bgra", F(EXT_vertex_array_bgra) },
{ OFF, "GL_ARB_vertex_array_object", F(ARB_vertex_array_object) },
{ ON, "GL_ARB_vertex_buffer_object", F(ARB_vertex_buffer_object) },
{ OFF, "GL_ARB_vertex_program", F(ARB_vertex_program) },
@@ -413,6 +414,7 @@ _mesa_enable_2_0_extensions(GLcontext *ctx)
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
#endif
ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
#if FEATURE_ARB_shader_objects
ctx->Extensions.ARB_shader_objects = GL_TRUE;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 83301f1e62..825a23090b 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -417,21 +417,22 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
if (format == GL_COLOR) {
if (att->Renderbuffer->_BaseFormat != GL_RGB &&
att->Renderbuffer->_BaseFormat != GL_RGBA) {
- ASSERT(att->Renderbuffer->RedBits);
- ASSERT(att->Renderbuffer->GreenBits);
- ASSERT(att->Renderbuffer->BlueBits);
att_incomplete("bad renderbuffer color format");
att->Complete = GL_FALSE;
return;
}
+ ASSERT(att->Renderbuffer->RedBits);
+ ASSERT(att->Renderbuffer->GreenBits);
+ ASSERT(att->Renderbuffer->BlueBits);
}
else if (format == GL_DEPTH) {
- ASSERT(att->Renderbuffer->DepthBits);
if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else {
@@ -442,12 +443,13 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
}
else {
assert(format == GL_STENCIL);
- ASSERT(att->Renderbuffer->StencilBits);
if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else {
@@ -2038,7 +2040,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
- if (readRb->StencilBits != drawRb->StencilBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->StencilBits != drawRb->StencilBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(stencil buffer size mismatch");
return;
@@ -2048,7 +2052,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
- if (readRb->DepthBits != drawRb->DepthBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->DepthBits != drawRb->DepthBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(depth buffer size mismatch");
return;
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 50a61bd84b..4323d3db82 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -67,7 +67,7 @@ _mesa_Fogiv(GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in _mesa_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_Fogfv(pname, p);
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 5a13c88a7a..dc79b8ca61 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -817,7 +817,7 @@ _mesa_update_framebuffer(GLcontext *ctx)
/**
* Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
- * glCopyTex[Sub]Image, etc. exists.
+ * glCopyTex[Sub]Image, etc) exists.
* \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
* GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
* \return GL_TRUE if buffer exists, GL_FALSE otherwise
@@ -825,8 +825,12 @@ _mesa_update_framebuffer(GLcontext *ctx)
GLboolean
_mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->ReadBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->ReadBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ }
if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -850,10 +854,8 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
return GL_FALSE;
}
- /* XXX enable this post 6.5 release:
ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||
ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);
- */
break;
case GL_DEPTH:
case GL_DEPTH_COMPONENT:
@@ -891,13 +893,17 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
/**
* As above, but for drawing operations.
- * XXX code do some code merging w/ above function.
+ * XXX could do some code merging w/ above function.
*/
GLboolean
_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->DrawBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
+ }
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -918,7 +924,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
case GL_BGRA:
case GL_ABGR_EXT:
case GL_COLOR_INDEX:
- /* nothing special */
+ /* Nothing special since GL_DRAW_BUFFER could be GL_NONE. */
/* Could assert that colorbuffer has RedBits > 0 */
break;
case GL_DEPTH:
@@ -945,7 +951,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
break;
default:
_mesa_problem(ctx,
- "Unexpected format 0x%x in _mesa_source_buffer_exists",
+ "Unexpected format 0x%x in _mesa_dest_buffer_exists",
format);
return GL_FALSE;
}
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 41fd786d7d..6599ed9698 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -266,5 +266,6 @@ _mesa_GetError( void )
_mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+ ctx->ErrorDebugCount = 0;
return e;
}
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index 5fee4fd0e3..726a50d3b1 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -649,7 +649,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack min/max values into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, 2, 1, 1,
@@ -687,7 +687,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
format, type, values, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -733,7 +733,7 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack min/max values into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, ctx->Histogram.Width, 1, 1,
@@ -761,7 +761,7 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
(CONST GLuint (*)[4]) ctx->Histogram.Count,
format, type, values, &ctx->Pack);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 090e5eb330..d77c593ac7 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -531,6 +531,210 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
/**
+ * Test if the given image format is a color/RGBA format (i.e., not color
+ * index, depth, stencil, etc).
+ * \param format the image format value (may by an internal texture format)
+ * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ */
+GLboolean
+_mesa_is_color_format(GLenum format)
+{
+ switch (format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case 3:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ case 4:
+ case GL_ABGR_EXT:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ /* float texture formats */
+ case GL_ALPHA16F_ARB:
+ case GL_ALPHA32F_ARB:
+ case GL_LUMINANCE16F_ARB:
+ case GL_LUMINANCE32F_ARB:
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ case GL_INTENSITY16F_ARB:
+ case GL_INTENSITY32F_ARB:
+ case GL_RGB16F_ARB:
+ case GL_RGB32F_ARB:
+ case GL_RGBA16F_ARB:
+ case GL_RGBA32F_ARB:
+ /* compressed formats */
+ case GL_COMPRESSED_ALPHA:
+ case GL_COMPRESSED_LUMINANCE:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_COMPRESSED_INTENSITY:
+ case GL_COMPRESSED_RGB:
+ case GL_COMPRESSED_RGBA:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+#if FEATURE_EXT_texture_sRGB
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif /* FEATURE_EXT_texture_sRGB */
+ return GL_TRUE;
+ /* signed texture formats */
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_TRUE;
+ case GL_YCBCR_MESA: /* not considered to be RGB */
+ /* fall-through */
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a color index format.
+ */
+GLboolean
+_mesa_is_index_format(GLenum format)
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth component format.
+ */
+GLboolean
+_mesa_is_depth_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a YCbCr format.
+ */
+GLboolean
+_mesa_is_ycbcr_format(GLenum format)
+{
+ switch (format) {
+ case GL_YCBCR_MESA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth+stencil format.
+ */
+GLboolean
+_mesa_is_depthstencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+/**
+ * Test if the given image format is a dudv format.
+ */
+GLboolean
+_mesa_is_dudv_format(GLenum format)
+{
+ switch (format) {
+ case GL_DUDV_ATI:
+ case GL_DU8DV8_ATI:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
* Return the address of a specific pixel in an image (1D, 2D or 3D).
*
* Pixel unpacking/packing parameters are observed according to \p packing.
@@ -5335,3 +5539,181 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
return GL_TRUE;
}
+
+
+/**
+ * Clip dst coords against Xmax (or Ymax).
+ */
+static INLINE void
+clip_right_or_top(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint maxValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX1 > maxValue) {
+ /* X1 outside right edge */
+ ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = maxValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX0 > maxValue) {
+ /* X0 outside right edge */
+ ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = maxValue;
+ bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
+ *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Clip dst coords against Xmin (or Ymin).
+ */
+static INLINE void
+clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint minValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX0 < minValue) {
+ /* X0 outside left edge */
+ ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
+ *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX1 < minValue) {
+ /* X1 outside left edge */
+ ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Do clipping of blit src/dest rectangles.
+ * The dest rect is clipped against both the buffer bounds and scissor bounds.
+ * The src rect is just clipped against the buffer bounds.
+ *
+ * When either the src or dest rect is clipped, the other is also clipped
+ * proportionately!
+ *
+ * Note that X0 need not be less than X1 (same for Y) for either the source
+ * and dest rects. That makes the clipping a little trickier.
+ *
+ * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
+ */
+GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
+{
+ const GLint srcXmin = 0;
+ const GLint srcXmax = ctx->ReadBuffer->Width;
+ const GLint srcYmin = 0;
+ const GLint srcYmax = ctx->ReadBuffer->Height;
+
+ /* these include scissor bounds */
+ const GLint dstXmin = ctx->DrawBuffer->_Xmin;
+ const GLint dstXmax = ctx->DrawBuffer->_Xmax;
+ const GLint dstYmin = ctx->DrawBuffer->_Ymin;
+ const GLint dstYmax = ctx->DrawBuffer->_Ymax;
+
+ /*
+ printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ /* trivial rejection tests */
+ if (*dstX0 == *dstX1)
+ return GL_FALSE; /* no width */
+ if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
+ return GL_FALSE; /* totally out (left) of bounds */
+ if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
+ return GL_FALSE; /* totally out (right) of bounds */
+
+ if (*dstY0 == *dstY1)
+ return GL_FALSE;
+ if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
+ return GL_FALSE;
+ if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
+ return GL_FALSE;
+
+ if (*srcX0 == *srcX1)
+ return GL_FALSE;
+ if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
+ return GL_FALSE;
+ if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
+ return GL_FALSE;
+
+ if (*srcY0 == *srcY1)
+ return GL_FALSE;
+ if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
+ return GL_FALSE;
+ if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
+ return GL_FALSE;
+
+ /*
+ * dest clip
+ */
+ clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
+ clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
+ clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
+ clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
+
+ /*
+ * src clip (just swap src/dst values from above)
+ */
+ clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
+ clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
+ clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
+ clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
+
+ /*
+ printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ ASSERT(*dstX0 >= dstXmin);
+ ASSERT(*dstX0 <= dstXmax);
+ ASSERT(*dstX1 >= dstXmin);
+ ASSERT(*dstX1 <= dstXmax);
+
+ ASSERT(*dstY0 >= dstYmin);
+ ASSERT(*dstY0 <= dstYmax);
+ ASSERT(*dstY1 >= dstYmin);
+ ASSERT(*dstY1 <= dstYmax);
+
+ ASSERT(*srcX0 >= srcXmin);
+ ASSERT(*srcX0 <= srcXmax);
+ ASSERT(*srcX1 >= srcXmin);
+ ASSERT(*srcX1 <= srcXmax);
+
+ ASSERT(*srcY0 >= srcYmin);
+ ASSERT(*srcY0 <= srcYmax);
+ ASSERT(*srcY1 >= srcYmin);
+ ASSERT(*srcY1 <= srcYmax);
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
index b26c27e5a8..20459a5f1e 100644
--- a/src/mesa/main/image.h
+++ b/src/mesa/main/image.h
@@ -54,6 +54,24 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type );
extern GLboolean
_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type );
+extern GLboolean
+_mesa_is_color_format(GLenum format);
+
+extern GLboolean
+_mesa_is_index_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depth_format(GLenum format);
+
+extern GLboolean
+_mesa_is_ycbcr_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depthstencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_dudv_format(GLenum format);
+
extern GLvoid *
_mesa_image_address( GLuint dimensions,
@@ -291,4 +309,10 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
+extern GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
+
+
#endif
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 1722579e82..6ffaddcde9 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -911,6 +911,20 @@ _mesa_strtod( const char *s, char **end )
return strtod(s, end);
}
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++)
+ sum += *c * (i % 100);
+ return sum;
+}
+
+
/*@}*/
@@ -1021,23 +1035,59 @@ output_if_debug(const char *prefixString, const char *outputString,
}
}
-static const char *error_string( GLenum error );
-static void flush_delayed_errors( GLcontext *ctx )
+/**
+ * Return string version of GL error code.
+ */
+static const char *
+error_string( GLenum error )
+{
+ switch (error) {
+ case GL_NO_ERROR:
+ return "GL_NO_ERROR";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "unknown";
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( GLcontext *ctx )
{
- char s2[MAXSTRING];
+ char s[MAXSTRING];
if (ctx->ErrorDebugCount) {
- _mesa_snprintf(s2, MAXSTRING, "%d similar %s errors",
+ _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
ctx->ErrorDebugCount,
error_string(ctx->ErrorValue));
- output_if_debug("Mesa: ", s2, GL_TRUE);
+ output_if_debug("Mesa", s, GL_TRUE);
ctx->ErrorDebugCount = 0;
}
}
+
/**
* Report a warning (a recoverable error condition) to stderr if
* either DEBUG is defined or the MESA_DEBUG env var is set.
@@ -1083,31 +1133,6 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
}
-static const char *error_string( GLenum error )
-{
- switch (error) {
- case GL_NO_ERROR:
- return "GL_NO_ERROR";
- case GL_INVALID_VALUE:
- return "GL_INVALID_VALUE";
- case GL_INVALID_ENUM:
- return "GL_INVALID_ENUM";
- case GL_INVALID_OPERATION:
- return "GL_INVALID_OPERATION";
- case GL_STACK_OVERFLOW:
- return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW:
- return "GL_STACK_UNDERFLOW";
- case GL_OUT_OF_MEMORY:
- return "GL_OUT_OF_MEMORY";
- case GL_TABLE_TOO_LARGE:
- return "GL_TABLE_TOO_LARGE";
- case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
- return "GL_INVALID_FRAMEBUFFER_OPERATION";
- default:
- return "unknown";
- }
-}
/**
* Record an OpenGL state error. These usually occur when the user
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 7b61e22e93..fb85f0862c 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -586,6 +586,9 @@ _mesa_atoi( const char *s );
extern double
_mesa_strtod( const char *s, char **end );
+extern unsigned int
+_mesa_str_checksum(const char *str);
+
extern int
_mesa_sprintf( char *str, const char *fmt, ... );
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 0f0d831fee..10c89f4368 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -528,7 +528,7 @@ _mesa_LightModeliv( GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_LightModelfv( pname, fparam );
}
@@ -1256,15 +1256,15 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state )
ctx->Driver.LightingSpaceChange( ctx );
}
else {
- GLuint new_state = ctx->NewState;
+ GLuint new_state2 = ctx->NewState;
/* Recalculate that same state only if it has been invalidated
* by other statechanges.
*/
- if (new_state & _NEW_MODELVIEW)
+ if (new_state2 & _NEW_MODELVIEW)
update_modelview_scale(ctx);
- if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
compute_light_positions( ctx );
}
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d0309f5e90..41172788ef 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -83,6 +83,7 @@
/*@{*/
struct _mesa_HashTable;
struct gl_attrib_node;
+struct gl_meta_state;
struct gl_pixelstore_attrib;
struct gl_program_cache;
struct gl_texture_format;
@@ -227,7 +228,9 @@ typedef enum
FRAG_ATTRIB_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
+ FRAG_ATTRIB_FACE = 12, /**< front/back face */
+ FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
+ FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
} gl_frag_attrib;
@@ -239,6 +242,8 @@ typedef enum
#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
+#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
+#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
@@ -1834,9 +1839,6 @@ struct gl_fragment_program
struct gl_program Base; /**< base class */
GLenum FogOption;
GLboolean UsesKill; /**< shader uses KIL instruction */
- GLboolean UsesPointCoord; /**< shader uses gl_PointCoord */
- GLboolean UsesFrontFacing; /**< shader used gl_FrontFacing */
- GLboolean UsesFogFragCoord; /**< shader used gl_FogFragCoord */
};
@@ -2004,6 +2006,7 @@ struct gl_shader
GLboolean Main; /**< shader defines main() */
GLboolean UnresolvedRefs;
const GLchar *Source; /**< Source code string */
+ GLuint SourceChecksum; /**< for debug/logging purposes */
struct gl_program *Program; /**< Post-compile assembly code */
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
@@ -2034,6 +2037,7 @@ struct gl_shader_program
struct gl_program_parameter_list *Varying;
GLboolean LinkStatus; /**< GL_LINK_STATUS */
GLboolean Validated;
+ GLboolean _Used; /**< Ever used for drawing? */
GLchar *InfoLog;
};
@@ -2981,6 +2985,8 @@ struct __GLcontextRec
struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
/*@}*/
+ struct gl_meta_state *Meta; /**< for "meta" operations */
+
#if FEATURE_EXT_framebuffer_object
struct gl_renderbuffer *CurrentRenderbuffer;
#endif
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index d9f3e476e8..25f55a422f 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -158,7 +158,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -188,7 +188,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
store_pixelmap(ctx, map, mapsize, values);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -217,7 +217,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -259,7 +259,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -290,7 +290,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -333,7 +333,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -359,7 +359,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -397,7 +397,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat));
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -420,7 +420,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -458,7 +458,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -481,7 +481,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
mapsize = pm ? pm->Size : 0;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -528,7 +528,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index 564250b881..d11c9424d5 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -193,7 +193,7 @@ _mesa_PolygonMode( GLenum face, GLenum mode )
void
_mesa_polygon_stipple(GLcontext *ctx, const GLubyte *pattern)
{
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* Get/unpack the stipple pattern from a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, 32, 32, 1,
@@ -258,7 +258,7 @@ _mesa_GetPolygonStipple( GLubyte *dest )
/* XXX someday we may put this code into a separate function and call
* it with ctx->Driver.GetPolygonStipple().
*/
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Put/pack the stipple pattern into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Pack, 32, 32, 1,
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 2326776ecb..feea1d375f 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -44,6 +44,10 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
GLboolean drawing)
{
const char *readDraw = drawing ? "Draw" : "Read";
+ const GLboolean reading = !drawing;
+
+ /* state validation should have already been done */
+ ASSERT(ctx->NewState == 0x0);
if (ctx->Extensions.EXT_packed_depth_stencil
&& type == GL_UNSIGNED_INT_24_8_EXT
@@ -73,32 +77,45 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
- if (drawing && !ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ if (drawing) {
+ if (!ctx->DrawBuffer->Visual.rgbMode) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(drawing RGB pixels into color index buffer)");
- return GL_TRUE;
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_COLOR_INDEX:
- if (!drawing && ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(reading color index format from RGB buffer)");
- return GL_TRUE;
+ if (drawing) {
+ if (ctx->DrawBuffer->Visual.rgbMode &&
+ (ctx->PixelMaps.ItoR.Size == 0 ||
+ ctx->PixelMaps.ItoG.Size == 0 ||
+ ctx->PixelMaps.ItoB.Size == 0)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(drawing color index pixels into RGB buffer)");
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_STENCIL_INDEX:
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no stencil buffer)", readDraw);
return GL_TRUE;
@@ -118,7 +135,7 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
return GL_TRUE;
}
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no depth or stencil buffer)", readDraw);
return GL_TRUE;
@@ -173,7 +190,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
if (width == 0 || height == 0)
return; /* nothing to do */
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -181,7 +198,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- if (ctx->Pack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
return;
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index ad6e6ce7cd..93bbccd3c7 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -196,7 +196,7 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData)
{
struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
GLcontext *ctx = (GLcontext *) userData;
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->Pointer = NULL;
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index d8191ab518..140a998df2 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -547,7 +547,8 @@ _mesa_update_state_locked( GLcontext *ctx )
/* Determine which state flags effect vertex/fragment program state */
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
prog_flags |= (_NEW_TEXTURE | _NEW_FOG |
- _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE);
+ _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
+ _NEW_PROGRAM);
}
if (ctx->VertexProgram._MaintainTnlProgram) {
prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
@@ -712,6 +713,6 @@ _mesa_set_vp_override(GLcontext *ctx, GLboolean flag)
/* Set one of the bits which will trigger fragment program
* regeneration:
*/
- ctx->NewState |= _NEW_ARRAY;
+ ctx->NewState |= _NEW_PROGRAM;
}
}
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 4c04a7ed37..6d86a4275c 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -35,6 +35,7 @@
#include "main/enums.h"
#include "main/macros.h"
#include "main/texenv.h"
+#include "main/texstate.h"
#define TE_ERROR(errCode, msg, value) \
@@ -466,7 +467,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
switch (pname) {
@@ -793,7 +794,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -857,7 +858,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -908,12 +909,26 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
}
}
-/* why does ATI_envmap_bumpmap require new entrypoints? Should just
- reuse TexEnv ones... */
+
+/**
+ * Why does ATI_envmap_bumpmap require new entrypoints? Should just
+ * reuse TexEnv ones...
+ */
void GLAPIENTRY
_mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
{
GLfloat p[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ /* This isn't an "official" error case, but let's tell the user
+ * that something's wrong.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterivATI");
+ return;
+ }
+
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
/* hope that conversion is correct here */
p[0] = INT_TO_FLOAT( param[0] );
@@ -923,11 +938,12 @@ _mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
}
else {
p[0] = (GLfloat) param[0];
- p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
+ p[1] = p[2] = p[3] = 0.0F; /* init to zero, just to be safe */
}
_mesa_TexBumpParameterfvATI( pname, p );
}
+
void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
{
@@ -935,8 +951,12 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
if (TEST_EQ_4V(param, texUnit->RotMatrix))
@@ -955,17 +975,21 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterivATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
@@ -982,12 +1006,13 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
param[3] = FLOAT_TO_INT(texUnit->RotMatrix[3]);
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = temp;
+ *param = count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1002,23 +1027,27 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
Don't think anyone would ever want to use it
(and apps might not understand it) so hardcode this. */
- *param = (GLfloat) 4;
+ *param = 4.0F;
}
else if (pname == GL_BUMP_ROT_MATRIX_ATI) {
param[0] = texUnit->RotMatrix[0];
@@ -1027,12 +1056,13 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
param[3] = texUnit->RotMatrix[3];
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = (GLfloat) temp;
+ *param = (GLfloat) count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1046,4 +1076,3 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
return;
}
}
-
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 6b090ff399..3736138b9e 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -275,6 +275,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
{
/* _NEW_PROGRAM */
const GLboolean vertexShader = (ctx->Shader.CurrentProgram &&
+ ctx->Shader.CurrentProgram->LinkStatus &&
ctx->Shader.CurrentProgram->VertexProgram);
const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
GLbitfield fp_inputs = 0x0;
@@ -321,8 +322,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
/* Then look at what might be varying as a result of enabled
* arrays, etc:
*/
- if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0;
- if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1;
+ if (varying_inputs & VERT_BIT_COLOR0)
+ fp_inputs |= FRAG_BIT_COL0;
+ if (varying_inputs & VERT_BIT_COLOR1)
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0)
<< FRAG_ATTRIB_TEX0);
@@ -340,7 +343,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (vertexShader)
vprog = ctx->Shader.CurrentProgram->VertexProgram;
else
- vprog = ctx->VertexProgram._Current;
+ vprog = ctx->VertexProgram.Current;
vp_outputs = vprog->Base.OutputsWritten;
@@ -351,8 +354,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (ctx->Point.PointSprite)
vp_outputs |= FRAG_BITS_TEX_ANY;
- if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0;
- if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1;
+ if (vp_outputs & (1 << VERT_RESULT_COL0))
+ fp_inputs |= FRAG_BIT_COL0;
+ if (vp_outputs & (1 << VERT_RESULT_COL1))
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0)
<< FRAG_ATTRIB_TEX0);
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 02409d8009..14d6fc7659 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -30,11 +30,14 @@
#include "glheader.h"
+#include "bufferobj.h"
#include "context.h"
#include "image.h"
#include "texcompress.h"
#include "texformat.h"
#include "texgetimage.h"
+#include "teximage.h"
+#include "texstate.h"
@@ -116,7 +119,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
{
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Packing texture image into a PBO.
* Map the (potentially) VRAM-based buffer into our process space so
* we can write into it with the code below.
@@ -296,7 +299,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
} /* img */
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -316,7 +319,7 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
{
GLuint size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack texture image into a PBO */
GLubyte *buf;
if ((const GLubyte *) img + texImage->CompressedSize >
@@ -349,8 +352,230 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
/* just memcpy, no pixelstore or pixel transfer */
_mesa_memcpy(img, texImage->Data, size);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
}
+
+
+
+/**
+ * Do error checking for a glGetTexImage() call.
+ * \return GL_TRUE if any error, GL_FALSE if no errors.
+ */
+static GLboolean
+getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+
+ if (maxLevels == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target);
+ return GL_TRUE;
+ }
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_sizeof_packed_type(type) <= 0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_components_in_format(format) <= 0 ||
+ format == GL_STENCIL_INDEX) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_packed_depth_stencil
+ && _mesa_is_depthstencil_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap
+ && _mesa_is_dudv_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ if (!texObj || _mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+ return GL_TRUE;
+ }
+
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (!texImage) {
+ /* out of memory */
+ return GL_TRUE;
+ }
+
+ /* Make sure the requested image format is compatible with the
+ * texture's format. Note that a color index texture can be converted
+ * to RGBA so that combo is allowed.
+ */
+ if (_mesa_is_color_format(format)
+ && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_index_format(format)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depth_format(format)
+ && !_mesa_is_depth_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_ycbcr_format(format)
+ && !_mesa_is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depthstencil_format(format)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_dudv_format(format)
+ && !_mesa_is_dudv_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
+ /* packing texture image into a PBO */
+ const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
+ texImage->Height, texImage->Depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexImage(invalid PBO access)");
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+
+/**
+ * Get texture image. Called by glGetTexImage.
+ *
+ * \param target texture target.
+ * \param level image level.
+ * \param format pixel data format for returned image.
+ * \param type pixel data type for returned image.
+ * \param pixels returned pixel data.
+ */
+void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* typically, this will call _mesa_get_teximage() */
+ ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLint maxLevels;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (_mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return;
+ }
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (texImage) {
+ if (texImage->IsCompressed) {
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
+ texObj, texImage);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImageARB");
+ }
+ }
+ else {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetCompressedTexImageARB(level)");
+ }
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h
index 01f486e8f0..088d27c7e1 100644
--- a/src/mesa/main/texgetimage.h
+++ b/src/mesa/main/texgetimage.h
@@ -43,4 +43,13 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+extern void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
+
+
#endif /* TEXGETIMAGE_H */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 825f5e26bf..8228303040 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -182,6 +182,8 @@ logbase2( int n )
*
* This is the format which is used during texture application (i.e. the
* texture format and env mode determine the arithmetic used.
+ *
+ * XXX this could be static
*/
GLint
_mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
@@ -415,211 +417,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
/**
- * Test if the given image format is a color/RGBA format (i.e., not color
- * index, depth, stencil, etc).
- * \param format the image format value (may by an internal texture format)
- * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
- * XXX maybe move this func to image.c
- */
-GLboolean
-_mesa_is_color_format(GLenum format)
-{
- switch (format) {
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case 3:
- case GL_RGB:
- case GL_BGR:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- case 4:
- case GL_ABGR_EXT:
- case GL_RGBA:
- case GL_BGRA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- /* float texture formats */
- case GL_ALPHA16F_ARB:
- case GL_ALPHA32F_ARB:
- case GL_LUMINANCE16F_ARB:
- case GL_LUMINANCE32F_ARB:
- case GL_LUMINANCE_ALPHA16F_ARB:
- case GL_LUMINANCE_ALPHA32F_ARB:
- case GL_INTENSITY16F_ARB:
- case GL_INTENSITY32F_ARB:
- case GL_RGB16F_ARB:
- case GL_RGB32F_ARB:
- case GL_RGBA16F_ARB:
- case GL_RGBA32F_ARB:
- /* compressed formats */
- case GL_COMPRESSED_ALPHA:
- case GL_COMPRESSED_LUMINANCE:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- case GL_COMPRESSED_INTENSITY:
- case GL_COMPRESSED_RGB:
- case GL_COMPRESSED_RGBA:
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
-#if FEATURE_EXT_texture_sRGB
- case GL_SRGB_EXT:
- case GL_SRGB8_EXT:
- case GL_SRGB_ALPHA_EXT:
- case GL_SRGB8_ALPHA8_EXT:
- case GL_SLUMINANCE_ALPHA_EXT:
- case GL_SLUMINANCE8_ALPHA8_EXT:
- case GL_SLUMINANCE_EXT:
- case GL_SLUMINANCE8_EXT:
- case GL_COMPRESSED_SRGB_EXT:
- case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_SLUMINANCE_EXT:
- case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
-#endif /* FEATURE_EXT_texture_sRGB */
- return GL_TRUE;
- /* signed texture formats */
- case GL_RGBA_SNORM:
- case GL_RGBA8_SNORM:
- return GL_TRUE;
- case GL_YCBCR_MESA: /* not considered to be RGB */
- /* fall-through */
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a color index format.
- */
-static GLboolean
-is_index_format(GLenum format)
-{
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a depth component format.
- */
-static GLboolean
-is_depth_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- case GL_DEPTH_COMPONENT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a YCbCr format.
- */
-static GLboolean
-is_ycbcr_format(GLenum format)
-{
- switch (format) {
- case GL_YCBCR_MESA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a Depth/Stencil format.
- */
-static GLboolean
-is_depthstencil_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH24_STENCIL8_EXT:
- case GL_DEPTH_STENCIL_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-/**
- * Test if the given image format is a dudv format.
- */
-static GLboolean
-is_dudv_format(GLenum format)
-{
- switch (format) {
- case GL_DUDV_ATI:
- case GL_DU8DV8_ATI:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
* Test if it is a supported compressed format.
*
* \param internalFormat the internal format token provided by the user.
@@ -765,6 +562,9 @@ _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
GLboolean
_mesa_is_proxy_texture(GLenum target)
{
+ /* NUM_TEXTURE_TARGETS should match number of terms below */
+ assert(NUM_TEXTURE_TARGETS == 7);
+
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
target == GL_PROXY_TEXTURE_3D ||
@@ -776,18 +576,6 @@ _mesa_is_proxy_texture(GLenum target)
/**
- * Return pointer to current texture unit.
- * This the texture unit set by glActiveTexture(), not glClientActiveTexture().
- */
-static INLINE struct gl_texture_unit *
-get_current_tex_unit(GLcontext *ctx)
-{
- ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
- return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
-}
-
-
-/**
* Get the texture object that corresponds to the target of the given texture unit.
*
* \param ctx GL context.
@@ -996,10 +784,6 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_PROXY_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
return ctx->Const.MaxTextureLevels;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
@@ -1012,10 +796,17 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
case GL_TEXTURE_CUBE_MAP_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- return ctx->Const.MaxCubeTextureLevels;
+ return ctx->Extensions.ARB_texture_cube_map
+ ? ctx->Const.MaxCubeTextureLevels : 0;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return 1;
+ return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array
+ ? ctx->Const.MaxTextureLevels : 0;
default:
return 0; /* bad target */
}
@@ -1216,6 +1007,23 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
/**
+ * Free and clear fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param texImage texture image structure to be cleared.
+ *
+ * After the call, \p texImage will have no data associated with it. Its
+ * fields are cleared so that its parent object will test incomplete.
+ */
+void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage)
+{
+ ctx->Driver.FreeTexImageData(ctx, texImage);
+ clear_teximage_fields(texImage);
+}
+
+
+/**
* This is the fallback for Driver.TestProxyTexImage(). Test the texture
* level, width, height and depth against the ctx->Const limits for textures.
*
@@ -1529,13 +1337,13 @@ texture_error_check( GLcontext *ctx, GLenum target,
/* make sure internal format and format basically agree */
colorFormat = _mesa_is_color_format(format);
- indexFormat = is_index_format(format);
+ indexFormat = _mesa_is_index_format(format);
if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
- (is_index_format(internalFormat) && !indexFormat) ||
- (is_depth_format(internalFormat) != is_depth_format(format)) ||
- (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
- (is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
- (is_dudv_format(internalFormat) != is_dudv_format(format))) {
+ (_mesa_is_index_format(internalFormat) && !indexFormat) ||
+ (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
+ (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
+ (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
+ (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
@@ -1970,7 +1778,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depth_format(internalFormat)) {
+ else if (_mesa_is_depth_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1978,7 +1786,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depthstencil_format(internalFormat)) {
+ else if (_mesa_is_depthstencil_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2203,169 +2011,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
-/**
- * Do error checking for a glGetTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
- */
-static GLboolean
-getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
-
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
- return GL_TRUE;
- }
-
- if (_mesa_sizeof_packed_type(type) <= 0) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
- return GL_TRUE;
- }
-
- if (_mesa_components_in_format(format) <= 0 ||
- format == GL_STENCIL_INDEX) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_packed_depth_stencil
- && is_depthstencil_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ATI_envmap_bumpmap
- && is_dudv_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* out of memory */
- return GL_TRUE;
- }
-
- /* Make sure the requested image format is compatible with the
- * texture's format. Note that a color index texture can be converted
- * to RGBA so that combo is allowed.
- */
- if (_mesa_is_color_format(format)
- && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_index_format(format)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_depth_format(format)
- && !is_depth_format(texImage->TexFormat->BaseFormat)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_ycbcr_format(format)
- && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_depthstencil_format(format)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_dudv_format(format)
- && !is_dudv_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
-
- if (ctx->Pack.BufferObj->Name) {
- /* packing texture image into a PBO */
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
- texImage->Height, texImage->Depth,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexImage(invalid PBO access)");
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
-}
-
-
-
-/**
- * Get texture image. Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param pixels returned pixel data.
- */
-void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj || _mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
- return;
- }
-
- if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, texObj, target, level);
-
- /* typically, this will call _mesa_get_teximage() */
- ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
- texObj, texImage);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
/** Callback info for walking over FBO hash table */
struct cb_info
{
@@ -2509,7 +2154,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2617,7 +2262,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2720,7 +2365,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2826,7 +2471,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
assert(texObj);
@@ -2886,7 +2531,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2938,7 +2583,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -2999,7 +2644,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
postConvWidth, 1, border))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3065,7 +2710,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
postConvWidth, postConvHeight, border))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3125,7 +2770,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 1, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3180,7 +2825,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 2, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3235,7 +2880,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 3, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3489,7 +3134,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3543,7 +3188,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3586,7 +3231,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3642,7 +3287,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3682,7 +3327,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3736,7 +3381,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3775,7 +3420,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3832,7 +3477,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3889,7 +3534,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3926,55 +3571,3 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
}
-void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLint maxLevels;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
- return;
- }
-
- maxLevels = _mesa_max_texture_levels(ctx, target);
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
- return;
- }
-
- if (_mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (texImage) {
- if (texImage->IsCompressed) {
- /* this typically calls _mesa_get_compressed_teximage() */
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
- texObj, texImage);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImageARB");
- }
- }
- else {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(level)");
- }
- }
- _mesa_unlock_texture(ctx, texObj);
-}
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index eb60a1fa8f..094177da79 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -73,6 +73,10 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
extern void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage);
+
+
+extern void
_mesa_set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
struct gl_texture_image *texImage);
@@ -111,10 +115,6 @@ extern GLuint
_mesa_tex_target_to_face(GLenum target);
-extern GLboolean
-_mesa_is_color_format(GLenum format);
-
-
/**
* Lock a texture for updating. See also _mesa_lock_context_textures().
*/
@@ -164,11 +164,6 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
extern void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels );
-
-
-extern void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
GLsizei width,
GLenum format, GLenum type,
@@ -260,9 +255,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data);
-extern void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
-
/*@}*/
#endif
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 2082f945f1..d09c439250 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -261,6 +261,32 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
/**
+ * Clear all texture images of the given texture object.
+ *
+ * \param ctx GL context.
+ * \param t texture object.
+ *
+ * \sa _mesa_clear_texture_image().
+ */
+void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+ GLuint i, j;
+
+ if (texObj->Target == 0)
+ return;
+
+ for (i = 0; i < MAX_FACES; i++) {
+ for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
+ struct gl_texture_image *texImage = texObj->Image[i][j];
+ if (texImage)
+ _mesa_clear_texture_image(ctx, texImage);
+ }
+ }
+}
+
+
+/**
* Check if the given texture object is valid by examining its Target field.
* For debugging only.
*/
@@ -308,7 +334,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
GLboolean deleteFlag = GL_FALSE;
struct gl_texture_object *oldTex = *ptr;
- assert(valid_texture_object(oldTex));
+ ASSERT(valid_texture_object(oldTex));
_glthread_LOCK_MUTEX(oldTex->Mutex);
ASSERT(oldTex->RefCount > 0);
@@ -331,7 +357,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
if (tex) {
/* reference new texture */
- assert(valid_texture_object(tex));
+ ASSERT(valid_texture_object(tex));
_glthread_LOCK_MUTEX(tex->Mutex);
if (tex->RefCount == 0) {
/* this texture's being deleted (look just above) */
@@ -665,6 +691,24 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
/**
+ * Mark a texture object dirty. It forces the object to be incomplete
+ * and optionally forces the context to re-validate its state.
+ *
+ * \param ctx GL context.
+ * \param texObj texture object.
+ * \param invalidate_state also invalidate context state.
+ */
+void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state)
+{
+ texObj->_Complete = GL_FALSE;
+ if (invalidate_state)
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+/**
* Return pointer to a default/fallback texture.
* The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1).
* That's the value a sampler should get when sampling from an
@@ -715,7 +759,6 @@ _mesa_get_fallback_texture(GLcontext *ctx)
}
-
/*@}*/
@@ -1160,10 +1203,9 @@ _mesa_IsTexture( GLuint texture )
/**
- * Simplest implementation of texture locking: Grab the a new mutex in
- * the shared context. Examine the shared context state timestamp and
- * if there has been a change, set the appropriate bits in
- * ctx->NewState.
+ * Simplest implementation of texture locking: grab the shared tex
+ * mutex. Examine the shared context state timestamp and if there has
+ * been a change, set the appropriate bits in ctx->NewState.
*
* This is used to deal with synchronizing things when a texture object
* is used/modified by different contexts (or threads) which are sharing
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 2599c0816a..9bfebd45c8 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -58,6 +58,9 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
extern void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *obj);
+
+extern void
_mesa_reference_texobj(struct gl_texture_object **ptr,
struct gl_texture_object *tex);
@@ -65,6 +68,10 @@ extern void
_mesa_test_texobj_completeness( const GLcontext *ctx,
struct gl_texture_object *obj );
+extern void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state);
+
extern struct gl_texture_object *
_mesa_get_fallback_texture(GLcontext *ctx);
@@ -76,7 +83,6 @@ _mesa_lock_context_textures( GLcontext *ctx );
/*@}*/
-
/**
* \name API functions
*/
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index d27c59381c..05d144270e 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -38,6 +38,7 @@
#include "main/texcompress.h"
#include "main/texparam.h"
#include "main/teximage.h"
+#include "main/texstate.h"
#include "shader/prog_instruction.h"
@@ -88,7 +89,7 @@ get_texobj(GLcontext *ctx, GLenum target)
return NULL;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
switch (target) {
case GL_TEXTURE_1D:
@@ -716,44 +717,6 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
}
-static GLuint
-tex_image_dimensions(GLcontext *ctx, GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_PROXY_TEXTURE_1D:
- return 1;
- case GL_TEXTURE_2D:
- case GL_PROXY_TEXTURE_2D:
- return 2;
- case GL_TEXTURE_3D:
- case GL_PROXY_TEXTURE_3D:
- return 3;
- case GL_TEXTURE_CUBE_MAP:
- case GL_PROXY_TEXTURE_CUBE_MAP:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 2 : 0;
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 3 : 0;
- default:
- _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
- return 0;
- }
-}
-
-
void GLAPIENTRY
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
GLenum pname, GLint *params )
@@ -761,7 +724,6 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
const struct gl_texture_image *img = NULL;
- GLuint dimensions;
GLboolean isProxy;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
@@ -773,19 +735,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
/* this will catch bad target values */
- dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
- if (dimensions == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
- return;
- }
-
maxLevels = _mesa_max_texture_levels(ctx, target);
if (maxLevels == 0) {
- /* should not happen since <target> was just checked above */
- _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(target=0x%x)", target);
return;
}
@@ -1002,7 +958,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
@@ -1169,7 +1125,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
index a7d7088c62..17ac68000c 100644
--- a/src/mesa/main/texstate.h
+++ b/src/mesa/main/texstate.h
@@ -35,6 +35,18 @@
#include "mtypes.h"
+/**
+ * Return pointer to current texture unit.
+ * This the texture unit set by glActiveTexture(), not glClientActiveTexture().
+ */
+static INLINE struct gl_texture_unit *
+_mesa_get_current_tex_unit(GLcontext *ctx)
+{
+ ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
+ return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+}
+
+
extern void
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst );
@@ -48,16 +60,14 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit );
*/
/*@{*/
-
-/*
- * GL_ARB_multitexture
- */
extern void GLAPIENTRY
_mesa_ActiveTextureARB( GLenum target );
extern void GLAPIENTRY
_mesa_ClientActiveTextureARB( GLenum target );
+/*@}*/
+
/**
* \name Initialization, state maintenance
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index bfced1b3f4..a22db628d3 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -3138,7 +3138,7 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
{
GLubyte *buf;
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
return pixels;
}
@@ -3174,7 +3174,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
{
GLubyte *buf;
- if (packing->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(packing->BufferObj)) {
/* not using a PBO - return pointer unchanged */
return pixels;
}
@@ -3204,7 +3204,7 @@ void
_mesa_unmap_teximage_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 3d5b8faecf..be1c03cec2 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -135,7 +135,8 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -186,7 +187,8 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -265,7 +267,8 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -415,7 +418,8 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -476,7 +480,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -610,7 +615,8 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -1093,6 +1099,29 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
/**
+ * Copy one client vertex array to another.
+ */
+void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src)
+{
+ dst->Size = src->Size;
+ dst->Type = src->Type;
+ dst->Format = src->Format;
+ dst->Stride = src->Stride;
+ dst->StrideB = src->StrideB;
+ dst->Ptr = src->Ptr;
+ dst->Enabled = src->Enabled;
+ dst->Normalized = src->Normalized;
+ dst->_ElementSize = src->_ElementSize;
+ _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
+ dst->_MaxElement = src->_MaxElement;
+}
+
+
+
+/**
* Print vertex array's fields.
*/
static void
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index d4d505ae04..becc67c29d 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -161,6 +161,12 @@ _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
extern void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src);
+
+
+extern void
_mesa_print_arrays(GLcontext *ctx);
extern void
diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
index 50e0402d27..309308c983 100644
--- a/src/mesa/main/viewport.c
+++ b/src/mesa/main/viewport.c
@@ -120,6 +120,10 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval)
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval);
+ if (ctx->Viewport.Near == nearval &&
+ ctx->Viewport.Far == farval)
+ return;
+
ctx->Viewport.Near = (GLfloat) CLAMP(nearval, 0.0, 1.0);
ctx->Viewport.Far = (GLfloat) CLAMP(farval, 0.0, 1.0);
ctx->NewState |= _NEW_VIEWPORT;
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 0f530ebb8a..381445c0e8 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -3975,13 +3975,6 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
if (program->FogOption)
program->Base.InputsRead |= FRAG_BIT_FOGC;
- /* XXX: assume that ARB fragment programs don't have access to the
- * FrontFacing and PointCoord values stuffed into the fog
- * coordinate in GLSL shaders.
- */
- if (program->Base.InputsRead & FRAG_BIT_FOGC)
- program->UsesFogFragCoord = GL_TRUE;
-
if (program->Base.Instructions)
_mesa_free(program->Base.Instructions);
program->Base.Instructions = ap.Base.Instructions;
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index cef0288a9c..3c1c17e099 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -933,7 +933,7 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
return;
}
- fprintf(f, "/* Shader %u source */\n", shader->Name);
+ fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
fputs(shader->Source, f);
fprintf(f, "\n");
@@ -958,3 +958,35 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
}
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog)
+{
+ const char *type;
+ char filename[100];
+ FILE *f;
+
+ if (shader->Type == GL_FRAGMENT_SHADER)
+ type = "frag";
+ else
+ type = "vert";
+
+ _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "a"); /* append */
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for appending\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* First-draw parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, prog->Parameters);
+ fprintf(f, "*/\n");
+
+ fclose(f);
+}
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
index 3da3e767cd..fc286ded54 100644
--- a/src/mesa/shader/prog_print.h
+++ b/src/mesa/shader/prog_print.h
@@ -86,5 +86,9 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list);
extern void
_mesa_write_shader_to_file(const struct gl_shader *shader);
+extern void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog);
+
#endif /* PROG_PRINT_H */
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
index ac5fe0f691..f70c75cec8 100644
--- a/src/mesa/shader/programopt.c
+++ b/src/mesa/shader/programopt.c
@@ -396,7 +396,6 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
fprog->Base.Instructions = newInst;
fprog->Base.NumInstructions = inst - newInst;
fprog->Base.InputsRead |= FRAG_BIT_FOGC;
- fprog->UsesFogFragCoord = GL_TRUE;
/* XXX do this? fprog->FogOption = GL_NONE; */
}
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 648fbc186b..cf0a902389 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -885,7 +885,7 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
static struct gl_program_parameter *
get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
{
- const struct gl_program *prog;
+ const struct gl_program *prog = NULL;
GLint progPos;
progPos = shProg->Uniforms->Uniforms[index].VertPos;
@@ -915,7 +915,7 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
GLenum *type, GLchar *nameOut)
{
const struct gl_shader_program *shProg;
- const struct gl_program *prog;
+ const struct gl_program *prog = NULL;
const struct gl_program_parameter *param;
GLint progPos;
@@ -1431,6 +1431,9 @@ _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
}
sh->Source = source;
sh->CompileStatus = GL_FALSE;
+#ifdef DEBUG
+ sh->SourceChecksum = _mesa_str_checksum(sh->Source);
+#endif
}
@@ -1506,9 +1509,10 @@ _mesa_use_program(GLcontext *ctx, GLuint program)
GLuint i;
_mesa_printf("Use Shader %u\n", shProg->Name);
for (i = 0; i < shProg->NumShaders; i++) {
- _mesa_printf(" shader %u, type 0x%x\n",
+ _mesa_printf(" shader %u, type 0x%x, checksum %u\n",
shProg->Shaders[i]->Name,
- shProg->Shaders[i]->Type);
+ shProg->Shaders[i]->Type,
+ shProg->Shaders[i]->SourceChecksum);
}
if (shProg->VertexProgram)
printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
index 289d94644f..ad2e306c19 100644
--- a/src/mesa/shader/slang/slang_builtin.c
+++ b/src/mesa/shader/slang/slang_builtin.c
@@ -710,3 +710,186 @@ _slang_alloc_statevar(slang_ir_node *n,
*direct = GL_FALSE;
return alloc_state_var_array(n->Var, paramList);
}
+
+
+
+
+#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/** Predefined shader inputs */
+struct input_info
+{
+ const char *Name;
+ GLuint Attrib;
+ GLenum Type;
+ GLuint Swizzle;
+};
+
+/** Predefined vertex shader inputs/attributes */
+static const struct input_info vertInputs[] = {
+ { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP },
+ { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX },
+ { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { NULL, 0, SWIZZLE_NOOP }
+};
+
+/** Predefined fragment shader inputs */
+static const struct input_info fragInputs[] = {
+ { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ /* note: we're packing several quantities into the fogcoord vector */
+ { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX },
+ { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX },
+ { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW },
+ { NULL, 0, SWIZZLE_NOOP }
+};
+
+
+/**
+ * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
+ * a vertex or fragment program input variable. Return -1 if the input
+ * name is invalid.
+ * XXX return size too
+ */
+GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
+{
+ const struct input_info *inputs;
+ GLuint i;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ inputs = vertInputs;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ inputs = fragInputs;
+ break;
+ /* XXX geom program */
+ default:
+ _mesa_problem(NULL, "bad target in _slang_input_index");
+ return -1;
+ }
+
+ ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
+
+ for (i = 0; inputs[i].Name; i++) {
+ if (strcmp(inputs[i].Name, name) == 0) {
+ /* found */
+ *swizzleOut = inputs[i].Swizzle;
+ return inputs[i].Attrib;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Return name of the given vertex attribute (VERT_ATTRIB_x).
+ */
+const char *
+_slang_vert_attrib_name(GLuint attrib)
+{
+ GLuint i;
+ assert(attrib < VERT_ATTRIB_GENERIC0);
+ for (i = 0; vertInputs[i].Name; i++) {
+ if (vertInputs[i].Attrib == attrib)
+ return vertInputs[i].Name;
+ }
+ return NULL;
+}
+
+
+/**
+ * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex
+ * attribute (VERT_ATTRIB_x).
+ */
+GLenum
+_slang_vert_attrib_type(GLuint attrib)
+{
+ GLuint i;
+ assert(attrib < VERT_ATTRIB_GENERIC0);
+ for (i = 0; vertInputs[i].Name; i++) {
+ if (vertInputs[i].Attrib == attrib)
+ return vertInputs[i].Type;
+ }
+ return GL_NONE;
+}
+
+
+
+
+
+/** Predefined shader output info */
+struct output_info
+{
+ const char *Name;
+ GLuint Attrib;
+};
+
+/** Predefined vertex shader outputs */
+static const struct output_info vertOutputs[] = {
+ { "gl_Position", VERT_RESULT_HPOS },
+ { "gl_FrontColor", VERT_RESULT_COL0 },
+ { "gl_BackColor", VERT_RESULT_BFC0 },
+ { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
+ { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
+ { "gl_TexCoord", VERT_RESULT_TEX0 },
+ { "gl_FogFragCoord", VERT_RESULT_FOGC },
+ { "gl_PointSize", VERT_RESULT_PSIZ },
+ { NULL, 0 }
+};
+
+/** Predefined fragment shader outputs */
+static const struct output_info fragOutputs[] = {
+ { "gl_FragColor", FRAG_RESULT_COLOR },
+ { "gl_FragDepth", FRAG_RESULT_DEPTH },
+ { "gl_FragData", FRAG_RESULT_DATA0 },
+ { NULL, 0 }
+};
+
+
+/**
+ * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
+ * a vertex or fragment program output variable. Return -1 for an invalid
+ * output name.
+ */
+GLint
+_slang_output_index(const char *name, GLenum target)
+{
+ const struct output_info *outputs;
+ GLuint i;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ outputs = vertOutputs;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ outputs = fragOutputs;
+ break;
+ /* XXX geom program */
+ default:
+ _mesa_problem(NULL, "bad target in _slang_output_index");
+ return -1;
+ }
+
+ for (i = 0; outputs[i].Name; i++) {
+ if (strcmp(outputs[i].Name, name) == 0) {
+ /* found */
+ return outputs[i].Attrib;
+ }
+ }
+ return -1;
+}
diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h
index 7f6fe80fcc..f814d11ac7 100644
--- a/src/mesa/shader/slang/slang_builtin.h
+++ b/src/mesa/shader/slang/slang_builtin.h
@@ -37,4 +37,18 @@ _slang_alloc_statevar(slang_ir_node *n,
GLboolean *direct);
+extern GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut);
+
+extern GLint
+_slang_output_index(const char *name, GLenum target);
+
+
+extern const char *
+_slang_vert_attrib_name(GLuint attrib);
+
+extern GLenum
+_slang_vert_attrib_type(GLuint attrib);
+
+
#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 2b7e781f98..349f432dec 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -46,6 +46,7 @@
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#include "slang_typeinfo.h"
+#include "slang_builtin.h"
#include "slang_codegen.h"
#include "slang_compile.h"
#include "slang_label.h"
@@ -342,109 +343,6 @@ slang_operation_identifier(slang_operation *oper,
}
-#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-/**
- * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
- * a vertex or fragment program input variable. Return -1 if the input
- * name is invalid.
- * XXX return size too
- */
-static GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
-{
- struct input_info {
- const char *Name;
- GLuint Attrib;
- GLuint Swizzle;
- };
- static const struct input_info vertInputs[] = {
- { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP },
- { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP },
- { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP },
- { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP },
- { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX },
- { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP },
- { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP },
- { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP },
- { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP },
- { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP },
- { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP },
- { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP },
- { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP },
- { NULL, 0, SWIZZLE_NOOP }
- };
- static const struct input_info fragInputs[] = {
- { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },
- { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },
- { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP },
- { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP },
- /* note: we're packing several quantities into the fogcoord vector */
- { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },
- { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/
- { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW },
- { NULL, 0, SWIZZLE_NOOP }
- };
- GLuint i;
- const struct input_info *inputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;
-
- ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
-
- for (i = 0; inputs[i].Name; i++) {
- if (strcmp(inputs[i].Name, name) == 0) {
- /* found */
- *swizzleOut = inputs[i].Swizzle;
- return inputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-/**
- * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
- * a vertex or fragment program output variable. Return -1 for an invalid
- * output name.
- */
-static GLint
-_slang_output_index(const char *name, GLenum target)
-{
- struct output_info {
- const char *Name;
- GLuint Attrib;
- };
- static const struct output_info vertOutputs[] = {
- { "gl_Position", VERT_RESULT_HPOS },
- { "gl_FrontColor", VERT_RESULT_COL0 },
- { "gl_BackColor", VERT_RESULT_BFC0 },
- { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
- { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
- { "gl_TexCoord", VERT_RESULT_TEX0 },
- { "gl_FogFragCoord", VERT_RESULT_FOGC },
- { "gl_PointSize", VERT_RESULT_PSIZ },
- { NULL, 0 }
- };
- static const struct output_info fragOutputs[] = {
- { "gl_FragColor", FRAG_RESULT_COLOR },
- { "gl_FragDepth", FRAG_RESULT_DEPTH },
- { "gl_FragData", FRAG_RESULT_DATA0 },
- { NULL, 0 }
- };
- GLuint i;
- const struct output_info *outputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;
-
- for (i = 0; outputs[i].Name; i++) {
- if (strcmp(outputs[i].Name, name) == 0) {
- /* found */
- return outputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
/**
* Called when we begin code/IR generation for a new while/do/for loop.
*/
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index f6032d1e9a..1caf5946fd 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -40,6 +40,7 @@
#include "shader/prog_statevars.h"
#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
+#include "slang_builtin.h"
#include "slang_link.h"
@@ -327,6 +328,7 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
GLuint i, j;
GLbitfield usedAttributes; /* generics only, not legacy attributes */
+ GLbitfield inputsRead = 0x0;
assert(origProg != linkedProg);
assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
@@ -370,6 +372,10 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
for (i = 0; i < linkedProg->NumInstructions; i++) {
struct prog_instruction *inst = linkedProg->Instructions + i;
for (j = 0; j < 3; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_INPUT) {
+ inputsRead |= (1 << inst->SrcReg[j].Index);
+ }
+
if (inst->SrcReg[j].File == PROGRAM_INPUT &&
inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
/*
@@ -431,6 +437,20 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
}
}
+ /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
+ * When the user queries the active attributes we need to include both
+ * the user-defined attributes and the built-in ones.
+ */
+ for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
+ if (inputsRead & (1 << i)) {
+ _mesa_add_attribute(linkedProg->Attributes,
+ _slang_vert_attrib_name(i),
+ 4, /* size in floats */
+ _slang_vert_attrib_type(i),
+ -1 /* attrib/input */);
+ }
+ }
+
return GL_TRUE;
}
@@ -484,20 +504,6 @@ _slang_update_inputs_outputs(struct gl_program *prog)
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
prog->InputsRead |= 1 << inst->SrcReg[j].Index;
- if (prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
- inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) {
- /* The fragment shader FOGC input is used for fog,
- * front-facing and sprite/point coord.
- */
- struct gl_fragment_program *fp = fragment_program(prog);
- const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0);
- if (swz == SWIZZLE_X)
- fp->UsesFogFragCoord = GL_TRUE;
- else if (swz == SWIZZLE_Y)
- fp->UsesFrontFacing = GL_TRUE;
- else if (swz == SWIZZLE_Z || swz == SWIZZLE_W)
- fp->UsesPointCoord = GL_TRUE;
- }
}
else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index b4b36368cf..d1c109c2c5 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -303,7 +303,8 @@ SPARC_API = \
sparc/glapi_sparc.S
COMMON_DRIVER_SOURCES = \
- drivers/common/driverfuncs.c
+ drivers/common/driverfuncs.c \
+ drivers/common/meta.c
# Sources for building non-Gallium drivers
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 8b3bb5cc03..ee649be885 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -139,23 +139,6 @@ find_translated_vp(struct st_context *st,
if (fragInputsRead & (1 << inAttr)) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
- if (((1 << inAttr) & FRAG_BIT_FOGC)) {
- /* leave placeholders for the
- * extra registers we extract from fog */
- if (stfp->Base.UsesFrontFacing) {
- if (!stfp->Base.UsesFogFragCoord)
- --stfp->input_to_slot[inAttr];
- else
- ++numIn;
- }
- if (stfp->Base.UsesPointCoord) {
- if (!stfp->Base.UsesFrontFacing &&
- !stfp->Base.UsesFogFragCoord)
- stfp->input_to_slot[inAttr] -= 2;
- else
- ++numIn;
- }
- }
}
else {
stfp->input_to_slot[inAttr] = UNUSED;
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 2852623472..c741940bcf 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -69,34 +69,107 @@ st_BlitFramebuffer(GLcontext *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
+ const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT);
struct st_context *st = ctx->st;
-
const uint pFilter = ((filter == GL_NEAREST)
? PIPE_TEX_MIPFILTER_NEAREST
: PIPE_TEX_MIPFILTER_LINEAR);
+ struct gl_framebuffer *readFB = ctx->ReadBuffer;
+ struct gl_framebuffer *drawFB = ctx->DrawBuffer;
+
+ if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
+ &dstX0, &dstY0, &dstX1, &dstY1)) {
+ return; /* nothing to draw/blit */
+ }
+
+ if (st_fb_orientation(drawFB) == Y_0_TOP) {
+ /* invert Y for dest */
+ dstY0 = drawFB->Height - dstY0;
+ dstY1 = drawFB->Height - dstY1;
+ }
+
+ if (st_fb_orientation(readFB) == Y_0_TOP) {
+ /* invert Y for src */
+ srcY0 = readFB->Height - srcY0;
+ srcY1 = readFB->Height - srcY1;
+ }
+
+ if (srcY0 > srcY1 && dstY0 > dstY1) {
+ /* Both src and dst are upside down. Swap Y to make it
+ * right-side up to increase odds of using a fast path.
+ * Recall that all Gallium raster coords have Y=0=top.
+ */
+ GLint tmp;
+ tmp = srcY0;
+ srcY0 = srcY1;
+ srcY1 = tmp;
+ tmp = dstY0;
+ dstY0 = dstY1;
+ dstY1 = tmp;
+ }
if (mask & GL_COLOR_BUFFER_BIT) {
struct st_renderbuffer *srcRb =
- st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+ st_renderbuffer(readFB->_ColorReadBuffer);
struct st_renderbuffer *dstRb =
- st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+ st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
struct pipe_surface *srcSurf = srcRb->surface;
struct pipe_surface *dstSurf = dstRb->surface;
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
- /* invert Y */
- srcY0 = srcRb->Base.Height - srcY0;
- srcY1 = srcRb->Base.Height - srcY1;
-
- dstY0 = dstRb->Base.Height - dstY0;
- dstY1 = dstRb->Base.Height - dstY1;
- }
-
util_blit_pixels(st->blit,
srcSurf, srcX0, srcY0, srcX1, srcY1,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
+ }
+ if (mask & depthStencil) {
+ /* depth and/or stencil blit */
+
+ /* get src/dst depth surfaces */
+ struct st_renderbuffer *srcDepthRb =
+ st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
+ struct st_renderbuffer *dstDepthRb =
+ st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
+ struct pipe_surface *srcDepthSurf =
+ srcDepthRb ? srcDepthRb->surface : NULL;
+ struct pipe_surface *dstDepthSurf =
+ dstDepthRb ? dstDepthRb->surface : NULL;
+
+ /* get src/dst stencil surfaces */
+ struct st_renderbuffer *srcStencilRb =
+ st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
+ struct st_renderbuffer *dstStencilRb =
+ st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
+ struct pipe_surface *srcStencilSurf =
+ srcStencilRb ? srcStencilRb->surface : NULL;
+ struct pipe_surface *dstStencilSurf =
+ dstStencilRb ? dstStencilRb->surface : NULL;
+
+ if ((mask & depthStencil) == depthStencil &&
+ srcDepthSurf == srcStencilSurf &&
+ dstDepthSurf == dstStencilSurf) {
+ /* Blitting depth and stencil values between combined
+ * depth/stencil buffers. This is the ideal case for such buffers.
+ */
+ util_blit_pixels(st->blit,
+ srcDepthSurf, srcX0, srcY0, srcX1, srcY1,
+ dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+ }
+ else {
+ /* blitting depth and stencil separately */
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ /* blit Z only */
+ _mesa_problem(ctx, "st_BlitFramebuffer(DEPTH) not completed");
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ /* blit stencil only */
+ _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
+ }
+ }
}
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index b39403129d..d19a88fa7c 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -804,8 +804,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- _mesa_set_vp_override( ctx, TRUE );
- _mesa_update_state( ctx );
+ /* Mesa state should be up to date by now */
+ assert(ctx->NewState == 0x0);
st_validate_state(st);
@@ -833,8 +833,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
pipe_texture_reference(&pt, NULL);
}
}
-
- _mesa_set_vp_override( ctx, FALSE );
}
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 3bcccd0df4..d82b2a2035 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -251,7 +251,7 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
rs->array[0].Ptr = (GLubyte *) v;
/* draw the point */
- st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);
+ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index e8d7f70ad6..90a059ca69 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -523,6 +523,12 @@ st_TexImage(GLcontext * ctx,
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
+ /* switch to "normal" */
+ if (stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_FALSE;
+ }
+
/* gallium does not support texture borders, strip it off */
if (border) {
strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 914a507bef..503a5f34a3 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -533,6 +533,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -545,6 +546,10 @@ st_draw_vbo(GLcontext *ctx,
unsigned num_vbuffers, num_velements;
GLboolean userSpace;
+ /* Gallium probably doesn't want this in some cases. */
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index dcfe7e1536..3e0face656 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -47,6 +47,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
@@ -56,6 +57,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 2712c131c0..b2d682ef64 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -96,6 +96,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -114,6 +115,9 @@ st_feedback_draw_vbo(GLcontext *ctx,
st_validate_state(ctx->st);
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* must get these after state validation! */
vp = ctx->st->vp;
vs = &st->vp->state;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 8a958e8bd8..3f835d38dd 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -233,7 +233,9 @@ void st_init_extensions(struct st_context *st)
if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
ctx->Extensions.ARB_point_sprite = GL_TRUE;
- ctx->Extensions.NV_point_sprite = GL_TRUE;
+ /* GL_NV_point_sprite is not supported by gallium because we don't
+ * support the GL_POINT_SPRITE_R_MODE_NV option.
+ */
}
if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index dd7e40be08..2ab12d3cf3 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -112,27 +112,6 @@ map_register_file_index(
{
switch( file ) {
case TGSI_FILE_INPUT:
- if (procType == TGSI_PROCESSOR_FRAGMENT &&
- index == FRAG_ATTRIB_FOGC) {
- if (GET_SWZ(*swizzle, 0) == SWIZZLE_X) {
- /* do nothing we're, ok */
- } else if (GET_SWZ(*swizzle, 0) == SWIZZLE_Y) {
- /* replace the swizzle with xxxx */
- *swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
- SWIZZLE_X,
- SWIZZLE_X,
- SWIZZLE_X);
- /* register after fog */
- return inputMapping[index] + 1;
- } else {
- *swizzle = MAKE_SWIZZLE4(SWIZZLE_Z,
- SWIZZLE_W,
- SWIZZLE_Z,
- SWIZZLE_W);
- /* register after frontface */
- return inputMapping[index] + 2;
- }
- }
/* inputs are mapped according to the user-defined map */
return inputMapping[index];
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 806e0ca8f6..d2da20ae42 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -458,34 +458,20 @@ st_translate_fragment_program(struct st_context *st,
stfp->input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
- case FRAG_ATTRIB_FOGC: {
- int extra_decls = 0;
- if (stfp->Base.UsesFogFragCoord) {
- stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- stfp->input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- input_flags[slot] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- if (stfp->Base.UsesFrontFacing) {
- GLint idx = slot + extra_decls;
- stfp->input_semantic_name[idx] = TGSI_SEMANTIC_FACE;
- stfp->input_semantic_index[idx] = 0;
- interpMode[idx] = TGSI_INTERPOLATE_CONSTANT;
- input_flags[idx] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- if (stfp->Base.UsesPointCoord) {
- GLint idx = slot + extra_decls;
- stfp->input_semantic_name[idx] = TGSI_SEMANTIC_GENERIC;
- stfp->input_semantic_index[idx] = num_generic++;
- interpMode[idx] = TGSI_INTERPOLATE_PERSPECTIVE;
- input_flags[idx] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- fs_num_inputs += extra_decls - 1;
- continue;
- }
+ case FRAG_ATTRIB_FOGC:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ stfp->input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
+ break;
+ case FRAG_ATTRIB_FACE:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
+ stfp->input_semantic_index[slot] = num_generic++;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
+ break;
+ case FRAG_ATTRIB_PNTC:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stfp->input_semantic_index[slot] = num_generic++;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1:
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index 04d3a3d7c2..a5fdac32d1 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -107,7 +107,9 @@ void st_swapbuffers(struct st_framebuffer *stfb,
struct pipe_surface **front_left,
struct pipe_surface **front_right);
-int st_set_teximage(struct pipe_texture *pt, int target);
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format);
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
/** Redirect rendering into stfb's surface to a texture image */
int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 10faa633ea..d58803991a 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -32,6 +32,7 @@
#include "st_cb_fbo.h"
#include "st_inlines.h"
#include "main/enums.h"
+#include "main/texobj.h"
#include "main/teximage.h"
#include "main/texstore.h"
@@ -353,25 +354,95 @@ st_texture_image_copy(struct pipe_context *pipe,
}
}
-/** Bind a pipe surface for use as a texture image */
+
+/**
+ * Bind a pipe surface to a texture object. After the call,
+ * the texture object is marked dirty and will be (re-)validated.
+ *
+ * If this is the first surface bound, the texture object is said to
+ * switch from normal to surface based. It will be cleared first in
+ * this case.
+ *
+ * \param ps pipe surface to be unbound
+ * \param target texture target
+ * \param level image level
+ * \param format internal format of the texture
+ */
int
-st_set_teximage(struct pipe_texture *pt, int target)
+st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format)
{
GET_CURRENT_CONTEXT(ctx);
const GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ struct st_texture_object *stObj;
struct st_texture_image *stImage;
- int internalFormat;
+ GLenum internalFormat;
- switch (pt->format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- internalFormat = GL_RGBA8;
+ switch (target) {
+ case ST_TEXTURE_2D:
+ target = GL_TEXTURE_2D;
+ break;
+ case ST_TEXTURE_RECT:
+ target = GL_TEXTURE_RECTANGLE_ARB;
break;
default:
return 0;
- };
+ }
+
+ /* map pipe format to base format for now */
+ if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0)
+ internalFormat = GL_RGBA;
+ else
+ internalFormat = GL_RGB;
+
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ _mesa_lock_texture(ctx, texObj);
+
+ stObj = st_texture_object(texObj);
+ /* switch to surface based */
+ if (!stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_TRUE;
+ }
+
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ stImage = st_texture_image(texImage);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ ps->width, ps->height, 1, 0, internalFormat);
+ texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
+ GL_RGBA, GL_UNSIGNED_BYTE);
+ _mesa_set_fetch_functions(texImage, 2);
+ pipe_texture_reference(&stImage->pt, ps->texture);
+
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ _mesa_unlock_texture(ctx, texObj);
+
+ return 1;
+}
+
+
+/**
+ * Unbind a pipe surface from a texture object. After the call,
+ * the texture object is marked dirty and will be (re-)validated.
+ *
+ * \param ps pipe surface to be unbound
+ * \param target texture target
+ * \param level image level
+ */
+int
+st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ struct st_texture_object *stObj;
+ struct st_texture_image *stImage;
switch (target) {
case ST_TEXTURE_2D:
@@ -385,21 +456,28 @@ st_set_teximage(struct pipe_texture *pt, int target)
}
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
+
+ _mesa_lock_texture(ctx, texObj);
+
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ stObj = st_texture_object(texObj);
stImage = st_texture_image(texImage);
-
- _mesa_init_teximage_fields(ctx, GL_TEXTURE_2D, texImage, pt->width[0],
- pt->height[0], 1, 0, internalFormat);
- texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, GL_RGBA,
- GL_UNSIGNED_BYTE);
- _mesa_set_fetch_functions(texImage, 2);
+ /* Make sure the pipe surface is still bound. The texture object is still
+ * considered surface based even if this is the last bound surface. */
+ if (stImage->pt == ps->texture) {
+ pipe_texture_reference(&stImage->pt, NULL);
+ _mesa_clear_texture_image(ctx, texImage);
- pipe_texture_reference(&stImage->pt, pt);
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+
return 1;
}
+
/** Redirect rendering into stfb's surface to a texture image */
int
st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index b9d447cb56..60868ce067 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -69,6 +69,11 @@ struct st_texture_object
struct pipe_texture *pt;
GLboolean teximage_realloc;
+
+ /* True if there is/was a surface bound to this texture object. It helps
+ * track whether the texture object is surface based or not.
+ */
+ GLboolean surface_based;
};
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c
index 0e32cb8f65..8303e4debc 100644
--- a/src/mesa/swrast/s_blit.c
+++ b/src/mesa/swrast/s_blit.c
@@ -24,6 +24,7 @@
#include "main/glheader.h"
+#include "main/image.h"
#include "main/macros.h"
#include "s_context.h"
@@ -104,7 +105,7 @@ static void
blit_nearest(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLenum buffer)
+ GLbitfield buffer)
{
struct gl_renderbuffer *readRb, *drawRb;
@@ -456,7 +457,7 @@ static void
simple_blit(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLenum buffer)
+ GLbitfield buffer)
{
struct gl_renderbuffer *readRb, *drawRb;
const GLint width = srcX1 - srcX0;
@@ -551,184 +552,6 @@ simple_blit(GLcontext *ctx,
/**
- * Clip dst coords against Xmax (or Ymax).
- */
-static INLINE void
-clip_right_or_top(GLint *srcX0, GLint *srcX1,
- GLint *dstX0, GLint *dstX1,
- GLint maxValue)
-{
- GLfloat t, bias;
-
- if (*dstX1 > maxValue) {
- /* X1 outside right edge */
- ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
- t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
- /* chop off [t, 1] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX1 = maxValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
- *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
- }
- else if (*dstX0 > maxValue) {
- /* X0 outside right edge */
- ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
- t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
- /* chop off [t, 1] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX0 = maxValue;
- bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
- *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
- }
-}
-
-
-/**
- * Clip dst coords against Xmin (or Ymin).
- */
-static INLINE void
-clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
- GLint *dstX0, GLint *dstX1,
- GLint minValue)
-{
- GLfloat t, bias;
-
- if (*dstX0 < minValue) {
- /* X0 outside left edge */
- ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
- t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
- /* chop off [0, t] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX0 = minValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
- *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
- }
- else if (*dstX1 < minValue) {
- /* X1 outside left edge */
- ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
- t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
- /* chop off [0, t] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX1 = minValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
- *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
- }
-}
-
-
-/**
- * Do clipping of blit src/dest rectangles.
- * The dest rect is clipped against both the buffer bounds and scissor bounds.
- * The src rect is just clipped against the buffer bounds.
- *
- * When either the src or dest rect is clipped, the other is also clipped
- * proportionately!
- *
- * Note that X0 need not be less than X1 (same for Y) for either the source
- * and dest rects. That makes the clipping a little trickier.
- *
- * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
- */
-static GLboolean
-clip_blit(GLcontext *ctx,
- GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
- GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
-{
- const GLint srcXmin = 0;
- const GLint srcXmax = ctx->ReadBuffer->Width;
- const GLint srcYmin = 0;
- const GLint srcYmax = ctx->ReadBuffer->Height;
-
- /* these include scissor bounds */
- const GLint dstXmin = ctx->DrawBuffer->_Xmin;
- const GLint dstXmax = ctx->DrawBuffer->_Xmax;
- const GLint dstYmin = ctx->DrawBuffer->_Ymin;
- const GLint dstYmax = ctx->DrawBuffer->_Ymax;
-
- /*
- printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
- *srcX0, *srcX1, *dstX0, *dstX1);
- printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
- *srcY0, *srcY1, *dstY0, *dstY1);
- */
-
- /* trivial rejection tests */
- if (*dstX0 == *dstX1)
- return GL_FALSE; /* no width */
- if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
- return GL_FALSE; /* totally out (left) of bounds */
- if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
- return GL_FALSE; /* totally out (right) of bounds */
-
- if (*dstY0 == *dstY1)
- return GL_FALSE;
- if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
- return GL_FALSE;
- if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
- return GL_FALSE;
-
- if (*srcX0 == *srcX1)
- return GL_FALSE;
- if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
- return GL_FALSE;
- if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
- return GL_FALSE;
-
- if (*srcY0 == *srcY1)
- return GL_FALSE;
- if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
- return GL_FALSE;
- if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
- return GL_FALSE;
-
- /*
- * dest clip
- */
- clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
- clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
- clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
- clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
-
- /*
- * src clip (just swap src/dst values from above)
- */
- clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
- clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
- clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
- clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
-
- /*
- printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
- *srcX0, *srcX1, *dstX0, *dstX1);
- printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
- *srcY0, *srcY1, *dstY0, *dstY1);
- */
-
- ASSERT(*dstX0 >= dstXmin);
- ASSERT(*dstX0 <= dstXmax);
- ASSERT(*dstX1 >= dstXmin);
- ASSERT(*dstX1 <= dstXmax);
-
- ASSERT(*dstY0 >= dstYmin);
- ASSERT(*dstY0 <= dstYmax);
- ASSERT(*dstY1 >= dstYmin);
- ASSERT(*dstY1 <= dstYmax);
-
- ASSERT(*srcX0 >= srcXmin);
- ASSERT(*srcX0 <= srcXmax);
- ASSERT(*srcX1 >= srcXmin);
- ASSERT(*srcX1 <= srcXmax);
-
- ASSERT(*srcY0 >= srcYmin);
- ASSERT(*srcY0 <= srcYmax);
- ASSERT(*srcY1 >= srcYmin);
- ASSERT(*srcY1 <= srcYmax);
-
- return GL_TRUE;
-}
-
-
-/**
* Software fallback for glBlitFramebufferEXT().
*/
void
@@ -737,7 +560,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
- static const GLint buffers[3] = {
+ static const GLbitfield buffers[3] = {
GL_COLOR_BUFFER_BIT,
GL_DEPTH_BUFFER_BIT,
GL_STENCIL_BUFFER_BIT
@@ -747,8 +570,8 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
if (!ctx->DrawBuffer->_NumColorDrawBuffers)
return;
- if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
- &dstX0, &dstY0, &dstX1, &dstY1)) {
+ if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
+ &dstX0, &dstY0, &dstX1, &dstY1)) {
return;
}
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index b71fb9eae9..613a91b0ec 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -157,9 +157,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
/* if running a GLSL program (not ARB_fragment_program) */
if (ctx->Shader.CurrentProgram) {
- /* Store front/back facing value in register FOGC.Y */
- machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing;
- /* Note FOGC.ZW is gl_PointCoord if drawing a sprite */
+ /* Store front/back facing value */
+ machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0 - span->facing;
}
machine->CurElement = col;
diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c
index 0a3ad97a71..50ec2063a5 100644
--- a/src/mesa/swrast/s_points.c
+++ b/src/mesa/swrast/s_points.c
@@ -139,9 +139,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
}
ATTRIB_LOOP_BEGIN
- if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+ if (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) {
+ /* a texcoord attribute */
const GLuint u = attr - FRAG_ATTRIB_TEX0;
- /* a texcoord */
+ ASSERT(u < Elements(ctx->Point.CoordReplace));
if (ctx->Point.CoordReplace[u]) {
tCoords[numTcoords++] = attr;
@@ -170,15 +171,15 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
continue;
}
}
- else if (attr == FRAG_ATTRIB_FOGC) {
- /* GLSL gl_PointCoord is stored in fog.zw */
- span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0;
- span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */
- span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx;
- span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0;
- span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0;
- span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy;
- tCoords[numTcoords++] = FRAG_ATTRIB_FOGC;
+ else if (attr == FRAG_ATTRIB_PNTC) {
+ /* GLSL gl_PointCoord.xy (.zw undefined) */
+ span.attrStart[FRAG_ATTRIB_PNTC][0] = 0.0;
+ span.attrStart[FRAG_ATTRIB_PNTC][1] = 0.0; /* t0 set below */
+ span.attrStepX[FRAG_ATTRIB_PNTC][0] = dsdx;
+ span.attrStepX[FRAG_ATTRIB_PNTC][1] = 0.0;
+ span.attrStepY[FRAG_ATTRIB_PNTC][0] = 0.0;
+ span.attrStepY[FRAG_ATTRIB_PNTC][1] = dtdy;
+ tCoords[numTcoords++] = FRAG_ATTRIB_PNTC;
continue;
}
/* use vertex's texcoord/attrib */
@@ -221,10 +222,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
GLuint i;
/* setup texcoord T for this row */
for (i = 0; i < numTcoords; i++) {
- if (tCoords[i] == FRAG_ATTRIB_FOGC)
- span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord;
- else
- span.attrStart[tCoords[i]][1] = tcoord;
+ span.attrStart[tCoords[i]][1] = tcoord;
}
/* these might get changed by span clipping */
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f69b122046..f2771cde09 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -81,7 +81,7 @@ _tnl_CreateContext( GLcontext *ctx )
tnl->nr_blocks = 0;
/* plug in the VBO drawing function */
- vbo_set_draw_func(ctx, _tnl_draw_prims);
+ vbo_set_draw_func(ctx, _tnl_vbo_draw_prims);
_math_init_transformation();
_math_init_translate();
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 2ec65d5323..c64c2c2077 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -360,6 +360,20 @@ static void unmap_vbos( GLcontext *ctx,
}
+void _tnl_vbo_draw_prims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index)
+{
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+}
/* This is the main entrypoint into the slimmed-down software tnl
* module. In a regular swtnl driver, this can be plugged straight
@@ -393,7 +407,7 @@ void _tnl_draw_prims( GLcontext *ctx,
*/
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
min_index, max_index,
- _tnl_draw_prims );
+ _tnl_vbo_draw_prims );
return;
}
else if (max_index > max) {
@@ -411,7 +425,7 @@ void _tnl_draw_prims( GLcontext *ctx,
*/
vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
0, max_index,
- _tnl_draw_prims,
+ _tnl_vbo_draw_prims,
&limits );
}
else {
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 66c5e13729..dc954bcba1 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -386,6 +386,9 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
#endif
COPY_4V(store->results[attr].data[i], machine.Outputs[attr]);
}
+#ifdef NAN_CHECK
+ ASSERT(machine.Outputs[0][3] != 0.0F);
+#endif
#if 0
printf("HPOS: %f %f %f %f\n",
machine.Outputs[0][0],
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
index 4d628aa9a6..9c66d3b019 100644
--- a/src/mesa/tnl/tnl.h
+++ b/src/mesa/tnl/tnl.h
@@ -81,6 +81,16 @@ _tnl_draw_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index);
+void
+_tnl_vbo_draw_prims( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index);
+
extern void
_mesa_load_tracked_matrices(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h
index 5362226c2f..5986e93576 100644
--- a/src/mesa/vbo/vbo.h
+++ b/src/mesa/vbo/vbo.h
@@ -69,6 +69,7 @@ typedef void (*vbo_draw_func)( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
@@ -112,7 +113,10 @@ void vbo_rebase_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index,
vbo_draw_func draw );
-
+void
+vbo_get_minmax_index(GLcontext *ctx, const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index);
void vbo_use_buffer_objects(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index b746a77bc1..387d4ee3d4 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -486,23 +486,6 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
}
-/**
- * Check if programs/shaders are enabled and valid at glBegin time.
- */
-GLboolean
-vbo_validate_shaders(GLcontext *ctx)
-{
- if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
- (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
- return GL_FALSE;
- }
- if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) {
- return GL_FALSE;
- }
- return GL_TRUE;
-}
-
-
/* Build a list of primitives on the fly. Keep
* ctx->Driver.CurrentExecPrimitive uptodate as well.
*/
@@ -521,9 +504,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
return;
}
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBegin (invalid vertex/fragment program)");
+ if (!_mesa_valid_to_render(ctx, "glBegin")) {
return;
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index f4b9b2f744..4148469ef4 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -41,13 +41,27 @@
/**
* Compute min and max elements for glDraw[Range]Elements() calls.
*/
-static void
-get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
- GLuint *min_index, GLuint *max_index)
+void
+vbo_get_minmax_index(GLcontext *ctx,
+ const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index)
{
GLuint i;
+ GLsizei count = prim->count;
+ const void *indices;
+
+ if (_mesa_is_bufferobj(ib->obj)) {
+ const GLvoid *map = ctx->Driver.MapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ GL_READ_ONLY,
+ ib->obj);
+ indices = ADD_POINTERS(map, ib->ptr);
+ } else {
+ indices = ib->ptr;
+ }
- switch(type) {
+ switch (ib->type) {
case GL_UNSIGNED_INT: {
const GLuint *ui_indices = (const GLuint *)indices;
GLuint max_ui = ui_indices[count-1];
@@ -88,6 +102,12 @@ get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
assert(0);
break;
}
+
+ if (_mesa_is_bufferobj(ib->obj)) {
+ ctx->Driver.UnmapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ ib->obj);
+ }
}
@@ -101,7 +121,7 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array,
{
if (array->Enabled) {
const void *data = array->Ptr;
- if (array->BufferObj->Name) {
+ if (_mesa_is_bufferobj(array->BufferObj)) {
if (!array->BufferObj->Pointer) {
/* need to map now */
array->BufferObj->Pointer = ctx->Driver.MapBuffer(ctx,
@@ -146,8 +166,8 @@ static void
unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
{
if (array->Enabled &&
- array->BufferObj->Name &&
- array->BufferObj->Pointer) {
+ _mesa_is_bufferobj(array->BufferObj) &&
+ _mesa_bufferobj_mapped(array->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx,
GL_ARRAY_BUFFER_ARB,
array->BufferObj);
@@ -166,7 +186,7 @@ check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
const void *elemMap;
GLint i, k;
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
elemMap = ctx->Driver.MapBuffer(ctx,
GL_ELEMENT_ARRAY_BUFFER_ARB,
GL_READ_ONLY,
@@ -205,7 +225,7 @@ check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
}
}
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
ctx->Driver.UnmapBuffer(ctx,
GL_ELEMENT_ARRAY_BUFFER_ARB,
ctx->Array.ElementArrayBufferObj);
@@ -469,8 +489,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
if (ctx->NewState)
_mesa_update_state( ctx );
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArrays(bad shader)");
+ if (!_mesa_valid_to_render(ctx, "glDrawArrays")) {
return;
}
@@ -500,7 +519,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
prim[0].indexed = 0;
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
- start, start + count - 1 );
+ GL_TRUE, start, start + count - 1 );
#if 0
print_draw_arrays(ctx, exec, mode, start, count);
@@ -566,70 +585,35 @@ dump_element_buffer(GLcontext *ctx, GLenum type)
ctx->Array.ElementArrayBufferObj);
}
-
-static void GLAPIENTRY
-vbo_exec_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type, const GLvoid *indices)
+/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+static void
+vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
+ GLboolean index_bounds_valid,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
{
- GET_CURRENT_CONTEXT(ctx);
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_exec_context *exec = &vbo->exec;
struct _mesa_index_buffer ib;
struct _mesa_prim prim[1];
- if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
- type, indices ))
- return;
-
- if (end >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
- "type 0x%x, indices=%p)\n"
- "\tindex=%u is out of bounds (max=%u) "
- "Element Buffer %u (size %d)",
- start, end, count, type, indices, end,
- ctx->Array.ArrayObj->_MaxElement - 1,
- ctx->Array.ElementArrayBufferObj->Name,
- ctx->Array.ElementArrayBufferObj->Size);
-
- if (0)
- dump_element_buffer(ctx, type);
-
- if (0)
- _mesa_print_arrays(ctx);
- return;
- }
- else if (0) {
- _mesa_printf("glDraw[Range]Elements"
- "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
- start, end, type, count,
- ctx->Array.ElementArrayBufferObj->Name);
- }
-
-#if 0
- check_draw_elements_data(ctx, count, type, indices);
-#else
- (void) check_draw_elements_data;
-#endif
-
FLUSH_CURRENT( ctx, 0 );
if (ctx->NewState)
_mesa_update_state( ctx );
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements(bad shader)");
+ if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) {
return;
}
- bind_arrays( ctx );
-
if (ctx->NewState)
_mesa_update_state( ctx );
+ bind_arrays( ctx );
+
ib.count = count;
- ib.type = type;
+ ib.type = type;
ib.obj = ctx->Array.ElementArrayBufferObj;
ib.ptr = indices;
@@ -673,44 +657,68 @@ vbo_exec_DrawRangeElements(GLenum mode,
* for the latter case elsewhere.
*/
- vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end );
+ vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
+ index_bounds_valid, start, end );
}
-
static void GLAPIENTRY
-vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
+vbo_exec_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type, const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
- GLuint min_index = 0;
- GLuint max_index = 0;
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
+ type, indices ))
return;
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(bad shader)");
+ if (end >= ctx->Array.ArrayObj->_MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
+ "type 0x%x, indices=%p)\n"
+ "\tindex=%u is out of bounds (max=%u) "
+ "Element Buffer %u (size %d)",
+ start, end, count, type, indices, end,
+ ctx->Array.ArrayObj->_MaxElement - 1,
+ ctx->Array.ElementArrayBufferObj->Name,
+ ctx->Array.ElementArrayBufferObj->Size);
+
+ if (0)
+ dump_element_buffer(ctx, type);
+
+ if (0)
+ _mesa_print_arrays(ctx);
return;
}
+ else if (0) {
+ _mesa_printf("glDraw[Range]Elements"
+ "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
+ start, end, type, count,
+ ctx->Array.ElementArrayBufferObj->Name);
+ }
- if (ctx->Array.ElementArrayBufferObj->Name) {
- const GLvoid *map = ctx->Driver.MapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- GL_READ_ONLY,
- ctx->Array.ElementArrayBufferObj);
+#if 0
+ check_draw_elements_data(ctx, count, type, indices);
+#else
+ (void) check_draw_elements_data;
+#endif
- get_minmax_index(count, type, ADD_POINTERS(map, indices),
- &min_index, &max_index);
+ vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
+ count, type, indices);
+}
- ctx->Driver.UnmapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- ctx->Array.ElementArrayBufferObj);
- }
- else {
- get_minmax_index(count, type, indices, &min_index, &max_index);
- }
- vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices);
+static void GLAPIENTRY
+vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ return;
+
+ vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+ count, type, indices);
}
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 18419928b2..d76c45f356 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -214,7 +214,7 @@ vbo_exec_bind_arrays( GLcontext *ctx )
/* override the default array set above */
exec->vtx.inputs[attr] = &arrays[attr];
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
/* a real buffer obj: Ptr is an offset, not a pointer*/
GLsizeiptr offset;
assert(exec->vtx.bufferobj->Pointer); /* buf should be mapped */
@@ -251,7 +251,7 @@ vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
{
GLenum target = GL_ARRAY_BUFFER_ARB;
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
GLcontext *ctx = exec->ctx;
if (ctx->Driver.FlushMappedBufferRange) {
@@ -291,7 +291,7 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )
MESA_MAP_NOWAIT_BIT;
const GLenum usage = GL_STREAM_DRAW_ARB;
- if (exec->vtx.bufferobj->Name == 0)
+ if (!_mesa_is_bufferobj(exec->vtx.bufferobj))
return;
if (exec->vtx.buffer_map != NULL) {
@@ -365,7 +365,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
if (ctx->NewState)
_mesa_update_state( ctx );
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
vbo_exec_vtx_unmap( exec );
}
@@ -378,12 +378,13 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
exec->vtx.prim,
exec->vtx.prim_count,
NULL,
+ GL_TRUE,
0,
exec->vtx.vert_count - 1);
/* If using a real VBO, get new storage -- unless asked not to.
*/
- if (exec->vtx.bufferobj->Name && !unmap) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj) && !unmap) {
vbo_exec_vtx_map( exec );
}
}
@@ -392,7 +393,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
/* May have to unmap explicitly if we didn't draw:
*/
if (unmap &&
- exec->vtx.bufferobj->Name &&
+ _mesa_is_bufferobj(exec->vtx.bufferobj) &&
exec->vtx.buffer_map) {
vbo_exec_vtx_unmap( exec );
}
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index ea87dede64..3bf7ef580f 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -208,6 +208,7 @@ void vbo_rebase_prims( GLcontext *ctx,
prim,
nr_prims,
ib,
+ GL_TRUE,
0,
max_index - min_index );
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index d00d304d2e..cdbbc9c187 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -911,7 +911,7 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
_ae_map_vbos( ctx );
- if (ctx->Array.ElementArrayBufferObj->Name)
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 5110648c28..d834fa1f2e 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -279,6 +279,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
node->prim,
node->prim_count,
NULL,
+ GL_TRUE,
0, /* Node is a VBO, so this is ok */
node->count - 1);
}
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index d7ffebf607..8ec180d550 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -30,6 +30,7 @@
*/
#include "main/glheader.h"
+#include "main/bufferobj.h"
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
@@ -194,6 +195,7 @@ flush( struct copy_context *copy )
copy->dstprim,
copy->dstprim_nr,
&copy->dstib,
+ GL_TRUE,
0,
copy->dstbuf_nr );
@@ -443,7 +445,7 @@ replay_init( struct copy_context *copy )
copy->varying[j].size = attr_size(copy->array[i]);
copy->vertex_size += attr_size(copy->array[i]);
- if (vbo->Name && !vbo->Pointer)
+ if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo))
ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY, vbo);
copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer,
@@ -457,7 +459,8 @@ replay_init( struct copy_context *copy )
* caller convert non-indexed prims to indexed. Could alternately
* do it internally.
*/
- if (copy->ib->obj->Name && !copy->ib->obj->Pointer)
+ if (_mesa_is_bufferobj(copy->ib->obj) &&
+ !_mesa_bufferobj_mapped(copy->ib->obj))
ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY,
copy->ib->obj);
@@ -561,13 +564,14 @@ replay_finish( struct copy_context *copy )
*/
for (i = 0; i < copy->nr_varying; i++) {
struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;
- if (vbo->Name && vbo->Pointer)
+ if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo))
ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo);
}
/* Unmap index buffer:
*/
- if (copy->ib->obj->Name && copy->ib->obj->Pointer) {
+ if (_mesa_is_bufferobj(copy->ib->obj) &&
+ _mesa_bufferobj_mapped(copy->ib->obj)) {
ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj);
}
}
diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c
index 9628227e7c..da84eaa6ea 100644
--- a/src/mesa/vbo/vbo_split_inplace.c
+++ b/src/mesa/vbo/vbo_split_inplace.c
@@ -85,6 +85,7 @@ static void flush_vertex( struct split_context *split )
split->dstprim,
split->dstprim_nr,
NULL,
+ GL_TRUE,
min_index,
max_index);