summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-07-15 14:17:07 -0400
committerAlex Deucher <alexdeucher@gmail.com>2009-07-15 14:17:07 -0400
commitc5c19919ce627b98d8aab4284da1694573bcccd4 (patch)
tree2e29b313b79b6a392e020fd5723e3cc00c800fd2 /src/mesa/drivers/dri
parenta0d4a12614fce072fa1eb5516e626909171c95e1 (diff)
parent3a3b83e5112b725e22f05b32a273a2351b820944 (diff)
Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/mesa/mesa into r6xx-rewrite
This builds, but I get an assertion in radeonGetLock() due to the drawable being null.
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/Makefile.template3
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.c541
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.h99
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c7
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h102
-rw-r--r--src/mesa/drivers/dri/common/xmlpool.h4
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c7
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c8
l---------[-rw-r--r--]src/mesa/drivers/dri/i915/intel_pixel_read.c307
-rw-r--r--src/mesa/drivers/dri/i915/intel_tris.c7
-rw-r--r--src/mesa/drivers/dri/i965/Makefile1
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c22
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_line.c12
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_point.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_state.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_tri.c13
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_unfilled.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_util.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h10
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h29
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c33
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h25
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c321
-rw-r--r--src/mesa/drivers/dri/i965/brw_fallback.c31
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_emit.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c39
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_emit.c41
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c21
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_dump.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h124
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c76
-rw-r--r--src/mesa/drivers/dri/i965/brw_urb.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_constval.c44
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c149
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_state.c18
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c38
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c47
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c87
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c16
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c24
l---------src/mesa/drivers/dri/i965/intel_pixel_read.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c109
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.h14
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c35
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.h7
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffers.c17
-rw-r--r--src/mesa/drivers/dri/intel/intel_chipset.h14
-rw-r--r--src/mesa/drivers/dri/intel/intel_clear.c234
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c65
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h42
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c5
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_generatemipmap.c20
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c69
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h6
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel.c255
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel.h15
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_bitmap.c67
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_copy.c24
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_draw.c48
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_read.c324
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c107
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.h24
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c34
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c46
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c26
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c27
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c1
-rw-r--r--src/mesa/drivers/dri/r128/r128_state.c5
-rw-r--r--src/mesa/drivers/dri/r128/r128_tris.c2
-rw-r--r--src/mesa/drivers/dri/r128/r128_tris.h2
-rw-r--r--src/mesa/drivers/dri/r200/.gitignore14
-rw-r--r--src/mesa/drivers/dri/r200/Makefile10
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c8
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c5
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.c12
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c53
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c42
-rw-r--r--src/mesa/drivers/dri/r200/r200_texstate.c6
-rw-r--r--src/mesa/drivers/dri/r300/.gitignore13
-rw-r--r--src/mesa/drivers/dri/r300/Makefile10
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c57
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c13
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h39
-rw-r--r--src/mesa/drivers/dri/r300/r300_draw.c38
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c19
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.h4
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.c290
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.h6
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c57
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h2
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c24
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c64
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c170
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_swtcl.c50
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c45
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c656
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.h4
-rw-r--r--src/mesa/drivers/dri/r300/radeon_nqssadce.c94
-rw-r--r--src/mesa/drivers/dri/r300/radeon_nqssadce.h7
-rw-r--r--src/mesa/drivers/dri/r300/radeon_program.h32
-rw-r--r--src/mesa/drivers/dri/r300/radeon_program_pair.c4
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.c11
-rw-r--r--src/mesa/drivers/dri/r600/r600_texstate.c39
-rw-r--r--src/mesa/drivers/dri/r600/r700_clear.c13
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile7
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_drm.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c17
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h30
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c309
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h22
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c13
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h24
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_drm.h56
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c108
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c234
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c21
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c234
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c56
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c50
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c70
140 files changed, 4489 insertions, 2829 deletions
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index bd38e3be47..18dbeba24a 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -11,7 +11,8 @@ COMMON_GALLIUM_SOURCES = \
COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \
../../common/driverfuncs.c \
../common/texmem.c \
- ../common/drirenderbuffer.c
+ ../common/drirenderbuffer.c \
+ ../common/dri_metaops.c
ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=
diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c
new file mode 100644
index 0000000000..fe183c2e87
--- /dev/null
+++ b/src/mesa/drivers/dri/common/dri_metaops.c
@@ -0,0 +1,541 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 Intel Corporation.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "main/arrayobj.h"
+#include "main/attrib.h"
+#include "main/blend.h"
+#include "main/bufferobj.h"
+#include "main/buffers.h"
+#include "main/depth.h"
+#include "main/enable.h"
+#include "main/matrix.h"
+#include "main/macros.h"
+#include "main/polygon.h"
+#include "main/shaders.h"
+#include "main/stencil.h"
+#include "main/texstate.h"
+#include "main/varray.h"
+#include "main/viewport.h"
+#include "shader/arbprogram.h"
+#include "shader/program.h"
+#include "dri_metaops.h"
+
+void
+meta_set_passthrough_transform(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+
+ meta->saved_vp_x = ctx->Viewport.X;
+ meta->saved_vp_y = ctx->Viewport.Y;
+ meta->saved_vp_width = ctx->Viewport.Width;
+ meta->saved_vp_height = ctx->Viewport.Height;
+ meta->saved_matrix_mode = ctx->Transform.MatrixMode;
+
+ meta->internal_viewport_call = GL_TRUE;
+ _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
+ meta->internal_viewport_call = GL_FALSE;
+
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_PushMatrix();
+ _mesa_LoadIdentity();
+ _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
+
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_PushMatrix();
+ _mesa_LoadIdentity();
+}
+
+void
+meta_restore_transform(struct dri_metaops *meta)
+{
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_PopMatrix();
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_PopMatrix();
+
+ _mesa_MatrixMode(meta->saved_matrix_mode);
+
+ meta->internal_viewport_call = GL_TRUE;
+ _mesa_Viewport(meta->saved_vp_x, meta->saved_vp_y,
+ meta->saved_vp_width, meta->saved_vp_height);
+ meta->internal_viewport_call = GL_FALSE;
+}
+
+
+/**
+ * Set up a vertex program to pass through the position and first texcoord
+ * for pixel path.
+ */
+void
+meta_set_passthrough_vertex_program(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+ static const char *vp =
+ "!!ARBvp1.0\n"
+ "TEMP vertexClip;\n"
+ "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n"
+ "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n"
+ "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n"
+ "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n"
+ "MOV result.position, vertexClip;\n"
+ "MOV result.texcoord[0], vertex.texcoord[0];\n"
+ "MOV result.color, vertex.color;\n"
+ "END\n";
+
+ assert(meta->saved_vp == NULL);
+
+ _mesa_reference_vertprog(ctx, &meta->saved_vp,
+ ctx->VertexProgram.Current);
+ if (meta->passthrough_vp == NULL) {
+ GLuint prog_name;
+ _mesa_GenPrograms(1, &prog_name);
+ _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name);
+ _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(vp), (const GLubyte *)vp);
+ _mesa_reference_vertprog(ctx, &meta->passthrough_vp,
+ ctx->VertexProgram.Current);
+ _mesa_DeletePrograms(1, &prog_name);
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ meta->passthrough_vp);
+ ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
+ &meta->passthrough_vp->Base);
+
+ meta->saved_vp_enable = ctx->VertexProgram.Enabled;
+ _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
+}
+
+/**
+ * Restores the previous vertex program after
+ * meta_set_passthrough_vertex_program()
+ */
+void
+meta_restore_vertex_program(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ meta->saved_vp);
+ _mesa_reference_vertprog(ctx, &meta->saved_vp, NULL);
+ ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
+ &ctx->VertexProgram.Current->Base);
+
+ if (!meta->saved_vp_enable)
+ _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
+}
+
+/**
+ * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the
+ * program object.
+ */
+void
+meta_set_fragment_program(struct dri_metaops *meta,
+ struct gl_fragment_program **prog,
+ const char *prog_string)
+{
+ GLcontext *ctx = meta->ctx;
+ assert(meta->saved_fp == NULL);
+
+ _mesa_reference_fragprog(ctx, &meta->saved_fp,
+ ctx->FragmentProgram.Current);
+ if (*prog == NULL) {
+ GLuint prog_name;
+ _mesa_GenPrograms(1, &prog_name);
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name);
+ _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(prog_string), (const GLubyte *)prog_string);
+ _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current);
+ /* Note that DeletePrograms unbinds the program on us */
+ _mesa_DeletePrograms(1, &prog_name);
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog);
+ ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base));
+
+ meta->saved_fp_enable = ctx->FragmentProgram.Enabled;
+ _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
+}
+
+/**
+ * Restores the previous fragment program after
+ * meta_set_fragment_program()
+ */
+void
+meta_restore_fragment_program(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ meta->saved_fp);
+ _mesa_reference_fragprog(ctx, &meta->saved_fp, NULL);
+ ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ &ctx->FragmentProgram.Current->Base);
+
+ if (!meta->saved_fp_enable)
+ _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
+}
+
+static const float default_texcoords[4][2] = { { 0.0, 0.0 },
+ { 1.0, 0.0 },
+ { 1.0, 1.0 },
+ { 0.0, 1.0 } };
+
+void
+meta_set_default_texrect(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+ struct gl_client_array *old_texcoord_array;
+
+ meta->saved_active_texture = ctx->Texture.CurrentUnit;
+ if (meta->saved_array_vbo == NULL) {
+ _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo,
+ ctx->Array.ArrayBufferObj);
+ }
+
+ old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0];
+ meta->saved_texcoord_type = old_texcoord_array->Type;
+ meta->saved_texcoord_size = old_texcoord_array->Size;
+ meta->saved_texcoord_stride = old_texcoord_array->Stride;
+ meta->saved_texcoord_enable = old_texcoord_array->Enabled;
+ meta->saved_texcoord_ptr = old_texcoord_array->Ptr;
+ _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo,
+ old_texcoord_array->BufferObj);
+
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0);
+
+ if (meta->texcoord_vbo == NULL) {
+ GLuint vbo_name;
+
+ _mesa_GenBuffersARB(1, &vbo_name);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords),
+ default_texcoords, GL_STATIC_DRAW_ARB);
+ _mesa_reference_buffer_object(ctx, &meta->texcoord_vbo,
+ ctx->Array.ArrayBufferObj);
+ } else {
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
+ meta->texcoord_vbo->Name);
+ }
+ _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL);
+
+ _mesa_Enable(GL_TEXTURE_COORD_ARRAY);
+}
+
+void
+meta_restore_texcoords(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+
+ /* Restore the old TexCoordPointer */
+ if (meta->saved_texcoord_vbo) {
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
+ meta->saved_texcoord_vbo->Name);
+ _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, NULL);
+ } else {
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
+
+ _mesa_TexCoordPointer(meta->saved_texcoord_size,
+ meta->saved_texcoord_type,
+ meta->saved_texcoord_stride,
+ meta->saved_texcoord_ptr);
+ if (!meta->saved_texcoord_enable)
+ _mesa_Disable(GL_TEXTURE_COORD_ARRAY);
+
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0 +
+ meta->saved_active_texture);
+
+ if (meta->saved_array_vbo) {
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
+ meta->saved_array_vbo->Name);
+ _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, NULL);
+ } else {
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
+}
+
+
+/**
+ * Perform glClear where mask contains only color, depth, and/or stencil.
+ *
+ * The implementation is based on calling into Mesa to set GL state and
+ * performing normal triangle rendering. The intent of this path is to
+ * have as generic a path as possible, so that any driver could make use of
+ * it.
+ */
+
+/**
+ * Per-context one-time init of things for intl_clear_tris().
+ * Basically set up a private array object for vertex/color arrays.
+ */
+static void
+meta_init_clear(struct dri_metaops *meta)
+{
+ GLcontext *ctx = meta->ctx;
+ struct gl_array_object *arraySave = NULL;
+ const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name;
+ const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name;
+
+ /* create new array object */
+ meta->clear.arrayObj = _mesa_new_array_object(ctx, ~0);
+
+ /* save current array object, bind new one */
+ _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj);
+
+ /* one-time setup of vertex arrays (pos, color) */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), meta->clear.color);
+ _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), meta->clear.vertices);
+ _mesa_Enable(GL_COLOR_ARRAY);
+ _mesa_Enable(GL_VERTEX_ARRAY);
+
+ /* restore original array object */
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
+ _mesa_reference_array_object(ctx, &arraySave, NULL);
+
+ /* restore original buffer objects */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer);
+ _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer);
+}
+
+
+
+/**
+ * Perform glClear where mask contains only color, depth, and/or stencil.
+ *
+ * The implementation is based on calling into Mesa to set GL state and
+ * performing normal triangle rendering. The intent of this path is to
+ * have as generic a path as possible, so that any driver could make use of
+ * it.
+ */
+void
+meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
+{
+ GLcontext *ctx = meta->ctx;
+ GLfloat dst_z;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ int i;
+ GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
+ GLuint saved_shader_program = 0;
+ unsigned int saved_active_texture;
+ struct gl_array_object *arraySave = NULL;
+
+ if (!meta->clear.arrayObj)
+ meta_init_clear(meta);
+
+ assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
+ BUFFER_BIT_STENCIL)) == 0);
+
+ _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_ENABLE_BIT |
+ GL_POLYGON_BIT |
+ GL_STENCIL_BUFFER_BIT |
+ GL_TRANSFORM_BIT |
+ GL_CURRENT_BIT |
+ GL_VIEWPORT_BIT);
+ saved_active_texture = ctx->Texture.CurrentUnit;
+
+ /* Disable existing GL state we don't want to apply to a clear. */
+ _mesa_Disable(GL_ALPHA_TEST);
+ _mesa_Disable(GL_BLEND);
+ _mesa_Disable(GL_CULL_FACE);
+ _mesa_Disable(GL_FOG);
+ _mesa_Disable(GL_POLYGON_SMOOTH);
+ _mesa_Disable(GL_POLYGON_STIPPLE);
+ _mesa_Disable(GL_POLYGON_OFFSET_FILL);
+ _mesa_Disable(GL_LIGHTING);
+ _mesa_Disable(GL_CLIP_PLANE0);
+ _mesa_Disable(GL_CLIP_PLANE1);
+ _mesa_Disable(GL_CLIP_PLANE2);
+ _mesa_Disable(GL_CLIP_PLANE3);
+ _mesa_Disable(GL_CLIP_PLANE4);
+ _mesa_Disable(GL_CLIP_PLANE5);
+ _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
+ saved_fp_enable = GL_TRUE;
+ _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+ if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
+ saved_vp_enable = GL_TRUE;
+ _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
+ }
+ if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
+ saved_shader_program = ctx->Shader.CurrentProgram->Name;
+ _mesa_UseProgramObjectARB(0);
+ }
+
+ if (ctx->Texture._EnabledUnits != 0) {
+ int i;
+
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
+ _mesa_Disable(GL_TEXTURE_1D);
+ _mesa_Disable(GL_TEXTURE_2D);
+ _mesa_Disable(GL_TEXTURE_3D);
+ if (ctx->Extensions.ARB_texture_cube_map)
+ _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
+ if (ctx->Extensions.NV_texture_rectangle)
+ _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
+ if (ctx->Extensions.MESA_texture_array) {
+ _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
+ _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
+ }
+ }
+ }
+
+ /* save current array object, bind our private one */
+ _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj);
+
+ meta_set_passthrough_transform(meta);
+
+ for (i = 0; i < 4; i++) {
+ COPY_4FV(meta->clear.color[i], ctx->Color.ClearColor);
+ }
+
+ /* convert clear Z from [0,1] to NDC coord in [-1,1] */
+ dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
+
+ /* The ClearDepth value is unaffected by DepthRange, so do a default
+ * mapping.
+ */
+ _mesa_DepthRange(0.0, 1.0);
+
+ /* Prepare the vertices, which are the same regardless of which buffer we're
+ * drawing to.
+ */
+ meta->clear.vertices[0][0] = fb->_Xmin;
+ meta->clear.vertices[0][1] = fb->_Ymin;
+ meta->clear.vertices[0][2] = dst_z;
+ meta->clear.vertices[1][0] = fb->_Xmax;
+ meta->clear.vertices[1][1] = fb->_Ymin;
+ meta->clear.vertices[1][2] = dst_z;
+ meta->clear.vertices[2][0] = fb->_Xmax;
+ meta->clear.vertices[2][1] = fb->_Ymax;
+ meta->clear.vertices[2][2] = dst_z;
+ meta->clear.vertices[3][0] = fb->_Xmin;
+ meta->clear.vertices[3][1] = fb->_Ymax;
+ meta->clear.vertices[3][2] = dst_z;
+
+ while (mask != 0) {
+ GLuint this_mask = 0;
+ GLuint color_bit;
+
+ color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
+ if (color_bit != 0)
+ this_mask |= (1 << (color_bit - 1));
+
+ /* Clear depth/stencil in the same pass as color. */
+ this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
+
+ /* Select the current color buffer and use the color write mask if
+ * we have one, otherwise don't write any color channels.
+ */
+ if (this_mask & BUFFER_BIT_FRONT_LEFT)
+ _mesa_DrawBuffer(GL_FRONT_LEFT);
+ else if (this_mask & BUFFER_BIT_BACK_LEFT)
+ _mesa_DrawBuffer(GL_BACK_LEFT);
+ else if (color_bit != 0)
+ _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
+ (color_bit - BUFFER_COLOR0 - 1));
+ else
+ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ /* Control writing of the depth clear value to depth. */
+ if (this_mask & BUFFER_BIT_DEPTH) {
+ _mesa_DepthFunc(GL_ALWAYS);
+ _mesa_Enable(GL_DEPTH_TEST);
+ } else {
+ _mesa_Disable(GL_DEPTH_TEST);
+ _mesa_DepthMask(GL_FALSE);
+ }
+
+ /* Control writing of the stencil clear value to stencil. */
+ if (this_mask & BUFFER_BIT_STENCIL) {
+ _mesa_Enable(GL_STENCIL_TEST);
+ _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 {
+ _mesa_Disable(GL_STENCIL_TEST);
+ }
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ mask &= ~this_mask;
+ }
+
+ meta_restore_transform(meta);
+
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
+ if (saved_fp_enable)
+ _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
+ if (saved_vp_enable)
+ _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
+
+ if (saved_shader_program)
+ _mesa_UseProgramObjectARB(saved_shader_program);
+
+ _mesa_PopAttrib();
+
+ /* restore current array object */
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
+ _mesa_reference_array_object(ctx, &arraySave, NULL);
+}
+
+void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta)
+{
+ meta->ctx = ctx;
+}
+
+void meta_destroy_metaops(struct dri_metaops *meta)
+{
+ if (meta->clear.arrayObj)
+ _mesa_delete_array_object(meta->ctx, meta->clear.arrayObj);
+
+}
diff --git a/src/mesa/drivers/dri/common/dri_metaops.h b/src/mesa/drivers/dri/common/dri_metaops.h
new file mode 100644
index 0000000000..bb4079d535
--- /dev/null
+++ b/src/mesa/drivers/dri/common/dri_metaops.h
@@ -0,0 +1,99 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 Intel Corporation.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+#ifndef DRI_METAOPS_H
+#define DRI_METAOPS_H
+
+#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
+ BUFFER_BIT_FRONT_LEFT | \
+ BUFFER_BIT_COLOR0 | \
+ BUFFER_BIT_COLOR1 | \
+ BUFFER_BIT_COLOR2 | \
+ BUFFER_BIT_COLOR3 | \
+ BUFFER_BIT_COLOR4 | \
+ BUFFER_BIT_COLOR5 | \
+ BUFFER_BIT_COLOR6 | \
+ BUFFER_BIT_COLOR7)
+
+struct dri_meta_clear {
+ struct gl_array_object *arrayObj;
+ GLfloat vertices[4][3];
+ GLfloat color[4][4];
+};
+
+struct dri_metaops {
+ GLcontext *ctx;
+ GLboolean internal_viewport_call;
+ struct gl_fragment_program *bitmap_fp;
+ struct gl_vertex_program *passthrough_vp;
+ struct gl_buffer_object *texcoord_vbo;
+
+ struct gl_fragment_program *saved_fp;
+ GLboolean saved_fp_enable;
+ struct gl_vertex_program *saved_vp;
+ GLboolean saved_vp_enable;
+
+ struct gl_fragment_program *tex2d_fp;
+
+ GLboolean saved_texcoord_enable;
+ struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo;
+ GLenum saved_texcoord_type;
+ GLsizei saved_texcoord_size, saved_texcoord_stride;
+ const void *saved_texcoord_ptr;
+ int saved_active_texture;
+
+ GLint saved_vp_x, saved_vp_y;
+ GLsizei saved_vp_width, saved_vp_height;
+ GLenum saved_matrix_mode;
+
+ struct dri_meta_clear clear;
+};
+
+
+void meta_set_passthrough_transform(struct dri_metaops *meta);
+
+void meta_restore_transform(struct dri_metaops *meta);
+
+void meta_set_passthrough_vertex_program(struct dri_metaops *meta);
+
+void meta_restore_vertex_program(struct dri_metaops *meta);
+
+void meta_set_fragment_program(struct dri_metaops *meta,
+ struct gl_fragment_program **prog,
+ const char *prog_string);
+
+void meta_restore_fragment_program(struct dri_metaops *meta);
+
+void meta_set_default_texrect(struct dri_metaops *meta);
+
+void meta_restore_texcoords(struct dri_metaops *meta);
+void meta_clear_tris(struct dri_metaops *meta, GLbitfield mask);
+
+void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta);
+void meta_destroy_metaops(struct dri_metaops *meta);
+#endif
+
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index ae0e61e515..1d940603fa 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */
/**
* \file dri_util.c
* DRI utility functions.
@@ -122,6 +121,9 @@ static int driUnbindContext(__DRIcontext *pcp)
pdp = pcp->driDrawablePriv;
prp = pcp->driReadablePriv;
+ /* already unbound */
+ if (!pdp && !prp)
+ return GL_TRUE;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
@@ -146,9 +148,10 @@ static int driUnbindContext(__DRIcontext *pcp)
* window we can determine the last context bound to the window and
* use that context's lock. (BrianP, 2-Dec-2000)
*/
+ pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
+
#if 0
/* Unbind the drawable */
- pcp->driDrawablePriv = NULL;
pdp->driContextPriv = &psp->dummyContextPriv;
#endif
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index f5e35e4161..e308fd2831 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -406,9 +406,10 @@ static const char UniformMatrix4fvARB_names[] =
"";
#endif
-#if defined(need_GL_APPLE_vertex_array_object)
+#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object)
static const char DeleteVertexArraysAPPLE_names[] =
"ip\0" /* Parameter signature */
+ "glDeleteVertexArrays\0"
"glDeleteVertexArraysAPPLE\0"
"";
#endif
@@ -941,6 +942,13 @@ static const char WeightivARB_names[] =
"";
#endif
+#if defined(need_GL_SGIX_instruments)
+static const char PollInstrumentsSGIX_names[] =
+ "p\0" /* Parameter signature */
+ "glPollInstrumentsSGIX\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_global_alpha)
static const char GlobalAlphaFactordSUN_names[] =
"d\0" /* Parameter signature */
@@ -2114,6 +2122,13 @@ static const char Tangent3fvEXT_names[] =
"";
#endif
+#if defined(need_GL_ARB_vertex_array_object)
+static const char GenVertexArrays_names[] =
+ "ip\0" /* Parameter signature */
+ "glGenVertexArrays\0"
+ "";
+#endif
+
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
static const char BindFramebufferEXT_names[] =
"ii\0" /* Parameter signature */
@@ -2340,10 +2355,10 @@ static const char GetCombinerStageParameterfvNV_names[] =
"";
#endif
-#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3fEXT_names[] =
- "fff\0" /* Parameter signature */
- "glBinormal3fEXT\0"
+#if defined(need_GL_ARB_vertex_array_object)
+static const char BindVertexArray_names[] =
+ "i\0" /* Parameter signature */
+ "glBindVertexArray\0"
"";
#endif
@@ -2773,10 +2788,10 @@ static const char Uniform4fARB_names[] =
"";
#endif
-#if defined(need_GL_IBM_multimode_draw_arrays)
-static const char MultiModeDrawArraysIBM_names[] =
- "pppii\0" /* Parameter signature */
- "glMultiModeDrawArraysIBM\0"
+#if defined(need_GL_ARB_map_buffer_range)
+static const char FlushMappedBufferRange_names[] =
+ "iii\0" /* Parameter signature */
+ "glFlushMappedBufferRange\0"
"";
#endif
@@ -3403,10 +3418,11 @@ static const char GetProgramParameterdvNV_names[] =
"";
#endif
-#if defined(need_GL_SGIX_instruments)
-static const char PollInstrumentsSGIX_names[] =
- "p\0" /* Parameter signature */
- "glPollInstrumentsSGIX\0"
+#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object)
+static const char IsVertexArrayAPPLE_names[] =
+ "i\0" /* Parameter signature */
+ "glIsVertexArray\0"
+ "glIsVertexArrayAPPLE\0"
"";
#endif
@@ -3904,6 +3920,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 */
@@ -3933,6 +3956,13 @@ static const char VertexWeightfEXT_names[] =
"";
#endif
+#if defined(need_GL_EXT_coordinate_frame)
+static const char Binormal3fEXT_names[] =
+ "fff\0" /* Parameter signature */
+ "glBinormal3fEXT\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
static const char FogCoordfvEXT_names[] =
"p\0" /* Parameter signature */
@@ -4048,10 +4078,10 @@ static const char BlendFuncSeparateEXT_names[] =
"";
#endif
-#if defined(need_GL_APPLE_vertex_array_object)
-static const char IsVertexArrayAPPLE_names[] =
- "i\0" /* Parameter signature */
- "glIsVertexArrayAPPLE\0"
+#if defined(need_GL_ARB_map_buffer_range)
+static const char MapBufferRange_names[] =
+ "iiii\0" /* Parameter signature */
+ "glMapBufferRange\0"
"";
#endif
@@ -4296,6 +4326,13 @@ static const char SpriteParameterivSGIX_names[] =
"";
#endif
+#if defined(need_GL_EXT_provoking_vertex)
+static const char ProvokingVertexEXT_names[] =
+ "i\0" /* Parameter signature */
+ "glProvokingVertexEXT\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_3)
static const char MultiTexCoord1fARB_names[] =
"if\0" /* Parameter signature */
@@ -4940,8 +4977,8 @@ static const struct dri_extension_function GL_3DFX_tbuffer_functions[] = {
static const struct dri_extension_function GL_APPLE_vertex_array_object_functions[] = {
{ DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 },
{ GenVertexArraysAPPLE_names, GenVertexArraysAPPLE_remap_index, -1 },
- { BindVertexArrayAPPLE_names, BindVertexArrayAPPLE_remap_index, -1 },
{ IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 },
+ { BindVertexArrayAPPLE_names, BindVertexArrayAPPLE_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
@@ -4986,6 +5023,14 @@ static const struct dri_extension_function GL_ARB_framebuffer_object_functions[]
};
#endif
+#if defined(need_GL_ARB_map_buffer_range)
+static const struct dri_extension_function GL_ARB_map_buffer_range_functions[] = {
+ { FlushMappedBufferRange_names, FlushMappedBufferRange_remap_index, -1 },
+ { MapBufferRange_names, MapBufferRange_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_matrix_palette)
static const struct dri_extension_function GL_ARB_matrix_palette_functions[] = {
{ MatrixIndexusvARB_names, MatrixIndexusvARB_remap_index, -1 },
@@ -5094,6 +5139,16 @@ static const struct dri_extension_function GL_ARB_transpose_matrix_functions[] =
};
#endif
+#if defined(need_GL_ARB_vertex_array_object)
+static const struct dri_extension_function GL_ARB_vertex_array_object_functions[] = {
+ { DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 },
+ { GenVertexArrays_names, GenVertexArrays_remap_index, -1 },
+ { BindVertexArray_names, BindVertexArray_remap_index, -1 },
+ { IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_vertex_blend)
static const struct dri_extension_function GL_ARB_vertex_blend_functions[] = {
{ WeightubvARB_names, WeightubvARB_remap_index, -1 },
@@ -5347,7 +5402,6 @@ static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] =
{ Binormal3ivEXT_names, Binormal3ivEXT_remap_index, -1 },
{ Tangent3sEXT_names, Tangent3sEXT_remap_index, -1 },
{ Tangent3fvEXT_names, Tangent3fvEXT_remap_index, -1 },
- { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 },
{ Tangent3dvEXT_names, Tangent3dvEXT_remap_index, -1 },
{ Binormal3bvEXT_names, Binormal3bvEXT_remap_index, -1 },
{ Binormal3dEXT_names, Binormal3dEXT_remap_index, -1 },
@@ -5356,6 +5410,7 @@ static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] =
{ Tangent3ivEXT_names, Tangent3ivEXT_remap_index, -1 },
{ Tangent3dEXT_names, Tangent3dEXT_remap_index, -1 },
{ Binormal3svEXT_names, Binormal3svEXT_remap_index, -1 },
+ { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 },
{ Binormal3dvEXT_names, Binormal3dvEXT_remap_index, -1 },
{ Tangent3iEXT_names, Tangent3iEXT_remap_index, -1 },
{ Tangent3bvEXT_names, Tangent3bvEXT_remap_index, -1 },
@@ -5541,6 +5596,13 @@ static const struct dri_extension_function GL_EXT_polygon_offset_functions[] = {
};
#endif
+#if defined(need_GL_EXT_provoking_vertex)
+static const struct dri_extension_function GL_EXT_provoking_vertex_functions[] = {
+ { ProvokingVertexEXT_names, ProvokingVertexEXT_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_EXT_secondary_color)
static const struct dri_extension_function GL_EXT_secondary_color_functions[] = {
{ SecondaryColor3iEXT_names, SecondaryColor3iEXT_remap_index, -1 },
@@ -6038,11 +6100,11 @@ static const struct dri_extension_function GL_SGIX_igloo_interface_functions[] =
#if defined(need_GL_SGIX_instruments)
static const struct dri_extension_function GL_SGIX_instruments_functions[] = {
{ ReadInstrumentsSGIX_names, ReadInstrumentsSGIX_remap_index, -1 },
+ { PollInstrumentsSGIX_names, PollInstrumentsSGIX_remap_index, -1 },
{ GetInstrumentsSGIX_names, GetInstrumentsSGIX_remap_index, -1 },
{ StartInstrumentsSGIX_names, StartInstrumentsSGIX_remap_index, -1 },
{ StopInstrumentsSGIX_names, StopInstrumentsSGIX_remap_index, -1 },
{ InstrumentsBufferSGIX_names, InstrumentsBufferSGIX_remap_index, -1 },
- { PollInstrumentsSGIX_names, PollInstrumentsSGIX_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
diff --git a/src/mesa/drivers/dri/common/xmlpool.h b/src/mesa/drivers/dri/common/xmlpool.h
index 7fbc6e800d..587517ea10 100644
--- a/src/mesa/drivers/dri/common/xmlpool.h
+++ b/src/mesa/drivers/dri/common/xmlpool.h
@@ -60,6 +60,10 @@
#define DRI_CONF_OPT_BEGIN(name,type,def) \
"<option name=\""#name"\" type=\""#type"\" default=\""#def"\">\n"
+/** \brief Begin an option definition with qouted default value */
+#define DRI_CONF_OPT_BEGIN_Q(name,type,def) \
+"<option name=\""#name"\" type=\""#type"\" default="#def">\n"
+
/** \brief Begin an option definition with restrictions on valid values */
#define DRI_CONF_OPT_BEGIN_V(name,type,def,valid) \
"<option name=\""#name"\" type=\""#type"\" default=\""#def"\" valid=\""valid"\">\n"
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index cbee9f9efe..9c6f891dd3 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -737,12 +737,6 @@ i830_assert_not_dirty( struct intel_context *intel )
assert(!get_dirty(state));
}
-static void
-i830_note_unlock( struct intel_context *intel )
-{
- /* nothing */
-}
-
void
i830InitVtbl(struct i830_context *i830)
{
@@ -757,6 +751,5 @@ i830InitVtbl(struct i830_context *i830)
i830->intel.vtbl.render_start = i830_render_start;
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
- i830->intel.vtbl.note_unlock = i830_note_unlock;
i830->intel.vtbl.finish_batch = intel_finish_vb;
}
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 2fca247af1..fe1be93a6d 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -692,13 +692,6 @@ i915_assert_not_dirty( struct intel_context *intel )
assert(!dirty);
}
-static void
-i915_note_unlock( struct intel_context *intel )
-{
- /* nothing */
-}
-
-
void
i915InitVtbl(struct i915_context *i915)
{
@@ -713,6 +706,5 @@ i915InitVtbl(struct i915_context *i915)
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
i915->intel.vtbl.flush_cmd = i915_flush_cmd;
i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty;
- i915->intel.vtbl.note_unlock = i915_note_unlock;
i915->intel.vtbl.finish_batch = intel_finish_vb;
}
diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c
index 56087aacd4..cc4589f4d4 100644..120000
--- a/src/mesa/drivers/dri/i915/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c
@@ -1,306 +1 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "main/enums.h"
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/image.h"
-#include "main/bufferobj.h"
-#include "swrast/swrast.h"
-
-#include "intel_screen.h"
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_blit.h"
-#include "intel_buffers.h"
-#include "intel_regions.h"
-#include "intel_pixel.h"
-#include "intel_buffer_objects.h"
-
-/* For many applications, the new ability to pull the source buffers
- * back out of the GTT and then do the packing/conversion operations
- * in software will be as much of an improvement as trying to get the
- * blitter and/or texture engine to do the work.
- *
- * This step is gated on private backbuffers.
- *
- * Obviously the frontbuffer can't be pulled back, so that is either
- * an argument for blit/texture readpixels, or for blitting to a
- * temporary and then pulling that back.
- *
- * When the destination is a pbo, however, it's not clear if it is
- * ever going to be pulled to main memory (though the access param
- * will be a good hint). So it sounds like we do want to be able to
- * choose between blit/texture implementation on the gpu and pullback
- * and cpu-based copying.
- *
- * Unless you can magically turn client memory into a PBO for the
- * duration of this call, there will be a cpu-based copying step in
- * any case.
- */
-
-
-static GLboolean
-do_texture_readpixels(GLcontext * ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *pack,
- struct intel_region *dest_region)
-{
-#if 0
- struct intel_context *intel = intel_context(ctx);
- intelScreenPrivate *screen = intel->intelScreen;
- GLint pitch = pack->RowLength ? pack->RowLength : width;
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
- int textureFormat;
- GLenum glTextureFormat;
- int destFormat, depthFormat, destPitch;
- drm_clip_rect_t tmp;
-
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
-
- if (ctx->_ImageTransferState ||
- pack->SwapBytes || pack->LsbFirst || !pack->Invert) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel));
-
- if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s: couldn't set dest %s/%s\n",
- __FUNCTION__,
- _mesa_lookup_enum_by_nr(type),
- _mesa_lookup_enum_by_nr(format));
- return GL_FALSE;
- }
-
- LOCK_HARDWARE(intel);
-
- if (intel->driDrawable->numClipRects) {
- intel->vtbl.install_meta_state(intel);
- intel->vtbl.meta_no_depth_write(intel);
- intel->vtbl.meta_no_stencil_write(intel);
-
- if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
- UNLOCK_HARDWARE(intel);
- SET_STATE(i830, state);
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
- return GL_TRUE;
- }
-
- y = dPriv->h - y - height;
- x += dPriv->x;
- y += dPriv->y;
-
-
- /* Set the frontbuffer up as a large rectangular texture.
- */
- intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat);
-
-
- intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat);
-
-
- /* Set the 3d engine to draw into the destination region:
- */
-
- intel->vtbl.meta_draw_region(intel, dest_region);
- intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */
-
-
- /* Draw a single quad, no cliprects:
- */
- intel->vtbl.meta_disable_cliprects(intel);
-
- intel->vtbl.draw_quad(intel,
- 0, width, 0, height,
- 0x00ff00ff, x, x + width, y, y + height);
-
- intel->vtbl.leave_meta_state(intel);
- }
- UNLOCK_HARDWARE(intel);
-
- intel_region_wait_fence(ctx, dest_region); /* required by GL */
- return GL_TRUE;
-#endif
-
- return GL_FALSE;
-}
-
-
-
-
-static GLboolean
-do_blit_readpixels(GLcontext * ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
-{
- struct intel_context *intel = intel_context(ctx);
- struct intel_region *src = intel_readbuf_region(intel);
- struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
- GLuint dst_offset;
- GLuint rowLength;
-
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s\n", __FUNCTION__);
-
- if (!src)
- return GL_FALSE;
-
- if (dst) {
- /* XXX This validation should be done by core mesa:
- */
- if (!_mesa_validate_pbo_access(2, pack, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels");
- return GL_TRUE;
- }
- }
- else {
- /* PBO only for now:
- */
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s - not PBO\n", __FUNCTION__);
- return GL_FALSE;
- }
-
-
- if (ctx->_ImageTransferState ||
- !intel_check_blit_format(src, format, type)) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s - bad format for blit\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s: bad packing params\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- if (pack->RowLength > 0)
- rowLength = pack->RowLength;
- else
- rowLength = width;
-
- if (pack->Invert) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__);
- return GL_FALSE;
- }
- else {
- rowLength = -rowLength;
- }
-
- /* XXX 64-bit cast? */
- dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height,
- format, type, 0, 0, 0);
-
-
- /* Although the blits go on the command buffer, need to do this and
- * fire with lock held to guarentee cliprects are correct.
- */
- intelFlush(&intel->ctx);
- LOCK_HARDWARE(intel);
-
- if (intel->driDrawable->numClipRects) {
- GLboolean all = (width * height * src->cpp == dst->Base.Size &&
- x == 0 && dst_offset == 0);
-
- dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
- all ? INTEL_WRITE_FULL :
- INTEL_WRITE_PART);
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
- int nbox = dPriv->numClipRects;
- drm_clip_rect_t *box = dPriv->pClipRects;
- drm_clip_rect_t rect;
- drm_clip_rect_t src_rect;
- int i;
-
- src_rect.x1 = dPriv->x + x;
- src_rect.y1 = dPriv->y + dPriv->h - (y + height);
- src_rect.x2 = src_rect.x1 + width;
- src_rect.y2 = src_rect.y1 + height;
-
-
-
- for (i = 0; i < nbox; i++) {
- if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
- continue;
-
- intelEmitCopyBlit(intel,
- src->cpp,
- src->pitch, src->buffer, 0, src->tiling,
- rowLength, dst_buffer, dst_offset, GL_FALSE,
- rect.x1,
- rect.y1,
- rect.x1 - src_rect.x1,
- rect.y2 - src_rect.y2,
- rect.x2 - rect.x1, rect.y2 - rect.y1,
- GL_COPY);
- }
- }
- UNLOCK_HARDWARE(intel);
-
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s - DONE\n", __FUNCTION__);
-
- return GL_TRUE;
-}
-
-void
-intelReadPixels(GLcontext * ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
-{
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- intelFlush(ctx);
-
- if (do_blit_readpixels
- (ctx, x, y, width, height, format, type, pack, pixels))
- return;
-
- if (do_texture_readpixels
- (ctx, x, y, width, height, format, type, pack, pixels))
- return;
-
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
-
- _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels);
-}
+../intel/intel_pixel_read.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index 1d39278cbf..a905455342 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -1255,11 +1255,9 @@ intel_meta_draw_poly(struct intel_context *intel,
{
union fi *vb;
GLint i;
- GLboolean was_locked = intel->locked;
unsigned int saved_vertex_size = intel->vertex_size;
- if (!was_locked)
- LOCK_HARDWARE(intel);
+ LOCK_HARDWARE(intel);
intel->vertex_size = 6;
@@ -1283,8 +1281,7 @@ intel_meta_draw_poly(struct intel_context *intel,
intel->vertex_size = saved_vertex_size;
- if (!was_locked)
- UNLOCK_HARDWARE(intel);
+ UNLOCK_HARDWARE(intel);
}
static void
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 9712c38725..00a42111da 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -23,6 +23,7 @@ DRIVER_SOURCES = \
intel_pixel_bitmap.c \
intel_pixel_copy.c \
intel_pixel_draw.c \
+ intel_pixel_read.c \
intel_state.c \
intel_swapbuffers.c \
intel_tex.c \
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 5cffcebde4..54d30a3f42 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -65,21 +65,31 @@ static void compile_clip_prog( struct brw_context *brw,
c.func.single_program_flow = 1;
c.key = *key;
-
+ c.need_ff_sync = BRW_IS_IGDNG(brw);
/* Need to locate the two positions present in vertex + header.
* These are currently hardcoded:
*/
c.header_position_offset = ATTR_SIZE;
- for (i = 0, delta = REG_SIZE; i < VERT_RESULT_MAX; i++)
+ if (BRW_IS_IGDNG(brw))
+ delta = 3 * REG_SIZE;
+ else
+ delta = REG_SIZE;
+
+ for (i = 0; i < VERT_RESULT_MAX; i++)
if (c.key.attrs & (1<<i)) {
c.offset[i] = delta;
delta += ATTR_SIZE;
}
c.nr_attrs = brw_count_bits(c.key.attrs);
- c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+
+ if (BRW_IS_IGDNG(brw))
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
+ else
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+
c.nr_bytes = c.nr_regs * REG_SIZE;
c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
@@ -148,7 +158,11 @@ static void upload_clip_prog(struct brw_context *brw)
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
/* _NEW_TRANSFORM */
key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
- key.clip_mode = BRW_CLIPMODE_NORMAL;
+
+ if (BRW_IS_IGDNG(brw))
+ key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
+ else
+ key.clip_mode = BRW_CLIPMODE_NORMAL;
/* _NEW_POLYGON */
if (key.primitive == GL_TRIANGLES) {
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index e06747864b..12e8548df1 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -117,6 +117,7 @@ struct brw_clip_compile {
GLuint header_position_offset;
GLuint offset[VERT_ATTRIB_MAX];
+ GLboolean need_ff_sync;
};
#define ATTR_SIZE (4*4)
@@ -171,5 +172,5 @@ struct brw_reg get_tmp( struct brw_clip_compile *c );
void brw_clip_project_position(struct brw_clip_compile *c,
struct brw_reg pos );
-
+void brw_clip_ff_sync(struct brw_clip_compile *c);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
index d830e49e50..9abd0642aa 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -130,7 +130,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
struct brw_instruction *plane_loop;
struct brw_instruction *plane_active;
struct brw_instruction *is_negative;
- struct brw_instruction *is_neg2;
+ struct brw_instruction *is_neg2 = NULL;
struct brw_instruction *not_culled;
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
@@ -148,7 +148,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_clip_init_clipmask(c);
/* -ve rhw workaround */
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
brw_imm_ud(1<<20));
@@ -185,7 +185,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
* Both can be negative on GM965/G965 due to RHW workaround
* if so, this object should be rejected.
*/
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
{
@@ -210,7 +210,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
/* If both are positive, do nothing */
/* Only on GM965/G965 */
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
}
@@ -225,7 +225,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_ENDIF(p, is_neg2);
}
}
@@ -246,6 +246,8 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
+ if (c->need_ff_sync)
+ brw_clip_ff_sync(c);
not_culled = brw_IF(p, BRW_EXECUTE_1);
{
brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE);
diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c
index d17b199b89..9738299168 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_point.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_point.c
@@ -50,5 +50,7 @@ void brw_emit_point_clip( struct brw_clip_compile *c )
/* Send an empty message to kill the thread:
*/
brw_clip_tri_alloc_regs(c, 0);
+ if (c->need_ff_sync)
+ brw_clip_ff_sync(c);
brw_clip_kill_thread(c);
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index 9b0d7eab7b..5762c9577c 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -95,7 +95,14 @@ clip_unit_create_from_key(struct brw_context *brw,
* even number.
*/
assert(key->nr_urb_entries % 2 == 0);
- clip.thread4.max_threads = 2 - 1;
+
+ /* Although up to 16 concurrent Clip threads are allowed on IGDNG,
+ * only 2 threads can output VUEs at a time.
+ */
+ if (BRW_IS_IGDNG(brw))
+ clip.thread4.max_threads = 16 - 1;
+ else
+ clip.thread4.max_threads = 2 - 1;
} else {
assert(key->nr_urb_entries >= 5);
clip.thread4.max_threads = 1 - 1;
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index 7fd37bd05f..4c2d655fb1 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -77,6 +77,10 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
if (c->nr_attrs & 1) {
for (j = 0; j < 3; j++) {
GLuint delta = c->nr_attrs*16 + 32;
+
+ if (BRW_IS_IGDNG(c->func.brw))
+ delta = c->nr_attrs * 16 + 32 * 3;
+
brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
}
}
@@ -562,7 +566,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
/* if -ve rhw workaround bit is set,
do cliptest */
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
brw_imm_ud(1<<20));
@@ -579,11 +583,14 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
if (c->key.do_flat_shading)
brw_clip_tri_flat_shade(c);
- if (c->key.clip_mode == BRW_CLIPMODE_NORMAL)
+ if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
+ (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
do_clip_tri(c);
else
maybe_do_clip_tri(c);
-
+
+ if (c->need_ff_sync)
+ brw_clip_ff_sync(c);
brw_clip_tri_emit_polygon(c);
/* Send an empty message to kill the thread:
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
index d7ca517927..26950383c1 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
@@ -496,6 +496,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
}
brw_ENDIF(p, do_clip);
+ if (c->need_ff_sync)
+ brw_clip_ff_sync(c);
emit_unfilled_primitives(c);
brw_clip_kill_thread(c);
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index 9d3b0be694..e09efc07ed 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -140,6 +140,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
/* Just copy the vertex header:
*/
+ /*
+ * After CLIP stage, only first 256 bits of the VUE are read
+ * back on IGDNG, so needn't change it
+ */
brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
/* Iterate over each attribute (could be done in pairs?)
@@ -147,6 +151,9 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
for (i = 0; i < c->nr_attrs; i++) {
GLuint delta = i*16 + 32;
+ if (BRW_IS_IGDNG(p->brw))
+ delta = i * 16 + 32 * 3;
+
if (delta == c->offset[VERT_RESULT_EDGE]) {
if (force_edgeflag)
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
@@ -177,6 +184,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
if (i & 1) {
GLuint delta = i*16 + 32;
+
+ if (BRW_IS_IGDNG(p->brw))
+ delta = i * 16 + 32 * 3;
+
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
}
@@ -343,3 +354,19 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c )
}
}
+void brw_clip_ff_sync(struct brw_clip_compile *c)
+{
+ struct brw_compile *p = &c->func;
+ brw_ff_sync(p,
+ c->reg.R0,
+ 0,
+ c->reg.R0,
+ 1,
+ 1, /* used */
+ 1, /* msg length */
+ 1, /* response length */
+ 0, /* eot */
+ 1, /* write compelete */
+ 0, /* urb offset */
+ BRW_URB_SWIZZLE_NONE);
+}
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 873fc8ffff..57ddf75413 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -129,7 +129,6 @@ struct brw_context;
#define BRW_NEW_PRIMITIVE 0x40
#define BRW_NEW_CONTEXT 0x80
#define BRW_NEW_WM_INPUT_DIMENSIONS 0x100
-#define BRW_NEW_INPUT_VARYING 0x200
#define BRW_NEW_PSP 0x800
#define BRW_NEW_WM_SURFACES 0x1000
#define BRW_NEW_FENCE 0x2000
@@ -246,9 +245,6 @@ struct brw_vs_ouput_sizes {
};
-/** Number of general purpose registers (VS, WM, etc) */
-#define BRW_MAX_GRF 128
-
/** Number of texture sampler units */
#define BRW_MAX_TEX_UNIT 16
@@ -405,7 +401,6 @@ struct brw_vertex_element {
struct brw_vertex_info {
- GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */
GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */
};
@@ -614,9 +609,10 @@ struct brw_context
struct brw_wm_prog_data *prog_data;
struct brw_wm_compile *compile_data;
- /* Input sizes, calculated from active vertex program:
+ /** Input sizes, calculated from active vertex program.
+ * One bit per fragment program input attribute.
*/
- GLuint input_size_masks[4];
+ GLbitfield input_size_masks[4];
/** Array of surface default colors (texture border color) */
dri_bo *sdc_bo[BRW_MAX_TEX_UNIT];
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 98fc909c2a..d166250b4f 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -139,6 +139,7 @@
#define BRW_CLIPMODE_CLIP_NON_REJECTED 2
#define BRW_CLIPMODE_REJECT_ALL 3
#define BRW_CLIPMODE_ACCEPT_ALL 4
+#define BRW_CLIPMODE_KERNEL_CLIP 5
#define BRW_CLIP_NDCSPACE 0
#define BRW_CLIP_SCREENSPACE 1
@@ -670,6 +671,25 @@
#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3
#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG 0
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_IGDNG 0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG 0
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG 1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_BIAS_IGDNG 1
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG 1
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_IGDNG 2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD_IGDNG 2
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD_IGDNG 2
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG 3
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE_IGDNG 3
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG 3
+
+/* for IGDNG only */
+#define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0
+#define BRW_SAMPLER_SIMD_MODE_SIMD8 1
+#define BRW_SAMPLER_SIMD_MODE_SIMD16 2
+#define BRW_SAMPLER_SIMD_MODE_SIMD32_64 3
+
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1
#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2
@@ -819,8 +839,11 @@
#include "intel_chipset.h"
#define BRW_IS_G4X(brw) (IS_G4X((brw)->intel.intelScreen->deviceID))
-#define CMD_PIPELINE_SELECT(brw) (BRW_IS_G4X(brw) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
-#define CMD_VF_STATISTICS(brw) (BRW_IS_G4X(brw) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
-#define URB_SIZES(brw) (BRW_IS_G4X(brw) ? 384 : 256) /* 512 bit units */
+#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->intel.intelScreen->deviceID))
+#define BRW_IS_965(brw) (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)))
+#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
+#define CMD_VF_STATISTICS(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
+#define URB_SIZES(brw) (BRW_IS_IGDNG(brw) ? 1024 : \
+ (BRW_IS_G4X(brw) ? 384 : 256)) /* 512 bit units */
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 5342622a73..5152c3f3a5 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -187,19 +187,13 @@ static void brw_merge_inputs( struct brw_context *brw,
brw->vb.inputs[i].glarray = arrays[i];
if (arrays[i]->StrideB != 0)
- brw->vb.info.varying |= 1 << i;
-
brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) <<
((i%16) * 2);
}
- /* Raise statechanges if input sizes and varying have changed:
- */
+ /* Raise statechanges if input sizes have changed. */
if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0)
brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
-
- if (brw->vb.info.varying != old.varying)
- brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
}
/* XXX: could split the primitive list to fallback only on the
@@ -416,6 +410,8 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
out:
UNLOCK_HARDWARE(intel);
+ brw_state_cache_check_size(brw);
+
if (warn)
fprintf(stderr, "i965: Single primitive emit potentially exceeded "
"available aperture space\n");
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 1b8bcc14ec..c29f1dd5c0 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -512,7 +512,19 @@ static void brw_emit_vertices(struct brw_context *brw)
OUT_RELOC(input->bo,
I915_GEM_DOMAIN_VERTEX, 0,
input->offset);
- OUT_BATCH(brw->vb.max_index);
+ if (BRW_IS_IGDNG(brw)) {
+ if (input->stride) {
+ OUT_RELOC(input->bo,
+ I915_GEM_DOMAIN_VERTEX, 0,
+ input->offset + input->stride * input->count);
+ } else {
+ assert(input->count == 1);
+ OUT_RELOC(input->bo,
+ I915_GEM_DOMAIN_VERTEX, 0,
+ input->offset + input->element_size);
+ }
+ } else
+ OUT_BATCH(brw->vb.max_index);
OUT_BATCH(0); /* Instance data step rate */
}
ADVANCE_BATCH();
@@ -542,11 +554,18 @@ static void brw_emit_vertices(struct brw_context *brw)
BRW_VE0_VALID |
(format << BRW_VE0_FORMAT_SHIFT) |
(0 << BRW_VE0_SRC_OFFSET_SHIFT));
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
- ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
+
+ if (BRW_IS_IGDNG(brw))
+ OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
+ (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
+ else
+ OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
+ (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
+ ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
}
ADVANCE_BATCH();
}
@@ -635,7 +654,7 @@ static void brw_emit_indices(struct brw_context *brw)
if (index_buffer == NULL)
return;
- ib_size = get_size(index_buffer->type) * index_buffer->count;
+ ib_size = get_size(index_buffer->type) * index_buffer->count - 1;
/* Emit the indexbuffer packet:
*/
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index bc7756ceab..30603bdd0e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -171,9 +171,9 @@ static INLINE struct brw_reg brw_reg( GLuint file,
{
struct brw_reg reg;
if (type == BRW_GENERAL_REGISTER_FILE)
- assert(nr < 128);
+ assert(nr < BRW_MAX_GRF);
else if (type == BRW_MESSAGE_REGISTER_FILE)
- assert(nr < 9);
+ assert(nr < BRW_MAX_MRF);
else if (type == BRW_ARCHITECTURE_REGISTER_FILE)
assert(nr <= BRW_ARF_IP);
@@ -538,6 +538,7 @@ static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
static INLINE struct brw_reg brw_message_reg( GLuint nr )
{
+ assert(nr < BRW_MAX_MRF);
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
nr,
0);
@@ -815,6 +816,19 @@ void brw_urb_WRITE(struct brw_compile *p,
GLuint offset,
GLuint swizzle);
+void brw_ff_sync(struct brw_compile *p,
+ struct brw_reg dest,
+ GLuint msg_reg_nr,
+ struct brw_reg src0,
+ GLboolean allocate,
+ GLboolean used,
+ GLuint msg_length,
+ GLuint response_length,
+ GLboolean eot,
+ GLboolean writes_complete,
+ GLuint offset,
+ GLuint swizzle);
+
void brw_fb_WRITE(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_reg_nr,
@@ -834,7 +848,9 @@ void brw_SAMPLE(struct brw_compile *p,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
- GLboolean eot);
+ GLboolean eot,
+ GLuint header_present,
+ GLuint simd_mode);
void brw_math_16( struct brw_compile *p,
struct brw_reg dest,
@@ -855,12 +871,10 @@ void brw_math( struct brw_compile *p,
void brw_dp_READ_16( struct brw_compile *p,
struct brw_reg dest,
- GLuint msg_reg_nr,
GLuint scratch_offset );
void brw_dp_READ_4( struct brw_compile *p,
struct brw_reg dest,
- GLuint msg_reg_nr,
GLboolean relAddr,
GLuint location,
GLuint bind_table_index );
@@ -875,7 +889,6 @@ void brw_dp_READ_4_vs( struct brw_compile *p,
void brw_dp_WRITE_16( struct brw_compile *p,
struct brw_reg src,
- GLuint msg_reg_nr,
GLuint scratch_offset );
/* If/else/endif. Works by manipulating the execution flags on each
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 60ea44f7a9..2412014248 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -241,7 +241,8 @@ void brw_set_src1( struct brw_instruction *insn,
-static void brw_set_math_message( struct brw_instruction *insn,
+static void brw_set_math_message( struct brw_context *brw,
+ struct brw_instruction *insn,
GLuint msg_length,
GLuint response_length,
GLuint function,
@@ -252,18 +253,35 @@ static void brw_set_math_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
- insn->bits3.math.function = function;
- insn->bits3.math.int_type = integer_type;
- insn->bits3.math.precision = low_precision;
- insn->bits3.math.saturate = saturate;
- insn->bits3.math.data_type = dataType;
- insn->bits3.math.response_length = response_length;
- insn->bits3.math.msg_length = msg_length;
- insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
- insn->bits3.math.end_of_thread = 0;
+ if (BRW_IS_IGDNG(brw)) {
+ insn->bits3.math_igdng.function = function;
+ insn->bits3.math_igdng.int_type = integer_type;
+ insn->bits3.math_igdng.precision = low_precision;
+ insn->bits3.math_igdng.saturate = saturate;
+ insn->bits3.math_igdng.data_type = dataType;
+ insn->bits3.math_igdng.snapshot = 0;
+ insn->bits3.math_igdng.header_present = 0;
+ insn->bits3.math_igdng.response_length = response_length;
+ insn->bits3.math_igdng.msg_length = msg_length;
+ insn->bits3.math_igdng.end_of_thread = 0;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_MATH;
+ insn->bits2.send_igdng.end_of_thread = 0;
+ } else {
+ insn->bits3.math.function = function;
+ insn->bits3.math.int_type = integer_type;
+ insn->bits3.math.precision = low_precision;
+ insn->bits3.math.saturate = saturate;
+ insn->bits3.math.data_type = dataType;
+ insn->bits3.math.response_length = response_length;
+ insn->bits3.math.msg_length = msg_length;
+ insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
+ insn->bits3.math.end_of_thread = 0;
+ }
}
-static void brw_set_urb_message( struct brw_instruction *insn,
+
+static void brw_set_ff_sync_message( struct brw_context *brw,
+ struct brw_instruction *insn,
GLboolean allocate,
GLboolean used,
GLuint msg_length,
@@ -273,21 +291,64 @@ static void brw_set_urb_message( struct brw_instruction *insn,
GLuint offset,
GLuint swizzle_control )
{
- brw_set_src1(insn, brw_imm_d(0));
+ brw_set_src1(insn, brw_imm_d(0));
+
+ insn->bits3.urb_igdng.opcode = 1;
+ insn->bits3.urb_igdng.offset = offset;
+ insn->bits3.urb_igdng.swizzle_control = swizzle_control;
+ insn->bits3.urb_igdng.allocate = allocate;
+ insn->bits3.urb_igdng.used = used;
+ insn->bits3.urb_igdng.complete = complete;
+ insn->bits3.urb_igdng.header_present = 1;
+ insn->bits3.urb_igdng.response_length = response_length;
+ insn->bits3.urb_igdng.msg_length = msg_length;
+ insn->bits3.urb_igdng.end_of_thread = end_of_thread;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
+ insn->bits2.send_igdng.end_of_thread = end_of_thread;
+}
- insn->bits3.urb.opcode = 0; /* ? */
- insn->bits3.urb.offset = offset;
- insn->bits3.urb.swizzle_control = swizzle_control;
- insn->bits3.urb.allocate = allocate;
- insn->bits3.urb.used = used; /* ? */
- insn->bits3.urb.complete = complete;
- insn->bits3.urb.response_length = response_length;
- insn->bits3.urb.msg_length = msg_length;
- insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
- insn->bits3.urb.end_of_thread = end_of_thread;
+static void brw_set_urb_message( struct brw_context *brw,
+ struct brw_instruction *insn,
+ GLboolean allocate,
+ GLboolean used,
+ GLuint msg_length,
+ GLuint response_length,
+ GLboolean end_of_thread,
+ GLboolean complete,
+ GLuint offset,
+ GLuint swizzle_control )
+{
+ brw_set_src1(insn, brw_imm_d(0));
+
+ if (BRW_IS_IGDNG(brw)) {
+ insn->bits3.urb_igdng.opcode = 0; /* ? */
+ insn->bits3.urb_igdng.offset = offset;
+ insn->bits3.urb_igdng.swizzle_control = swizzle_control;
+ insn->bits3.urb_igdng.allocate = allocate;
+ insn->bits3.urb_igdng.used = used; /* ? */
+ insn->bits3.urb_igdng.complete = complete;
+ insn->bits3.urb_igdng.header_present = 1;
+ insn->bits3.urb_igdng.response_length = response_length;
+ insn->bits3.urb_igdng.msg_length = msg_length;
+ insn->bits3.urb_igdng.end_of_thread = end_of_thread;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
+ insn->bits2.send_igdng.end_of_thread = end_of_thread;
+ } else {
+ insn->bits3.urb.opcode = 0; /* ? */
+ insn->bits3.urb.offset = offset;
+ insn->bits3.urb.swizzle_control = swizzle_control;
+ insn->bits3.urb.allocate = allocate;
+ insn->bits3.urb.used = used; /* ? */
+ insn->bits3.urb.complete = complete;
+ insn->bits3.urb.response_length = response_length;
+ insn->bits3.urb.msg_length = msg_length;
+ insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
+ insn->bits3.urb.end_of_thread = end_of_thread;
+ }
}
-static void brw_set_dp_write_message( struct brw_instruction *insn,
+static void brw_set_dp_write_message( struct brw_context *brw,
+ struct brw_instruction *insn,
GLuint binding_table_index,
GLuint msg_control,
GLuint msg_type,
@@ -298,18 +359,33 @@ static void brw_set_dp_write_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
- insn->bits3.dp_write.binding_table_index = binding_table_index;
- insn->bits3.dp_write.msg_control = msg_control;
- insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
- insn->bits3.dp_write.msg_type = msg_type;
- insn->bits3.dp_write.send_commit_msg = 0;
- insn->bits3.dp_write.response_length = response_length;
- insn->bits3.dp_write.msg_length = msg_length;
- insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
- insn->bits3.urb.end_of_thread = end_of_thread;
+ if (BRW_IS_IGDNG(brw)) {
+ insn->bits3.dp_write_igdng.binding_table_index = binding_table_index;
+ insn->bits3.dp_write_igdng.msg_control = msg_control;
+ insn->bits3.dp_write_igdng.pixel_scoreboard_clear = pixel_scoreboard_clear;
+ insn->bits3.dp_write_igdng.msg_type = msg_type;
+ insn->bits3.dp_write_igdng.send_commit_msg = 0;
+ insn->bits3.dp_write_igdng.header_present = 1;
+ insn->bits3.dp_write_igdng.response_length = response_length;
+ insn->bits3.dp_write_igdng.msg_length = msg_length;
+ insn->bits3.dp_write_igdng.end_of_thread = end_of_thread;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ insn->bits2.send_igdng.end_of_thread = end_of_thread;
+ } else {
+ insn->bits3.dp_write.binding_table_index = binding_table_index;
+ insn->bits3.dp_write.msg_control = msg_control;
+ insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
+ insn->bits3.dp_write.msg_type = msg_type;
+ insn->bits3.dp_write.send_commit_msg = 0;
+ insn->bits3.dp_write.response_length = response_length;
+ insn->bits3.dp_write.msg_length = msg_length;
+ insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ insn->bits3.dp_write.end_of_thread = end_of_thread;
+ }
}
-static void brw_set_dp_read_message( struct brw_instruction *insn,
+static void brw_set_dp_read_message( struct brw_context *brw,
+ struct brw_instruction *insn,
GLuint binding_table_index,
GLuint msg_control,
GLuint msg_type,
@@ -320,15 +396,29 @@ static void brw_set_dp_read_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
- insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
- insn->bits3.dp_read.msg_control = msg_control; /*8:11*/
- insn->bits3.dp_read.msg_type = msg_type; /*12:13*/
- insn->bits3.dp_read.target_cache = target_cache; /*14:15*/
- insn->bits3.dp_read.response_length = response_length; /*16:19*/
- insn->bits3.dp_read.msg_length = msg_length; /*20:23*/
- insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/
- insn->bits3.dp_read.pad1 = 0; /*28:30*/
- insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/
+ if (BRW_IS_IGDNG(brw)) {
+ insn->bits3.dp_read_igdng.binding_table_index = binding_table_index;
+ insn->bits3.dp_read_igdng.msg_control = msg_control;
+ insn->bits3.dp_read_igdng.msg_type = msg_type;
+ insn->bits3.dp_read_igdng.target_cache = target_cache;
+ insn->bits3.dp_read_igdng.header_present = 1;
+ insn->bits3.dp_read_igdng.response_length = response_length;
+ insn->bits3.dp_read_igdng.msg_length = msg_length;
+ insn->bits3.dp_read_igdng.pad1 = 0;
+ insn->bits3.dp_read_igdng.end_of_thread = end_of_thread;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_READ;
+ insn->bits2.send_igdng.end_of_thread = end_of_thread;
+ } else {
+ insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
+ insn->bits3.dp_read.msg_control = msg_control; /*8:11*/
+ insn->bits3.dp_read.msg_type = msg_type; /*12:13*/
+ insn->bits3.dp_read.target_cache = target_cache; /*14:15*/
+ insn->bits3.dp_read.response_length = response_length; /*16:19*/
+ insn->bits3.dp_read.msg_length = msg_length; /*20:23*/
+ insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/
+ insn->bits3.dp_read.pad1 = 0; /*28:30*/
+ insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/
+ }
}
static void brw_set_sampler_message(struct brw_context *brw,
@@ -338,11 +428,25 @@ static void brw_set_sampler_message(struct brw_context *brw,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
- GLboolean eot)
+ GLboolean eot,
+ GLuint header_present,
+ GLuint simd_mode)
{
+ assert(eot == 0);
brw_set_src1(insn, brw_imm_d(0));
- if (BRW_IS_G4X(brw)) {
+ if (BRW_IS_IGDNG(brw)) {
+ insn->bits3.sampler_igdng.binding_table_index = binding_table_index;
+ insn->bits3.sampler_igdng.sampler = sampler;
+ insn->bits3.sampler_igdng.msg_type = msg_type;
+ insn->bits3.sampler_igdng.simd_mode = simd_mode;
+ insn->bits3.sampler_igdng.header_present = header_present;
+ insn->bits3.sampler_igdng.response_length = response_length;
+ insn->bits3.sampler_igdng.msg_length = msg_length;
+ insn->bits3.sampler_igdng.end_of_thread = eot;
+ insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_SAMPLER;
+ insn->bits2.send_igdng.end_of_thread = eot;
+ } else if (BRW_IS_G4X(brw)) {
insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
insn->bits3.sampler_g4x.sampler = sampler;
insn->bits3.sampler_g4x.msg_type = msg_type;
@@ -484,6 +588,10 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p,
{
struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1);
+ insn->header.execution_size = 1;
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+ insn->header.mask_control = BRW_MASK_DISABLE;
+
p->current->header.predicate_control = BRW_PREDICATE_NONE;
return insn;
@@ -540,6 +648,10 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
struct brw_instruction *if_insn)
{
struct brw_instruction *insn;
+ GLuint br = 1;
+
+ if (BRW_IS_IGDNG(p->brw))
+ br = 2;
if (p->single_program_flow) {
insn = next_insn(p, BRW_OPCODE_ADD);
@@ -566,7 +678,7 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
} else {
assert(if_insn->header.opcode == BRW_OPCODE_IF);
- if_insn->bits3.if_else.jump_count = insn - if_insn;
+ if_insn->bits3.if_else.jump_count = br * (insn - if_insn);
if_insn->bits3.if_else.pop_count = 1;
if_insn->bits3.if_else.pad0 = 0;
}
@@ -577,6 +689,11 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
void brw_ENDIF(struct brw_compile *p,
struct brw_instruction *patch_insn)
{
+ GLuint br = 1;
+
+ if (BRW_IS_IGDNG(p->brw))
+ br = 2;
+
if (p->single_program_flow) {
/* In single program flow mode, there's no need to execute an ENDIF,
* since we don't need to do any stack operations, and if we're executing
@@ -608,11 +725,11 @@ void brw_ENDIF(struct brw_compile *p,
/* Automagically turn it into an IFF:
*/
patch_insn->header.opcode = BRW_OPCODE_IFF;
- patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
+ patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1);
patch_insn->bits3.if_else.pop_count = 0;
patch_insn->bits3.if_else.pad0 = 0;
} else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) {
- patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1;
+ patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1);
patch_insn->bits3.if_else.pop_count = 1;
patch_insn->bits3.if_else.pad0 = 0;
} else {
@@ -686,6 +803,10 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *do_insn)
{
struct brw_instruction *insn;
+ GLuint br = 1;
+
+ if (BRW_IS_IGDNG(p->brw))
+ br = 2;
if (p->single_program_flow)
insn = next_insn(p, BRW_OPCODE_ADD);
@@ -706,7 +827,7 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
insn->header.execution_size = do_insn->header.execution_size;
assert(do_insn->header.opcode == BRW_OPCODE_DO);
- insn->bits3.if_else.jump_count = do_insn - insn + 1;
+ insn->bits3.if_else.jump_count = br * (do_insn - insn + 1);
insn->bits3.if_else.pop_count = 0;
insn->bits3.if_else.pad0 = 0;
}
@@ -725,11 +846,15 @@ void brw_land_fwd_jump(struct brw_compile *p,
struct brw_instruction *jmp_insn)
{
struct brw_instruction *landing = &p->store[p->nr_insn];
+ GLuint jmpi = 1;
+
+ if (BRW_IS_IGDNG(p->brw))
+ jmpi = 2;
assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE);
- jmp_insn->bits3.ud = (landing - jmp_insn) - 1;
+ jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1);
}
@@ -794,7 +919,8 @@ void brw_math( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
- brw_set_math_message(insn,
+ brw_set_math_message(p->brw,
+ insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@@ -830,7 +956,8 @@ void brw_math_16( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
- brw_set_math_message(insn,
+ brw_set_math_message(p->brw,
+ insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@@ -846,7 +973,8 @@ void brw_math_16( struct brw_compile *p,
brw_set_dest(insn, offset(dest,1));
brw_set_src0(insn, src);
- brw_set_math_message(insn,
+ brw_set_math_message(p->brw,
+ insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@@ -865,9 +993,9 @@ void brw_math_16( struct brw_compile *p,
*/
void brw_dp_WRITE_16( struct brw_compile *p,
struct brw_reg src,
- GLuint msg_reg_nr,
GLuint scratch_offset )
{
+ GLuint msg_reg_nr = 1;
{
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE);
@@ -877,7 +1005,7 @@ void brw_dp_WRITE_16( struct brw_compile *p,
brw_MOV(p,
retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D),
brw_imm_d(scratch_offset));
-
+
brw_pop_insn_state(p);
}
@@ -893,7 +1021,8 @@ void brw_dp_WRITE_16( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
- brw_set_dp_write_message(insn,
+ brw_set_dp_write_message(p->brw,
+ insn,
255, /* binding table index (255=stateless) */
BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */
BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */
@@ -912,9 +1041,9 @@ void brw_dp_WRITE_16( struct brw_compile *p,
*/
void brw_dp_READ_16( struct brw_compile *p,
struct brw_reg dest,
- GLuint msg_reg_nr,
GLuint scratch_offset )
{
+ GLuint msg_reg_nr = 1;
{
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
@@ -924,7 +1053,7 @@ void brw_dp_READ_16( struct brw_compile *p,
brw_MOV(p,
retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D),
brw_imm_d(scratch_offset));
-
+
brw_pop_insn_state(p);
}
@@ -938,7 +1067,8 @@ void brw_dp_READ_16( struct brw_compile *p,
brw_set_dest(insn, dest); /* UW? */
brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
- brw_set_dp_read_message(insn,
+ brw_set_dp_read_message(p->brw,
+ insn,
255, /* binding table index (255=stateless) */
3, /* msg_control (3 means 4 Owords) */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@@ -958,21 +1088,26 @@ void brw_dp_READ_16( struct brw_compile *p,
*/
void brw_dp_READ_4( struct brw_compile *p,
struct brw_reg dest,
- GLuint msg_reg_nr,
GLboolean relAddr,
GLuint location,
GLuint bind_table_index )
{
+ /* XXX: relAddr not implemented */
+ GLuint msg_reg_nr = 1;
{
+ struct brw_reg b;
brw_push_insn_state(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_mask_control(p, BRW_MASK_DISABLE);
- /* set message header global offset field (reg 0, element 2) */
- /* Note that grf[0] will be copied to mrf[1] implicitly by the SEND instr */
- brw_MOV(p,
- retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD),
- brw_imm_d(location));
+ /* Setup MRF[1] with location/offset into const buffer */
+ b = brw_message_reg(msg_reg_nr);
+ b = retype(b, BRW_REGISTER_TYPE_UD);
+ /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
+ * when the docs say only dword[2] should be set. Hmmm. But it works.
+ */
+ brw_MOV(p, b, brw_imm_ud(location));
brw_pop_insn_state(p);
}
@@ -988,9 +1123,10 @@ void brw_dp_READ_4( struct brw_compile *p,
dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
brw_set_dest(insn, dest);
- brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
+ brw_set_src0(insn, brw_null_reg());
- brw_set_dp_read_message(insn,
+ brw_set_dp_read_message(p->brw,
+ insn,
bind_table_index,
0, /* msg_control (0 means 1 Oword) */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@@ -1061,7 +1197,8 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, brw_null_reg());
- brw_set_dp_read_message(insn,
+ brw_set_dp_read_message(p->brw,
+ insn,
bind_table_index,
oword, /* 0 = lower Oword, 1 = upper Oword */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@@ -1091,7 +1228,8 @@ void brw_fb_WRITE(struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
- brw_set_dp_write_message(insn,
+ brw_set_dp_write_message(p->brw,
+ insn,
binding_table_index,
BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */
BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
@@ -1117,7 +1255,9 @@ void brw_SAMPLE(struct brw_compile *p,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
- GLboolean eot)
+ GLboolean eot,
+ GLuint header_present,
+ GLuint simd_mode)
{
GLboolean need_stall = 0;
@@ -1192,7 +1332,9 @@ void brw_SAMPLE(struct brw_compile *p,
msg_type,
response_length,
msg_length,
- eot);
+ eot,
+ header_present,
+ simd_mode);
}
if (need_stall) {
@@ -1227,7 +1369,7 @@ void brw_urb_WRITE(struct brw_compile *p,
{
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
- assert(msg_length < 16);
+ assert(msg_length < BRW_MAX_MRF);
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
@@ -1235,7 +1377,8 @@ void brw_urb_WRITE(struct brw_compile *p,
insn->header.destreg__conditonalmod = msg_reg_nr;
- brw_set_urb_message(insn,
+ brw_set_urb_message(p->brw,
+ insn,
allocate,
used,
msg_length,
@@ -1246,3 +1389,37 @@ void brw_urb_WRITE(struct brw_compile *p,
swizzle);
}
+void brw_ff_sync(struct brw_compile *p,
+ struct brw_reg dest,
+ GLuint msg_reg_nr,
+ struct brw_reg src0,
+ GLboolean allocate,
+ GLboolean used,
+ GLuint msg_length,
+ GLuint response_length,
+ GLboolean eot,
+ GLboolean writes_complete,
+ GLuint offset,
+ GLuint swizzle)
+{
+ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+
+ assert(msg_length < 16);
+
+ brw_set_dest(insn, dest);
+ brw_set_src0(insn, src0);
+ brw_set_src1(insn, brw_imm_d(0));
+
+ insn->header.destreg__conditonalmod = msg_reg_nr;
+
+ brw_set_ff_sync_message(p->brw,
+ insn,
+ allocate,
+ used,
+ msg_length,
+ response_length,
+ eot,
+ writes_complete,
+ offset,
+ swizzle);
+}
diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c
index 299357409c..d27c6c24ca 100644
--- a/src/mesa/drivers/dri/i965/brw_fallback.c
+++ b/src/mesa/drivers/dri/i965/brw_fallback.c
@@ -37,6 +37,9 @@
#include "tnl/tnl.h"
#include "brw_context.h"
#include "brw_fallback.h"
+#include "intel_chipset.h"
+#include "intel_fbo.h"
+#include "intel_regions.h"
#include "glapi/glapi.h"
@@ -44,6 +47,7 @@
static GLboolean do_check_fallback(struct brw_context *brw)
{
+ struct intel_context *intel = &brw->intel;
GLcontext *ctx = &brw->intel.ctx;
GLuint i;
@@ -81,6 +85,33 @@ static GLboolean do_check_fallback(struct brw_context *brw)
return GL_TRUE;
}
+ /* _NEW_BUFFERS */
+ if (IS_965(intel->intelScreen->deviceID) &&
+ !IS_G4X(intel->intelScreen->deviceID)) {
+ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+ /* The original gen4 hardware couldn't set up WM surfaces pointing
+ * at an offset within a tile, which can happen when rendering to
+ * anything but the base level of a texture or the +X face/0 depth.
+ * This was fixed with the 4 Series hardware.
+ *
+ * For these original chips, you would have to make the depth and
+ * color destination surfaces include information on the texture
+ * type, LOD, face, and various limits to use them as a destination.
+ * I would have done this, but there's also a nasty requirement that
+ * the depth and the color surfaces all be of the same LOD, which
+ * may be a worse requirement than this alignment. (Also, we may
+ * want to just demote the texture to untiled, instead).
+ */
+ if (irb->region && irb->region->tiling != I915_TILING_NONE &&
+ (irb->region->draw_offset & 4095)) {
+ DBG("FALLBACK: non-tile-aligned destination for tiled FBO\n");
+ return GL_TRUE;
+ }
+ }
+ }
return GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index a8b74a0afe..48c2b9a41c 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -54,12 +54,17 @@ static void compile_gs_prog( struct brw_context *brw,
memset(&c, 0, sizeof(c));
c.key = *key;
-
+ c.need_ff_sync = BRW_IS_IGDNG(brw);
/* Need to locate the two positions present in vertex + header.
* These are currently hardcoded:
*/
c.nr_attrs = brw_count_bits(c.key.attrs);
- c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+
+ if (BRW_IS_IGDNG(brw))
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
+ else
+ c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+
c.nr_bytes = c.nr_regs * REG_SIZE;
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 18a4537c32..bbb991ea2e 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -62,6 +62,7 @@ struct brw_gs_compile {
GLuint nr_attrs;
GLuint nr_regs;
GLuint nr_bytes;
+ GLboolean need_ff_sync;
};
#define ATTR_SIZE (4*4)
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 22e0d25c2e..980eac7646 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -101,6 +101,23 @@ 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)
+{
+ struct brw_compile *p = &c->func;
+ brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
+ brw_ff_sync(p,
+ c->reg.R0,
+ 0,
+ c->reg.R0,
+ 1,
+ 1, /* used */
+ 1, /* msg length */
+ 1, /* response length */
+ 0, /* eot */
+ 1, /* write compelete */
+ 0, /* urb offset */
+ BRW_URB_SWIZZLE_NONE);
+}
void brw_gs_quads( struct brw_gs_compile *c )
@@ -110,6 +127,8 @@ void brw_gs_quads( struct brw_gs_compile *c )
/* Use polygons for correct edgeflag behaviour. Note that vertex 3
* is the PV for quads, but vertex 0 for polygons:
*/
+ if (c->need_ff_sync)
+ brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
@@ -120,6 +139,8 @@ void brw_gs_quad_strip( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 4);
+ if (c->need_ff_sync)
+ brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
@@ -129,6 +150,9 @@ void brw_gs_quad_strip( struct brw_gs_compile *c )
void brw_gs_tris( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 3);
+
+ if (c->need_ff_sync)
+ brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2));
brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END));
@@ -137,6 +161,9 @@ void brw_gs_tris( struct brw_gs_compile *c )
void brw_gs_lines( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 2);
+
+ if (c->need_ff_sync)
+ brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END));
}
@@ -144,6 +171,9 @@ void brw_gs_lines( struct brw_gs_compile *c )
void brw_gs_points( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 1);
+
+ if (c->need_ff_sync)
+ brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END));
}
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index 27023cf034..a761c03153 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -95,6 +95,9 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key)
gs.thread4.max_threads = 0; /* Hardware requirement */
+ if (BRW_IS_IGDNG(brw))
+ gs.thread4.rendering_enable = 1;
+
if (INTEL_DEBUG & DEBUG_STATS)
gs.thread4.stats_enable = 1;
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 4784254bc7..85a7706404 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -211,7 +211,7 @@ static void emit_depthbuffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
struct intel_region *region = brw->state.depth_region;
- unsigned int len = BRW_IS_G4X(brw) ? 6 : 5;
+ unsigned int len = (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? 6 : 5;
if (region == NULL) {
BEGIN_BATCH(len, IGNORE_CLIPRECTS);
@@ -222,7 +222,7 @@ static void emit_depthbuffer(struct brw_context *brw)
OUT_BATCH(0);
OUT_BATCH(0);
- if (BRW_IS_G4X(brw))
+ if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
OUT_BATCH(0);
ADVANCE_BATCH();
@@ -244,6 +244,8 @@ static void emit_depthbuffer(struct brw_context *brw)
return;
}
+ assert(region->tiling != I915_TILING_X);
+
BEGIN_BATCH(len, IGNORE_CLIPRECTS);
OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
OUT_BATCH(((region->pitch * region->cpp) - 1) |
@@ -259,7 +261,7 @@ static void emit_depthbuffer(struct brw_context *brw)
((region->height - 1) << 19));
OUT_BATCH(0);
- if (BRW_IS_G4X(brw))
+ if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
OUT_BATCH(0);
ADVANCE_BATCH();
@@ -372,7 +374,7 @@ static void upload_aa_line_parameters(struct brw_context *brw)
{
struct brw_aa_line_parameters balp;
- if (!BRW_IS_G4X(brw))
+ if (BRW_IS_965(brw))
return;
/* use legacy aa line coverage computation */
@@ -509,14 +511,27 @@ static void upload_state_base_address( struct brw_context *brw )
/* Output the structure (brw_state_base_address) directly to the
* batchbuffer, so we can emit relocations inline.
*/
- BEGIN_BATCH(6, IGNORE_CLIPRECTS);
- OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
- OUT_BATCH(1); /* General state base address */
- OUT_BATCH(1); /* Surface state base address */
- OUT_BATCH(1); /* Indirect object base address */
- OUT_BATCH(1); /* General state upper bound */
- OUT_BATCH(1); /* Indirect object upper bound */
- ADVANCE_BATCH();
+ if (BRW_IS_IGDNG(brw)) {
+ BEGIN_BATCH(8, IGNORE_CLIPRECTS);
+ OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
+ OUT_BATCH(1); /* General state base address */
+ OUT_BATCH(1); /* Surface state base address */
+ OUT_BATCH(1); /* Indirect object base address */
+ OUT_BATCH(1); /* Instruction base address */
+ OUT_BATCH(1); /* General state upper bound */
+ OUT_BATCH(1); /* Indirect object upper bound */
+ OUT_BATCH(1); /* Instruction access upper bound */
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(6, IGNORE_CLIPRECTS);
+ OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
+ OUT_BATCH(1); /* General state base address */
+ OUT_BATCH(1); /* Surface state base address */
+ OUT_BATCH(1); /* Indirect object base address */
+ OUT_BATCH(1); /* General state upper bound */
+ OUT_BATCH(1); /* Indirect object upper bound */
+ ADVANCE_BATCH();
+ }
}
const struct brw_tracked_state brw_state_base_address = {
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index c3c85978f4..e1c2c7777b 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -166,6 +166,9 @@ static void upload_sf_prog(struct brw_context *brw)
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
+ /* _NEW_HINT */
+ key.linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
+
/* _NEW_POLYGON */
if (key.do_twoside_color) {
/* If we're rendering to a FBO, we have to invert the polygon
@@ -188,7 +191,7 @@ static void upload_sf_prog(struct brw_context *brw)
const struct brw_tracked_state brw_sf_prog = {
.dirty = {
- .mesa = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT),
+ .mesa = (_NEW_HINT | _NEW_LIGHT | _NEW_POLYGON | _NEW_POINT),
.brw = (BRW_NEW_REDUCED_PRIMITIVE),
.cache = CACHE_NEW_VS_PROG
},
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h
index 1c0fb70fe0..6426b6df9f 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.h
+++ b/src/mesa/drivers/dri/i965/brw_sf.h
@@ -51,7 +51,8 @@ struct brw_sf_prog_key {
GLuint do_flat_shading:1;
GLuint frontface_ccw:1;
GLuint do_point_sprite:1;
- GLuint pad:10;
+ GLuint linear_color:1; /**< linear interp vs. perspective interp */
+ GLuint pad:25;
GLenum SpriteOrigin;
};
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index 862835f157..ca8f97f9f9 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -151,6 +151,8 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
+ GLuint jmpi = 1;
+
if (!nr)
return;
@@ -159,18 +161,21 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
+ if (BRW_IS_IGDNG(p->brw))
+ jmpi = 2;
+
brw_push_insn_state(p);
- brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr*2+1));
+ brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
copy_colors(c, c->vert[2], c->vert[0]);
- brw_JMPI(p, ip, ip, brw_imm_ud(nr*4+1));
+ brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));
copy_colors(c, c->vert[0], c->vert[1]);
copy_colors(c, c->vert[2], c->vert[1]);
- brw_JMPI(p, ip, ip, brw_imm_ud(nr*2));
+ brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));
copy_colors(c, c->vert[0], c->vert[2]);
copy_colors(c, c->vert[1], c->vert[2]);
@@ -184,7 +189,8 @@ static void do_flatshade_line( struct brw_sf_compile *c )
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
-
+ GLuint jmpi = 1;
+
if (!nr)
return;
@@ -193,13 +199,16 @@ static void do_flatshade_line( struct brw_sf_compile *c )
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
+ if (BRW_IS_IGDNG(p->brw))
+ jmpi = 2;
+
brw_push_insn_state(p);
- brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr+1));
+ brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
- brw_JMPI(p, ip, ip, brw_imm_ud(nr));
+ brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
copy_colors(c, c->vert[0], c->vert[1]);
brw_pop_insn_state(p);
@@ -218,7 +227,7 @@ static void alloc_regs( struct brw_sf_compile *c )
/* Values computed by fixed function unit:
*/
- c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD);
+ c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D);
c->det = brw_vec1_grf(1, 2);
c->dx0 = brw_vec1_grf(1, 3);
c->dx2 = brw_vec1_grf(1, 4);
@@ -295,9 +304,6 @@ static void invert_det( struct brw_sf_compile *c)
}
-#define NON_PERPECTIVE_ATTRS (FRAG_BIT_WPOS | \
- FRAG_BIT_COL0 | \
- FRAG_BIT_COL1)
static GLboolean calculate_masks( struct brw_sf_compile *c,
GLuint reg,
@@ -306,9 +312,16 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
GLushort *pc_linear)
{
GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
- GLuint persp_mask = c->key.attrs & ~NON_PERPECTIVE_ATTRS;
+ GLuint persp_mask;
GLuint linear_mask;
+ if (c->key.do_flat_shading || c->key.linear_color)
+ persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
+ FRAG_BIT_COL0 |
+ FRAG_BIT_COL1);
+ else
+ persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS);
+
if (c->key.do_flat_shading)
linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1);
else
@@ -674,7 +687,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
(1<<_3DPRIM_POLYGON) |
(1<<_3DPRIM_RECTLIST) |
(1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
- jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
+ jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
{
saveflag = p->flag_value;
brw_push_insn_state(p);
@@ -695,7 +708,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
(1<<_3DPRIM_LINESTRIP_CONT) |
(1<<_3DPRIM_LINESTRIP_BF) |
(1<<_3DPRIM_LINESTRIP_CONT_BF)));
- jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
+ jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
{
saveflag = p->flag_value;
brw_push_insn_state(p);
@@ -708,7 +721,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
- jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
+ jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
{
saveflag = p->flag_value;
brw_push_insn_state(p);
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index c99918724b..e73e57a1c8 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -162,7 +162,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
{
struct brw_sf_unit_state sf;
dri_bo *bo;
-
+ int chipset_max_threads;
memset(&sf, 0, sizeof(sf));
sf.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1;
@@ -171,13 +171,26 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
sf.thread3.dispatch_grf_start_reg = 3;
- sf.thread3.urb_entry_read_offset = 1;
+
+ if (BRW_IS_IGDNG(brw))
+ sf.thread3.urb_entry_read_offset = 3;
+ else
+ sf.thread3.urb_entry_read_offset = 1;
+
sf.thread3.urb_entry_read_length = key->urb_entry_read_length;
sf.thread4.nr_urb_entries = key->nr_urb_entries;
sf.thread4.urb_entry_allocation_size = key->sfsize - 1;
- /* Each SF thread produces 1 PUE, and there can be up to 24 threads */
- sf.thread4.max_threads = MIN2(24, key->nr_urb_entries) - 1;
+
+ /* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or
+ * 48(IGDNG) threads
+ */
+ if (BRW_IS_IGDNG(brw))
+ chipset_max_threads = 48;
+ else
+ chipset_max_threads = 24;
+
+ sf.thread4.max_threads = MIN2(chipset_max_threads, key->nr_urb_entries) - 1;
if (INTEL_DEBUG & DEBUG_SINGLE_THREAD)
sf.thread4.max_threads = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c
index a713262269..e94fa7d2b4 100644
--- a/src/mesa/drivers/dri/i965/brw_state_dump.c
+++ b/src/mesa/drivers/dri/i965/brw_state_dump.c
@@ -126,6 +126,8 @@ static void dump_wm_surface_state(struct brw_context *brw)
surf->ss3.pitch + 1, surf->ss3.tiled_surface ? "" : "not ");
state_out(name, surf, surfoff, 4, "mip base %d\n",
surf->ss4.min_lod);
+ state_out(name, surf, surfoff, 5, "x,y offset: %d,%d\n",
+ surf->ss5.x_offset, surf->ss5.y_offset);
dri_bo_unmap(surf_bo);
}
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index c6dfea4743..38d9dd8991 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -205,7 +205,6 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_PRIMITIVE),
DEFINE_BIT(BRW_NEW_CONTEXT),
DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS),
- DEFINE_BIT(BRW_NEW_INPUT_VARYING),
DEFINE_BIT(BRW_NEW_PSP),
DEFINE_BIT(BRW_NEW_FENCE),
DEFINE_BIT(BRW_NEW_INDICES),
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 89e2981203..8ba7eb27b3 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -33,6 +33,14 @@
#ifndef BRW_STRUCTS_H
#define BRW_STRUCTS_H
+
+/** Number of general purpose registers (VS, WM, etc) */
+#define BRW_MAX_GRF 128
+
+/** Number of message register file registers */
+#define BRW_MAX_MRF 16
+
+
/* Command packets:
*/
struct header
@@ -815,7 +823,9 @@ struct brw_gs_unit_state
struct
{
- GLuint pad0:10;
+ GLuint pad0:8;
+ GLuint rendering_enable:1; /* for IGDNG */
+ GLuint pad4:1;
GLuint stats_enable:1;
GLuint nr_urb_entries:7;
GLuint pad1:1;
@@ -923,6 +933,28 @@ struct brw_wm_unit_state
GLfloat global_depth_offset_constant;
GLfloat global_depth_offset_scale;
+
+ /* for IGDNG only */
+ struct {
+ GLuint pad0:1;
+ GLuint grf_reg_count_1:3;
+ GLuint pad1:2;
+ GLuint kernel_start_pointer_1:26;
+ } wm8;
+
+ struct {
+ GLuint pad0:1;
+ GLuint grf_reg_count_2:3;
+ GLuint pad1:2;
+ GLuint kernel_start_pointer_2:26;
+ } wm9;
+
+ struct {
+ GLuint pad0:1;
+ GLuint grf_reg_count_3:3;
+ GLuint pad1:2;
+ GLuint kernel_start_pointer_3:26;
+ } wm10;
};
struct brw_sampler_default_color {
@@ -1075,7 +1107,7 @@ struct brw_surface_state
GLuint y_offset:4;
GLuint pad0:1;
GLuint x_offset:7;
- } ss5; /* NEW in Integrated Graphics Device */
+ } ss5; /* New in G4X */
};
@@ -1298,6 +1330,14 @@ struct brw_instruction
GLuint pad1:6;
} ia16;
+ struct
+ {
+ GLuint pad:26;
+ GLuint end_of_thread:1;
+ GLuint pad1:1;
+ GLuint sfid:4;
+ } send_igdng; /* for IGDNG only */
+
} bits2;
union
@@ -1385,6 +1425,21 @@ struct brw_instruction
} math;
struct {
+ GLuint function:4;
+ GLuint int_type:1;
+ GLuint precision:1;
+ GLuint saturate:1;
+ GLuint data_type:1;
+ GLuint snapshot:1;
+ GLuint pad0:10;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } math_igdng;
+
+ struct {
GLuint binding_table_index:8;
GLuint sampler:4;
GLuint return_format:2;
@@ -1407,9 +1462,38 @@ struct brw_instruction
GLuint end_of_thread:1;
} sampler_g4x;
+ struct {
+ GLuint binding_table_index:8;
+ GLuint sampler:4;
+ GLuint msg_type:4;
+ GLuint simd_mode:2;
+ GLuint pad0:1;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } sampler_igdng;
+
struct brw_urb_immediate urb;
struct {
+ GLuint opcode:4;
+ GLuint offset:6;
+ GLuint swizzle_control:2;
+ GLuint pad:1;
+ GLuint allocate:1;
+ GLuint used:1;
+ GLuint complete:1;
+ GLuint pad0:3;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } urb_igdng;
+
+ struct {
GLuint binding_table_index:8;
GLuint msg_control:4;
GLuint msg_type:2;
@@ -1423,6 +1507,19 @@ struct brw_instruction
struct {
GLuint binding_table_index:8;
+ GLuint msg_control:3;
+ GLuint msg_type:3;
+ GLuint target_cache:2;
+ GLuint pad0:3;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } dp_read_igdng;
+
+ struct {
+ GLuint binding_table_index:8;
GLuint msg_control:3;
GLuint pixel_scoreboard_clear:1;
GLuint msg_type:3;
@@ -1435,6 +1532,20 @@ struct brw_instruction
} dp_write;
struct {
+ GLuint binding_table_index:8;
+ GLuint msg_control:3;
+ GLuint pixel_scoreboard_clear:1;
+ GLuint msg_type:3;
+ GLuint send_commit_msg:1;
+ GLuint pad0:3;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } dp_write_igdng;
+
+ struct {
GLuint pad:16;
GLuint response_length:4;
GLuint msg_length:4;
@@ -1443,6 +1554,15 @@ struct brw_instruction
GLuint end_of_thread:1;
} generic;
+ struct {
+ GLuint pad:19;
+ GLuint header_present:1;
+ GLuint response_length:5;
+ GLuint msg_length:4;
+ GLuint pad1:2;
+ GLuint end_of_thread:1;
+ } generic_igdng;
+
GLint d;
GLuint ud;
} bits3;
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 5c5455813a..7f9b253534 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -36,6 +36,7 @@
#include "intel_tex_layout.h"
#include "intel_context.h"
#include "main/macros.h"
+#include "intel_chipset.h"
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
@@ -48,6 +49,77 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
+ if (IS_IGDNG(intel->intelScreen->deviceID)) {
+ GLuint align_h = 2, align_w = 4;
+ GLuint level;
+ GLuint x = 0;
+ GLuint y = 0;
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+ GLuint qpitch = 0;
+ GLuint y_pitch = 0;
+
+ mt->pitch = mt->width0;
+ intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
+ y_pitch = ALIGN(height, align_h);
+
+ 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) {
+ GLuint mip1_width;
+
+ if (mt->compressed) {
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ + ALIGN(minify(minify(mt->width0)), align_w);
+ } else {
+ mip1_width = ALIGN(minify(mt->width0), align_w)
+ + minify(minify(mt->width0));
+ }
+
+ if (mip1_width > mt->pitch) {
+ mt->pitch = mip1_width;
+ }
+ }
+
+ mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch);
+
+ for (level = mt->first_level; level <= mt->last_level; level++) {
+ GLuint img_height;
+ GLuint nr_images = 6;
+ GLuint q = 0;
+
+ intel_miptree_set_level_info(mt, level, nr_images, x, y, width,
+ height, 1);
+
+ for (q = 0; q < nr_images; q++)
+ intel_miptree_set_image_offset_ex(mt, level, q, x, y, q * qpitch);
+
+ if (mt->compressed)
+ img_height = MAX2(1, height/4);
+ else
+ img_height = ALIGN(height, align_h);
+
+ if (level == mt->first_level + 1) {
+ x += ALIGN(width, align_w);
+ }
+ else {
+ y += img_height;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ }
+
+ break;
+ }
+
case GL_TEXTURE_3D: {
GLuint width = mt->width0;
GLuint height = mt->height0;
@@ -59,9 +131,9 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
GLuint align_w = 4;
mt->total_height = 0;
+ intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
if (mt->compressed) {
- align_w = intel_compressed_alignment(mt->internal_format);
mt->pitch = ALIGN(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else {
@@ -69,7 +141,7 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
pack_y_pitch = ALIGN(mt->height0, align_h);
}
- pack_x_pitch = mt->pitch;
+ pack_x_pitch = width;
pack_x_nr = 1;
for (level = mt->first_level ; level <= mt->last_level ; level++) {
diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
index 7673dd36eb..8c6f4355a6 100644
--- a/src/mesa/drivers/dri/i965/brw_urb.c
+++ b/src/mesa/drivers/dri/i965/brw_urb.c
@@ -143,7 +143,29 @@ static void recalculate_urb_fence( struct brw_context *brw )
brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries;
brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;
-
+
+ brw->urb.constrained = 0;
+
+ if (BRW_IS_IGDNG(brw)) {
+ brw->urb.nr_vs_entries = 128;
+ brw->urb.nr_sf_entries = 48;
+ if (check_urb_layout(brw)) {
+ goto done;
+ } else {
+ brw->urb.constrained = 1;
+ brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
+ brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
+ }
+ } else if (BRW_IS_G4X(brw)) {
+ brw->urb.nr_vs_entries = 64;
+ if (check_urb_layout(brw)) {
+ goto done;
+ } else {
+ brw->urb.constrained = 1;
+ brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
+ }
+ }
+
if (!check_urb_layout(brw)) {
brw->urb.nr_vs_entries = limits[VS].min_nr_entries;
brw->urb.nr_gs_entries = limits[GS].min_nr_entries;
@@ -169,9 +191,8 @@ static void recalculate_urb_fence( struct brw_context *brw )
if (INTEL_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS))
_mesa_printf("URB CONSTRAINED\n");
}
- else
- brw->urb.constrained = 0;
+done:
if (INTEL_DEBUG & DEBUG_URB)
_mesa_printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n",
brw->urb.vs_start,
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 1e4f66091e..4a591365c9 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -58,6 +58,7 @@ struct brw_vs_compile {
GLuint first_output;
GLuint nr_outputs;
+ GLuint first_overflow_output; /**< VERT_ATTRIB_x */
GLuint first_tmp;
GLuint last_tmp;
diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c
index 2637344b48..249a800bf4 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_constval.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c
@@ -39,8 +39,8 @@
*/
struct tracker {
GLboolean twoside;
- GLubyte active[PROGRAM_OUTPUT+1][128];
- GLuint size_masks[4];
+ GLubyte active[PROGRAM_OUTPUT+1][MAX_PROGRAM_TEMPS];
+ GLbitfield size_masks[4]; /**< one bit per fragment program input attrib */
};
@@ -53,8 +53,10 @@ static void set_active_component( struct tracker *t,
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
+ assert(file < PROGRAM_OUTPUT + 1);
+ assert(index < Elements(t->active[0]));
t->active[file][index] |= active;
-
+ break;
default:
break;
}
@@ -108,10 +110,15 @@ static GLubyte get_active( struct tracker *t,
return active;
}
+/**
+ * Return the size (1,2,3 or 4) of the output/result for VERT_RESULT_idx.
+ */
static GLubyte get_output_size( struct tracker *t,
GLuint idx )
{
- GLubyte active = t->active[PROGRAM_OUTPUT][idx];
+ GLubyte active;
+ assert(idx < VERT_RESULT_MAX);
+ active = t->active[PROGRAM_OUTPUT][idx];
if (active & (1<<3)) return 4;
if (active & (1<<2)) return 3;
if (active & (1<<1)) return 2;
@@ -123,7 +130,7 @@ static GLubyte get_output_size( struct tracker *t,
*/
static void calc_sizes( struct tracker *t )
{
- GLuint i;
+ GLint vertRes;
if (t->twoside) {
t->active[PROGRAM_OUTPUT][VERT_RESULT_COL0] |=
@@ -133,12 +140,27 @@ static void calc_sizes( struct tracker *t )
t->active[PROGRAM_OUTPUT][VERT_RESULT_BFC1];
}
- for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
- switch (get_output_size(t, i)) {
- case 4: t->size_masks[4-1] |= 1<<i;
- case 3: t->size_masks[3-1] |= 1<<i;
- case 2: t->size_masks[2-1] |= 1<<i;
- case 1: t->size_masks[1-1] |= 1<<i;
+ /* Examine vertex program output sizes to set the size_masks[] info
+ * which describes the fragment program input sizes.
+ */
+ for (vertRes = VERT_RESULT_TEX0; vertRes < VERT_RESULT_MAX; vertRes++) {
+ GLint fragAttrib;
+
+ /* map vertex program output index to fragment program input index */
+ if (vertRes <= VERT_RESULT_TEX7)
+ fragAttrib = FRAG_ATTRIB_TEX0 + vertRes - VERT_RESULT_TEX0;
+ else if (vertRes >= VERT_RESULT_VAR0)
+ fragAttrib = FRAG_ATTRIB_VAR0 + vertRes - VERT_RESULT_VAR0;
+ else
+ continue;
+ assert(fragAttrib >= FRAG_ATTRIB_TEX0);
+ assert(fragAttrib <= FRAG_ATTRIB_MAX);
+
+ switch (get_output_size(t, vertRes)) {
+ case 4: t->size_masks[4-1] |= 1 << fragAttrib;
+ case 3: t->size_masks[3-1] |= 1 << fragAttrib;
+ case 2: t->size_masks[2-1] |= 1 << fragAttrib;
+ case 1: t->size_masks[1-1] |= 1 << fragAttrib;
break;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index d7f75e3685..514f15d5e3 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -129,15 +129,21 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
}
}
- /* Allocate outputs: TODO: could organize the non-position outputs
- * to go straight into message regs.
+ /* Allocate outputs. The non-position outputs go straight into message regs.
*/
c->nr_outputs = 0;
c->first_output = reg;
- mrf = 4;
+ c->first_overflow_output = 0;
+
+ if (BRW_IS_IGDNG(c->func.brw))
+ mrf = 8;
+ else
+ mrf = 4;
+
for (i = 0; i < VERT_RESULT_MAX; i++) {
if (c->prog_data.outputs_written & (1 << i)) {
c->nr_outputs++;
+ assert(i < Elements(c->regs[PROGRAM_OUTPUT]));
if (i == VERT_RESULT_HPOS) {
c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
@@ -148,8 +154,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
mrf++; /* just a placeholder? XXX fix later stages & remove this */
}
else {
- c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
- mrf++;
+ if (mrf < 16) {
+ c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
+ mrf++;
+ }
+ else {
+ /* too many vertex results to fit in MRF, use GRF for overflow */
+ if (!c->first_overflow_output)
+ c->first_overflow_output = i;
+ c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
+ reg++;
+ }
}
}
}
@@ -206,7 +221,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
*/
c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
- c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
+ if (BRW_IS_IGDNG(c->func.brw))
+ c->prog_data.urb_entry_size = (c->nr_outputs + 6 + 3) / 4;
+ else
+ c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
+
c->prog_data.total_grf = reg;
if (INTEL_DEBUG & DEBUG_VS) {
@@ -1067,6 +1086,8 @@ static void emit_vertex_write( struct brw_vs_compile *c)
struct brw_reg m0 = brw_message_reg(0);
struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];
struct brw_reg ndc;
+ int eot;
+ GLuint len_vertext_header = 2;
if (c->key.copy_edgeflag) {
brw_MOV(p,
@@ -1076,14 +1097,16 @@ static void emit_vertex_write( struct brw_vs_compile *c)
/* Build ndc coords */
ndc = get_tmp(c);
+ /* ndc = 1.0 / pos.w */
emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL);
+ /* ndc.xyz = pos * ndc */
brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc);
/* Update the header for point size, user clipping flags, and -ve rhw
* workaround.
*/
if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) ||
- c->key.nr_userclip || !BRW_IS_G4X(p->brw))
+ c->key.nr_userclip || BRW_IS_965(p->brw))
{
struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
GLuint i;
@@ -1114,7 +1137,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
* Later, clipping will detect ucp[6] and ensure the primitive is
* clipped against all fixed planes.
*/
- if (!BRW_IS_G4X(p->brw)) {
+ if (BRW_IS_965(p->brw)) {
brw_CMP(p,
vec8(brw_null_reg()),
BRW_CONDITIONAL_L,
@@ -1141,7 +1164,23 @@ static void emit_vertex_write( struct brw_vs_compile *c)
*/
brw_set_access_mode(p, BRW_ALIGN_1);
brw_MOV(p, offset(m0, 2), ndc);
- brw_MOV(p, offset(m0, 3), pos);
+
+ if (BRW_IS_IGDNG(p->brw)) {
+ /* There are 20 DWs (D0-D19) in VUE vertex header on IGDNG */
+ brw_MOV(p, offset(m0, 3), pos); /* a portion of vertex header */
+ /* m4, m5 contain the distances from vertex to the user clip planeXXX.
+ * Seems it is useless for us.
+ * m6 is used for aligning, so that the remainder of vertex element is
+ * reg-aligned.
+ */
+ brw_MOV(p, offset(m0, 7), pos); /* the remainder of vertex element */
+ len_vertext_header = 6;
+ } else {
+ brw_MOV(p, offset(m0, 3), pos);
+ len_vertext_header = 2;
+ }
+
+ eot = (c->first_overflow_output == 0);
brw_urb_WRITE(p,
brw_null_reg(), /* dest */
@@ -1149,12 +1188,43 @@ static void emit_vertex_write( struct brw_vs_compile *c)
c->r0, /* src */
0, /* allocate */
1, /* used */
- c->nr_outputs + 3, /* msg len */
+ MIN2(c->nr_outputs + 1 + len_vertext_header, (BRW_MAX_MRF-1)), /* msg len */
0, /* response len */
- 1, /* eot */
+ eot, /* eot */
1, /* writes complete */
0, /* urb destination offset */
BRW_URB_SWIZZLE_INTERLEAVE);
+
+ if (c->first_overflow_output > 0) {
+ /* Not all of the vertex outputs/results fit into the MRF.
+ * Move the overflowed attributes from the GRF to the MRF and
+ * issue another brw_urb_WRITE().
+ */
+ /* XXX I'm not 100% sure about which MRF regs to use here. Starting
+ * at mrf[4] atm...
+ */
+ GLuint i, mrf = 0;
+ for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) {
+ if (c->prog_data.outputs_written & (1 << i)) {
+ /* move from GRF to MRF */
+ brw_MOV(p, brw_message_reg(4+mrf), c->regs[PROGRAM_OUTPUT][i]);
+ mrf++;
+ }
+ }
+
+ brw_urb_WRITE(p,
+ brw_null_reg(), /* dest */
+ 4, /* starting mrf reg nr */
+ c->r0, /* src */
+ 0, /* allocate */
+ 1, /* used */
+ mrf+1, /* msg len */
+ 0, /* response len */
+ 1, /* eot */
+ 1, /* writes complete */
+ BRW_MAX_MRF-1, /* urb destination offset */
+ BRW_URB_SWIZZLE_INTERLEAVE);
+ }
}
@@ -1183,15 +1253,15 @@ post_vs_emit( struct brw_vs_compile *c,
*/
void brw_vs_emit(struct brw_vs_compile *c )
{
-#define MAX_IFSN 32
+#define MAX_IF_DEPTH 32
+#define MAX_LOOP_DEPTH 32
struct brw_compile *p = &c->func;
- GLuint nr_insns = c->vp->program.Base.NumInstructions;
- GLuint insn, if_insn = 0;
+ const GLuint nr_insns = c->vp->program.Base.NumInstructions;
+ GLuint insn, if_depth = 0, loop_depth = 0;
GLuint end_offset = 0;
struct brw_instruction *end_inst, *last_inst;
- struct brw_instruction *if_inst[MAX_IFSN];
- struct brw_indirect stack_index = brw_indirect(0, 0);
-
+ struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
+ const struct brw_indirect stack_index = brw_indirect(0, 0);
GLuint index;
GLuint file;
@@ -1382,16 +1452,51 @@ void brw_vs_emit(struct brw_vs_compile *c )
emit_xpd(p, dst, args[0], args[1]);
break;
case OPCODE_IF:
- assert(if_insn < MAX_IFSN);
- if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ assert(if_depth < MAX_IF_DEPTH);
+ if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
break;
case OPCODE_ELSE:
- if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
break;
case OPCODE_ENDIF:
- assert(if_insn > 0);
- brw_ENDIF(p, if_inst[--if_insn]);
+ assert(if_depth > 0);
+ brw_ENDIF(p, if_inst[--if_depth]);
break;
+#if 0
+ case OPCODE_BGNLOOP:
+ loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_BRK:
+ brw_BREAK(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_CONT:
+ brw_CONT(p);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case OPCODE_ENDLOOP:
+ {
+ struct brw_instruction *inst0, *inst1;
+ loop_depth--;
+ inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
+ /* patch all the BREAK/CONT instructions from last BEGINLOOP */
+ while (inst0 > loop_inst[loop_depth]) {
+ inst0--;
+ if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+ inst0->bits3.if_else.pop_count = 0;
+ }
+ else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ inst0->bits3.if_else.jump_count = inst1 - inst0;
+ inst0->bits3.if_else.pop_count = 0;
+ }
+ }
+ }
+ break;
+#else
+ (void) loop_inst;
+ (void) loop_depth;
+#endif
case OPCODE_BRA:
brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index 3d29538843..d790ab6555 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -97,7 +97,11 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
* brw_urb_WRITE() results.
*/
vs.thread1.single_program_flow = 0;
- vs.thread1.binding_table_entry_count = key->nr_surfaces;
+
+ if (BRW_IS_IGDNG(brw))
+ vs.thread1.binding_table_entry_count = 0; /* hardware requirement */
+ else
+ vs.thread1.binding_table_entry_count = key->nr_surfaces;
vs.thread3.urb_entry_read_length = key->urb_entry_read_length;
vs.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
@@ -105,10 +109,16 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
vs.thread3.urb_entry_read_offset = 0;
vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
- vs.thread4.nr_urb_entries = key->nr_urb_entries;
+ if (BRW_IS_IGDNG(brw))
+ vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2;
+ else
+ vs.thread4.nr_urb_entries = key->nr_urb_entries;
+
vs.thread4.urb_entry_allocation_size = key->urb_size - 1;
- if (BRW_IS_G4X(brw))
+ if (BRW_IS_IGDNG(brw))
+ chipset_max_threads = 72;
+ else if (BRW_IS_G4X(brw))
chipset_max_threads = 32;
else
chipset_max_threads = 16;
@@ -120,6 +130,8 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
/* No samplers for ARB_vp programs:
*/
+ /* It has to be set to 0 for IGDNG
+ */
vs.vs5.sampler_count = 0;
if (INTEL_DEBUG & DEBUG_STATS)
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index ba03afd6c1..ac11790151 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -177,14 +177,6 @@ static void brw_note_fence( struct intel_context *intel, GLuint fence )
brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE;
}
-
-static void brw_note_unlock( struct intel_context *intel )
-{
- struct brw_context *brw = brw_context(&intel->ctx);
- brw_state_cache_check_size(brw);
-}
-
-
/* called from intelWaitForIdle() and intelFlush()
*
* For now, just flush everything. Could be smarter later.
@@ -194,7 +186,7 @@ static GLuint brw_flush_cmd( void )
struct brw_mi_flush flush;
flush.opcode = CMD_MI_FLUSH;
flush.pad = 0;
- flush.flags = BRW_FLUSH_READ_CACHE | BRW_FLUSH_STATE_CACHE;
+ flush.flags = BRW_FLUSH_STATE_CACHE;
return *(GLuint *)&flush;
}
@@ -215,7 +207,6 @@ void brwInitVtbl( struct brw_context *brw )
brw->intel.vtbl.invalidate_state = brw_invalidate_state;
brw->intel.vtbl.note_fence = brw_note_fence;
- brw->intel.vtbl.note_unlock = brw_note_unlock;
brw->intel.vtbl.new_batch = brw_new_batch;
brw->intel.vtbl.finish_batch = brw_finish_batch;
brw->intel.vtbl.destroy = brw_destroy_context;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 3e476fd3be..14e05be4f6 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -267,11 +267,14 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* BRW_NEW_WM_INPUT_DIMENSIONS */
- key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS);
+ key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
/* _NEW_LIGHT */
key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
+ /* _NEW_HINT */
+ key->linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
+
/* _NEW_TEXTURE */
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
@@ -351,6 +354,7 @@ const struct brw_tracked_state brw_wm_prog = {
.dirty = {
.mesa = (_NEW_COLOR |
_NEW_DEPTH |
+ _NEW_HINT |
_NEW_STENCIL |
_NEW_POLYGON |
_NEW_LINE |
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index fb15c03e83..ba497432c6 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -63,9 +63,10 @@ struct brw_wm_prog_key {
GLuint computes_depth:1; /* could be derived from program string */
GLuint source_depth_to_render_target:1;
GLuint flat_shade:1;
+ GLuint linear_color:1; /**< linear interpolation vs perspective interp */
GLuint runtime_check_aads_emit:1;
- GLuint projtex_mask:16;
+ GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */
GLuint shadowtex_mask:16;
GLuint yuvtex_mask:16;
GLuint yuvtex_swap_mask:16; /* UV swaped */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 14ab9042de..9f82916c02 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -714,6 +714,7 @@ static void emit_tex( struct brw_wm_compile *c,
GLuint msgLength, responseLength;
GLuint i, nr;
GLuint emit;
+ GLuint msg_type;
/* How many input regs are there?
*/
@@ -751,6 +752,18 @@ static void emit_tex( struct brw_wm_compile *c,
responseLength = 8; /* always */
+ if (BRW_IS_IGDNG(p->brw)) {
+ if (inst->tex_shadow)
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG;
+ else
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG;
+ } else {
+ if (inst->tex_shadow)
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+ else
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+ }
+
brw_SAMPLE(p,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
@@ -758,12 +771,12 @@ static void emit_tex( struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
inst->writemask,
- (inst->tex_shadow ?
- BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE :
- BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE),
+ msg_type,
responseLength,
msgLength,
- 0);
+ 0,
+ 1,
+ BRW_SAMPLER_SIMD_MODE_SIMD16);
}
@@ -775,7 +788,7 @@ static void emit_txb( struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
GLuint msgLength;
-
+ GLuint msg_type;
/* Shadow ignored for txb.
*/
switch (inst->tex_idx) {
@@ -800,6 +813,11 @@ static void emit_txb( struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(8), arg[3]);
msgLength = 9;
+ if (BRW_IS_IGDNG(p->brw))
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG;
+ else
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+
brw_SAMPLE(p,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
@@ -807,10 +825,12 @@ static void emit_txb( struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
inst->writemask,
- BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
+ msg_type,
8, /* responseLength */
msgLength,
- 0);
+ 0,
+ 1,
+ BRW_SAMPLER_SIMD_MODE_SIMD16);
}
@@ -1022,7 +1042,7 @@ static void emit_fb_write( struct brw_wm_compile *c,
get_element_ud(brw_vec8_grf(1,0), 6),
brw_imm_ud(1<<26));
- jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
+ jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
{
emit_aa(c, arg1, 2);
fire_fb_write(c, 0, nr, target, eot);
@@ -1057,7 +1077,6 @@ static void emit_spill( struct brw_wm_compile *c,
*/
brw_dp_WRITE_16(p,
retype(vec16(brw_vec8_grf(0, 0)), BRW_REGISTER_TYPE_UW),
- 1,
slot);
}
@@ -1085,7 +1104,6 @@ static void emit_unspill( struct brw_wm_compile *c,
brw_dp_READ_16(p,
retype(vec16(reg), BRW_REGISTER_TYPE_UW),
- 1,
slot);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 1798d842c7..b9e8dd2e96 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -354,13 +354,25 @@ static void emit_interp( struct brw_wm_compile *c,
src_undef());
}
else {
- emit_op(c,
- WM_LINTERP,
- dst,
- 0,
- interp,
- deltas,
- src_undef());
+ if (c->key.linear_color) {
+ emit_op(c,
+ WM_LINTERP,
+ dst,
+ 0,
+ interp,
+ deltas,
+ src_undef());
+ }
+ else {
+ /* perspective-corrected color interpolation */
+ emit_op(c,
+ WM_PINTERP,
+ dst,
+ 0,
+ interp,
+ deltas,
+ get_pixel_w(c));
+ }
}
break;
case FRAG_ATTRIB_FOGC:
@@ -834,10 +846,16 @@ static void precalc_tex( struct brw_wm_compile *c,
}
+/**
+ * Check if the given TXP instruction really needs the divide-by-W step.
+ */
static GLboolean projtex( struct brw_wm_compile *c,
const struct prog_instruction *inst )
{
- struct prog_src_register src = inst->SrcReg[0];
+ const struct prog_src_register src = inst->SrcReg[0];
+ GLboolean retVal;
+
+ assert(inst->Opcode == OPCODE_TXP);
/* Only try to detect the simplest cases. Could detect (later)
* cases where we are trying to emit code like RCP {1.0}, MUL x,
@@ -847,16 +865,21 @@ static GLboolean projtex( struct brw_wm_compile *c,
* user-provided fragment programs anyway:
*/
if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)
- return 0; /* ut2004 gun rendering !?! */
+ retVal = GL_FALSE; /* ut2004 gun rendering !?! */
else if (src.File == PROGRAM_INPUT &&
GET_SWZ(src.Swizzle, W) == W &&
- (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0)
- return 0;
+ (c->key.proj_attrib_mask & (1 << src.Index)) == 0)
+ retVal = GL_FALSE;
else
- return 1;
+ retVal = GL_TRUE;
+
+ return retVal;
}
+/**
+ * Emit code for TXP.
+ */
static void precalc_txp( struct brw_wm_compile *c,
const struct prog_instruction *inst )
{
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 0e6a2f8ef0..19f777fe32 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -446,7 +446,6 @@ static void fetch_constants(struct brw_wm_compile *c,
/* need to fetch the constant now */
brw_dp_READ_4(p,
c->current_const[i].reg, /* writeback dest */
- 1, /* msg_reg */
src->RelAddr, /* relative indexing? */
16 * src->Index, /* byte offset */
SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */
@@ -2626,6 +2625,7 @@ static void emit_txb(struct brw_wm_compile *c,
struct brw_reg dst[4], src[4], payload_reg;
GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
GLuint i;
+ GLuint msg_type;
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
@@ -2654,6 +2654,14 @@ static void emit_txb(struct brw_wm_compile *c,
}
brw_MOV(p, brw_message_reg(5), src[3]); /* bias */
brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); /* ref (unused?) */
+
+ if (BRW_IS_IGDNG(p->brw)) {
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG;
+ } else {
+ /* Does it work well on SIMD8? */
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+ }
+
brw_SAMPLE(p,
retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
1, /* msg_reg_nr */
@@ -2661,10 +2669,12 @@ static void emit_txb(struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(unit),
unit, /* sampler */
inst->DstReg.WriteMask, /* writemask */
- BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, /* msg_type */
+ msg_type, /* msg_type */
4, /* response_length */
4, /* msg_length */
- 0); /* eot */
+ 0, /* eot */
+ 1,
+ BRW_SAMPLER_SIMD_MODE_SIMD8);
}
@@ -2678,6 +2688,7 @@ static void emit_tex(struct brw_wm_compile *c,
GLuint i, nr;
GLuint emit;
GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
+ GLuint msg_type;
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
@@ -2718,6 +2729,16 @@ static void emit_tex(struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(6), src[2]); /* ref value / R coord */
}
+ if (BRW_IS_IGDNG(p->brw)) {
+ if (shadow)
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG;
+ else
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG;
+ } else {
+ /* Does it work for shadow on SIMD8 ? */
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
+ }
+
brw_SAMPLE(p,
retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
1, /* msg_reg_nr */
@@ -2725,10 +2746,12 @@ static void emit_tex(struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(unit),
unit, /* sampler */
inst->DstReg.WriteMask, /* writemask */
- BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, /* msg_type */
+ msg_type, /* msg_type */
4, /* response_length */
shadow ? 6 : 4, /* msg_length */
- 0); /* eot */
+ 0, /* eot */
+ 1,
+ BRW_SAMPLER_SIMD_MODE_SIMD8);
if (shadow)
brw_MOV(p, dst[3], brw_imm_f(1.0));
@@ -2745,11 +2768,10 @@ static void post_wm_emit( struct brw_wm_compile *c )
static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
{
-#define MAX_IFSN 32
+#define MAX_IF_DEPTH 32
#define MAX_LOOP_DEPTH 32
- struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH];
- struct brw_instruction *inst0, *inst1;
- int i, if_insn = 0, loop_insn = 0;
+ struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
+ GLuint i, if_depth = 0, loop_depth = 0;
struct brw_compile *p = &c->func;
struct brw_indirect stack_index = brw_indirect(0, 0);
@@ -2831,6 +2853,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_trunc(c, inst);
break;
case OPCODE_MOV:
+ case OPCODE_SWZ:
emit_mov(c, inst);
break;
case OPCODE_DP3:
@@ -2922,15 +2945,15 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_kil(c);
break;
case OPCODE_IF:
- assert(if_insn < MAX_IFSN);
- if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ assert(if_depth < MAX_IF_DEPTH);
+ if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
break;
case OPCODE_ELSE:
- if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
+ if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
break;
case OPCODE_ENDIF:
- assert(if_insn > 0);
- brw_ENDIF(p, if_inst[--if_insn]);
+ assert(if_depth > 0);
+ brw_ENDIF(p, if_inst[--if_depth]);
break;
case OPCODE_BGNSUB:
brw_save_label(p, inst->Comment, p->nr_insn);
@@ -2964,7 +2987,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
break;
case OPCODE_BGNLOOP:
/* XXX may need to invalidate the current_constant regs */
- loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
+ loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
break;
case OPCODE_BRK:
brw_BREAK(p);
@@ -2975,21 +2998,29 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_ENDLOOP:
- loop_insn--;
- inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]);
- /* patch all the BREAK instructions from
- last BEGINLOOP */
- while (inst0 > loop_inst[loop_insn]) {
- inst0--;
- if (inst0->header.opcode == BRW_OPCODE_BREAK) {
- inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+ {
+ struct brw_instruction *inst0, *inst1;
+ GLuint br = 1;
+
+ if (BRW_IS_IGDNG(brw))
+ br = 2;
+
+ loop_depth--;
+ inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
+ /* patch all the BREAK/CONT instructions from last BEGINLOOP */
+ while (inst0 > loop_inst[loop_depth]) {
+ inst0--;
+ if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
inst0->bits3.if_else.pop_count = 0;
- } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
- inst0->bits3.if_else.jump_count = inst1 - inst0;
+ }
+ else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
inst0->bits3.if_else.pop_count = 0;
- }
- }
- break;
+ }
+ }
+ }
+ break;
default:
_mesa_printf("unsupported IR in fragment shader %d\n",
inst->Opcode);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 67b41173fb..39f8c6d522 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -71,7 +71,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
key->max_threads = 1;
else {
/* WM maximum threads is number of EUs times number of threads per EU. */
- if (BRW_IS_G4X(brw))
+ if (BRW_IS_IGDNG(brw))
+ key->max_threads = 12 * 6;
+ else if (BRW_IS_G4X(brw))
key->max_threads = 10 * 5;
else
key->max_threads = 8 * 4;
@@ -141,7 +143,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
wm.thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
wm.thread1.depth_coef_urb_read_offset = 1;
wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
- wm.thread1.binding_table_entry_count = key->nr_surfaces;
+
+ if (BRW_IS_IGDNG(brw))
+ wm.thread1.binding_table_entry_count = 0; /* hardware requirement */
+ else
+ wm.thread1.binding_table_entry_count = key->nr_surfaces;
if (key->total_scratch != 0) {
wm.thread2.scratch_space_base_pointer =
@@ -158,7 +164,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
wm.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
wm.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
- wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
+ if (BRW_IS_IGDNG(brw))
+ wm.wm4.sampler_count = 0; /* hardware requirement */
+ else
+ wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
+
if (brw->wm.sampler_bo != NULL) {
/* reloc */
wm.wm4.sampler_state_pointer = brw->wm.sampler_bo->offset >> 5;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index c49a5f6b4e..096f74394e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -578,7 +578,27 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
surf.ss0.surface_format = key.surface_format;
surf.ss0.surface_type = key.surface_type;
- surf.ss1.base_addr = key.draw_offset;
+ if (key.tiling == I915_TILING_NONE) {
+ surf.ss1.base_addr = key.draw_offset;
+ } else {
+ uint32_t tile_offset = key.draw_offset % 4096;
+
+ surf.ss1.base_addr = key.draw_offset - tile_offset;
+
+ assert(BRW_IS_G4X(brw) || tile_offset == 0);
+ if (BRW_IS_G4X(brw)) {
+ if (key.tiling == I915_TILING_X) {
+ /* Note that the low bits of these fields are missing, so
+ * there's the possibility of getting in trouble.
+ */
+ surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
+ surf.ss5.y_offset = tile_offset / 512 / 2;
+ } else {
+ surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
+ surf.ss5.y_offset = tile_offset / 128 / 2;
+ }
+ }
+ }
if (region_bo != NULL)
surf.ss1.base_addr += region_bo->offset; /* reloc */
@@ -609,7 +629,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
offsetof(struct brw_surface_state, ss1),
region_bo,
- key.draw_offset,
+ surf.ss1.base_addr,
I915_GEM_DOMAIN_RENDER,
I915_GEM_DOMAIN_RENDER);
}
diff --git a/src/mesa/drivers/dri/i965/intel_pixel_read.c b/src/mesa/drivers/dri/i965/intel_pixel_read.c
new file mode 120000
index 0000000000..cc4589f4d4
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_pixel_read.c
@@ -0,0 +1 @@
+../intel/intel_pixel_read.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 29dc05c518..0f87fc46a4 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -195,7 +195,6 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
{
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
- GLboolean was_locked = intel->locked;
if (used == 0) {
batch->cliprect_mode = IGNORE_CLIPRECTS;
@@ -243,13 +242,9 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
- if (!was_locked)
- LOCK_HARDWARE(intel);
-
+ LOCK_HARDWARE(intel);
do_flush_locked(batch, used, GL_FALSE);
-
- if (!was_locked)
- UNLOCK_HARDWARE(intel);
+ UNLOCK_HARDWARE(intel);
if (INTEL_DEBUG & DEBUG_SYNC) {
fprintf(stderr, "waiting for idle\n");
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 4919828131..2e95bd1013 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -108,6 +108,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
+ assert(src->tiling != I915_TILING_Y);
+ assert(dst->tiling != I915_TILING_Y);
#ifndef I915
if (src->tiling != I915_TILING_NONE) {
CMD |= XY_SRC_TILED;
@@ -175,66 +177,6 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
UNLOCK_HARDWARE(intel);
}
-
-
-
-void
-intelEmitFillBlit(struct intel_context *intel,
- GLuint cpp,
- GLshort dst_pitch,
- dri_bo *dst_buffer,
- GLuint dst_offset,
- uint32_t dst_tiling,
- GLshort x, GLshort y,
- GLshort w, GLshort h,
- GLuint color)
-{
- GLuint BR13, CMD;
- BATCH_LOCALS;
-
- dst_pitch *= cpp;
-
- switch (cpp) {
- case 1:
- BR13 = (0xF0 << 16);
- CMD = XY_COLOR_BLT_CMD;
- break;
- case 2:
- BR13 = (0xF0 << 16) | BR13_565;
- CMD = XY_COLOR_BLT_CMD;
- break;
- case 4:
- BR13 = (0xF0 << 16) | BR13_8888;
- CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
- break;
- default:
- return;
- }
-#ifndef I915
- if (dst_tiling != I915_TILING_NONE) {
- CMD |= XY_DST_TILED;
- dst_pitch /= 4;
- }
-#endif
-
- DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
- __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h);
-
- assert(w > 0);
- assert(h > 0);
-
- BEGIN_BATCH(6, NO_LOOP_CLIPRECTS);
- OUT_BATCH(CMD);
- OUT_BATCH(BR13 | dst_pitch);
- OUT_BATCH((y << 16) | x);
- OUT_BATCH(((y + h) << 16) | (x + w));
- OUT_RELOC(dst_buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- dst_offset);
- OUT_BATCH(color);
- ADVANCE_BATCH();
-}
-
static GLuint translate_raster_op(GLenum logicop)
{
switch(logicop) {
@@ -261,7 +203,7 @@ static GLuint translate_raster_op(GLenum logicop)
/* Copy BitBlt
*/
-void
+GLboolean
intelEmitCopyBlit(struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
@@ -283,6 +225,19 @@ intelEmitCopyBlit(struct intel_context *intel,
dri_bo *aper_array[3];
BATCH_LOCALS;
+ if (dst_tiling != I915_TILING_NONE) {
+ if (dst_offset & 4095)
+ return GL_FALSE;
+ if (dst_tiling == I915_TILING_Y)
+ return GL_FALSE;
+ }
+ if (src_tiling != I915_TILING_NONE) {
+ if (src_offset & 4095)
+ return GL_FALSE;
+ if (src_tiling == I915_TILING_Y)
+ return GL_FALSE;
+ }
+
/* do space/cliprects check before going any further */
do {
aper_array[0] = intel->batch->buf;
@@ -297,12 +252,7 @@ intelEmitCopyBlit(struct intel_context *intel,
} while (pass < 2);
if (pass >= 2) {
- GLboolean locked = GL_FALSE;
- if (!intel->locked) {
- LOCK_HARDWARE(intel);
- locked = GL_TRUE;
- }
-
+ LOCK_HARDWARE(intel);
dri_bo_map(dst_buffer, GL_TRUE);
dri_bo_map(src_buffer, GL_FALSE);
_mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset,
@@ -316,11 +266,9 @@ intelEmitCopyBlit(struct intel_context *intel,
dri_bo_unmap(src_buffer);
dri_bo_unmap(dst_buffer);
-
- if (locked)
- UNLOCK_HARDWARE(intel);
+ UNLOCK_HARDWARE(intel);
- return;
+ return GL_TRUE;
}
intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS);
@@ -347,7 +295,7 @@ intelEmitCopyBlit(struct intel_context *intel,
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
- return;
+ return GL_FALSE;
}
#ifndef I915
@@ -362,7 +310,7 @@ intelEmitCopyBlit(struct intel_context *intel,
#endif
if (dst_y2 <= dst_y || dst_x2 <= dst_x) {
- return;
+ return GL_TRUE;
}
assert(dst_x < dst_x2);
@@ -384,6 +332,8 @@ intelEmitCopyBlit(struct intel_context *intel,
ADVANCE_BATCH();
intel_batchbuffer_emit_mi_flush(intel->batch);
+
+ return GL_TRUE;
}
@@ -596,7 +546,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
UNLOCK_HARDWARE(intel);
}
-void
+GLboolean
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
@@ -612,11 +562,18 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
int dwords = ALIGN(src_size, 8) / 4;
uint32_t opcode, br13, blit_cmd;
+ if (dst_tiling != I915_TILING_NONE) {
+ if (dst_offset & 4095)
+ return GL_FALSE;
+ if (dst_tiling == I915_TILING_Y)
+ return GL_FALSE;
+ }
+
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
if (w < 0 || h < 0)
- return;
+ return GL_TRUE;
dst_pitch *= cpp;
@@ -673,4 +630,6 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
REFERENCES_CLIPRECTS );
intel_batchbuffer_emit_mi_flush(intel->batch);
+
+ return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h
index 52065b13ed..152fa3f17b 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.h
+++ b/src/mesa/drivers/dri/intel/intel_blit.h
@@ -35,7 +35,8 @@ extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv,
extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask);
-extern void intelEmitCopyBlit(struct intel_context *intel,
+GLboolean
+intelEmitCopyBlit(struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
dri_bo *src_buffer,
@@ -50,16 +51,7 @@ extern void intelEmitCopyBlit(struct intel_context *intel,
GLshort w, GLshort h,
GLenum logicop );
-extern void intelEmitFillBlit(struct intel_context *intel,
- GLuint cpp,
- GLshort dst_pitch,
- dri_bo *dst_buffer,
- GLuint dst_offset,
- uint32_t dst_tiling,
- GLshort x, GLshort y,
- GLshort w, GLshort h, GLuint color);
-
-void
+GLboolean
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 23ba3b9ef6..9600557f2c 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -243,6 +243,9 @@ intel_bufferobj_map(GLcontext * ctx,
return obj->Pointer;
}
+ if (!read_only)
+ intelFlush(ctx);
+
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
@@ -274,7 +277,10 @@ intel_bufferobj_unmap(GLcontext * ctx,
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
assert(intel_obj);
- if (intel_obj->buffer != NULL) {
+ if (intel_obj->sys_buffer != NULL) {
+ assert(obj->Pointer);
+ obj->Pointer = NULL;
+ } else if (intel_obj->buffer != NULL) {
assert(obj->Pointer);
if (intel_obj->mapped_gtt) {
drm_intel_gem_bo_unmap_gtt(intel_obj->buffer);
@@ -300,14 +306,19 @@ intel_bufferobj_buffer(struct intel_context *intel,
}
if (intel_obj->buffer == NULL) {
+ void *sys_buffer = intel_obj->sys_buffer;
+
+ /* only one of buffer and sys_buffer could be non-NULL */
intel_bufferobj_alloc_buffer(intel, intel_obj);
+ intel_obj->sys_buffer = NULL;
+
intel_bufferobj_subdata(&intel->ctx,
GL_ARRAY_BUFFER_ARB,
0,
intel_obj->Base.Size,
- intel_obj->sys_buffer,
+ sys_buffer,
&intel_obj->Base);
- _mesa_free(intel_obj->sys_buffer);
+ _mesa_free(sys_buffer);
intel_obj->sys_buffer = NULL;
}
@@ -315,15 +326,13 @@ intel_bufferobj_buffer(struct intel_context *intel,
}
void
-intel_bufferobj_init(struct intel_context *intel)
+intelInitBufferObjectFuncs(struct dd_function_table *functions)
{
- GLcontext *ctx = &intel->ctx;
-
- ctx->Driver.NewBufferObject = intel_bufferobj_alloc;
- ctx->Driver.DeleteBuffer = intel_bufferobj_free;
- ctx->Driver.BufferData = intel_bufferobj_data;
- ctx->Driver.BufferSubData = intel_bufferobj_subdata;
- ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata;
- ctx->Driver.MapBuffer = intel_bufferobj_map;
- ctx->Driver.UnmapBuffer = intel_bufferobj_unmap;
+ functions->NewBufferObject = intel_bufferobj_alloc;
+ functions->DeleteBuffer = intel_bufferobj_free;
+ functions->BufferData = intel_bufferobj_data;
+ functions->BufferSubData = intel_bufferobj_subdata;
+ functions->GetBufferSubData = intel_bufferobj_get_subdata;
+ functions->MapBuffer = intel_bufferobj_map;
+ functions->UnmapBuffer = intel_bufferobj_unmap;
}
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
index 0431015631..8164407f07 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
@@ -60,7 +60,7 @@ dri_bo *intel_bufferobj_buffer(struct intel_context *intel,
/* Hook the bufferobject implementation into mesa:
*/
-void intel_bufferobj_init(struct intel_context *intel);
+void intelInitBufferObjectFuncs(struct dd_function_table *functions);
@@ -72,10 +72,7 @@ void intel_bufferobj_init(struct intel_context *intel);
static INLINE struct intel_buffer_object *
intel_buffer_object(struct gl_buffer_object *obj)
{
- if (obj->Name)
- return (struct intel_buffer_object *) obj;
- else
- return NULL;
+ return (struct intel_buffer_object *) obj;
}
/* Helpers for zerocopy image uploads. See also intel_regions.h:
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index df5c3fc176..e7357e78c5 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -345,6 +345,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
static void
intelReadBuffer(GLcontext * ctx, GLenum mode)
{
+ if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
+ struct intel_context *const intel = intel_context(ctx);
+ const GLboolean was_front_buffer_reading =
+ intel->is_front_buffer_reading;
+
+ intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
+ || (mode == GL_FRONT);
+
+ /* If we weren't front-buffer reading before but we are now, make sure
+ * that the front-buffer has actually been allocated.
+ */
+ if (!was_front_buffer_reading && intel->is_front_buffer_reading) {
+ intel_update_renderbuffers(intel->driContext,
+ intel->driContext->driDrawablePriv);
+ }
+ }
+
if (ctx->ReadBuffer == ctx->DrawBuffer) {
/* This will update FBO completeness status.
* A framebuffer will be incomplete if the GL_READ_BUFFER setting
diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h
index 4593d90df3..3c38f1676c 100644
--- a/src/mesa/drivers/dri/intel/intel_chipset.h
+++ b/src/mesa/drivers/dri/intel/intel_chipset.h
@@ -67,13 +67,18 @@
#define PCI_CHIP_G45_G 0x2E22
#define PCI_CHIP_G41_G 0x2E32
+#define PCI_CHIP_ILD_G 0x0042
+#define PCI_CHIP_ILM_G 0x0046
+
#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \
devid == PCI_CHIP_I915_GM || \
devid == PCI_CHIP_I945_GM || \
devid == PCI_CHIP_I945_GME || \
devid == PCI_CHIP_I965_GM || \
devid == PCI_CHIP_I965_GME || \
- devid == PCI_CHIP_GM45_GM || IS_IGD(devid))
+ devid == PCI_CHIP_GM45_GM || \
+ IS_IGD(devid) || \
+ devid == PCI_CHIP_ILM_G)
#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \
devid == PCI_CHIP_Q45_G || \
@@ -82,6 +87,10 @@
#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM)
#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid))
+#define IS_ILD(devid) (devid == PCI_CHIP_ILD_G)
+#define IS_ILM(devid) (devid == PCI_CHIP_ILM_G)
+#define IS_IGDNG(devid) (IS_ILD(devid) || IS_ILM(devid))
+
#define IS_915(devid) (devid == PCI_CHIP_I915_G || \
devid == PCI_CHIP_E7221_G || \
devid == PCI_CHIP_I915_GM)
@@ -99,7 +108,8 @@
devid == PCI_CHIP_I965_GM || \
devid == PCI_CHIP_I965_GME || \
devid == PCI_CHIP_I946_GZ || \
- IS_G4X(devid))
+ IS_G4X(devid) || \
+ IS_IGDNG(devid))
#define IS_9XX(devid) (IS_915(devid) || \
IS_945(devid) || \
diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c
index 309ac1923b..cfddabd318 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -57,237 +57,6 @@
#define FILE_DEBUG_FLAG DEBUG_BLIT
-#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
- BUFFER_BIT_FRONT_LEFT | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
-
-
-/**
- * Per-context one-time init of things for intl_clear_tris().
- * Basically set up a private array object for vertex/color arrays.
- */
-static void
-init_clear(GLcontext *ctx)
-{
- struct intel_context *intel = intel_context(ctx);
- struct gl_array_object *arraySave = NULL;
- const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name;
- const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name;
-
- /* create new array object */
- intel->clear.arrayObj = _mesa_new_array_object(ctx, ~0);
-
- /* save current array object, bind new one */
- _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj);
-
- /* one-time setup of vertex arrays (pos, color) */
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), intel->clear.color);
- _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), intel->clear.vertices);
- _mesa_Enable(GL_COLOR_ARRAY);
- _mesa_Enable(GL_VERTEX_ARRAY);
-
- /* restore original array object */
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
- _mesa_reference_array_object(ctx, &arraySave, NULL);
-
- /* restore original buffer objects */
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer);
-}
-
-
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering. The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-void
-intel_clear_tris(GLcontext *ctx, GLbitfield mask)
-{
- struct intel_context *intel = intel_context(ctx);
- GLfloat dst_z;
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- int i;
- GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
- GLuint saved_shader_program = 0;
- unsigned int saved_active_texture;
- struct gl_array_object *arraySave = NULL;
-
- if (!intel->clear.arrayObj)
- init_clear(ctx);
-
- assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
- BUFFER_BIT_STENCIL)) == 0);
-
- _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
- GL_CURRENT_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_POLYGON_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT |
- GL_CURRENT_BIT);
- saved_active_texture = ctx->Texture.CurrentUnit;
-
- /* Disable existing GL state we don't want to apply to a clear. */
- _mesa_Disable(GL_ALPHA_TEST);
- _mesa_Disable(GL_BLEND);
- _mesa_Disable(GL_CULL_FACE);
- _mesa_Disable(GL_FOG);
- _mesa_Disable(GL_POLYGON_SMOOTH);
- _mesa_Disable(GL_POLYGON_STIPPLE);
- _mesa_Disable(GL_POLYGON_OFFSET_FILL);
- _mesa_Disable(GL_LIGHTING);
- _mesa_Disable(GL_CLIP_PLANE0);
- _mesa_Disable(GL_CLIP_PLANE1);
- _mesa_Disable(GL_CLIP_PLANE2);
- _mesa_Disable(GL_CLIP_PLANE3);
- _mesa_Disable(GL_CLIP_PLANE4);
- _mesa_Disable(GL_CLIP_PLANE5);
- _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
- saved_fp_enable = GL_TRUE;
- _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
- saved_vp_enable = GL_TRUE;
- _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
- saved_shader_program = ctx->Shader.CurrentProgram->Name;
- _mesa_UseProgramObjectARB(0);
- }
-
- if (ctx->Texture._EnabledUnits != 0) {
- int i;
-
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
- _mesa_Disable(GL_TEXTURE_1D);
- _mesa_Disable(GL_TEXTURE_2D);
- _mesa_Disable(GL_TEXTURE_3D);
- if (ctx->Extensions.ARB_texture_cube_map)
- _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
- if (ctx->Extensions.NV_texture_rectangle)
- _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
- if (ctx->Extensions.MESA_texture_array) {
- _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
- _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
- }
- }
- }
-
- /* save current array object, bind our private one */
- _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj);
-
- intel_meta_set_passthrough_transform(intel);
-
- for (i = 0; i < 4; i++) {
- COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor);
- }
-
- /* convert clear Z from [0,1] to NDC coord in [-1,1] */
- dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
-
- /* Prepare the vertices, which are the same regardless of which buffer we're
- * drawing to.
- */
- intel->clear.vertices[0][0] = fb->_Xmin;
- intel->clear.vertices[0][1] = fb->_Ymin;
- intel->clear.vertices[0][2] = dst_z;
- intel->clear.vertices[1][0] = fb->_Xmax;
- intel->clear.vertices[1][1] = fb->_Ymin;
- intel->clear.vertices[1][2] = dst_z;
- intel->clear.vertices[2][0] = fb->_Xmax;
- intel->clear.vertices[2][1] = fb->_Ymax;
- intel->clear.vertices[2][2] = dst_z;
- intel->clear.vertices[3][0] = fb->_Xmin;
- intel->clear.vertices[3][1] = fb->_Ymax;
- intel->clear.vertices[3][2] = dst_z;
-
- while (mask != 0) {
- GLuint this_mask = 0;
- GLuint color_bit;
-
- color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
- if (color_bit != 0)
- this_mask |= (1 << (color_bit - 1));
-
- /* Clear depth/stencil in the same pass as color. */
- this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
- /* Select the current color buffer and use the color write mask if
- * we have one, otherwise don't write any color channels.
- */
- if (this_mask & BUFFER_BIT_FRONT_LEFT)
- _mesa_DrawBuffer(GL_FRONT_LEFT);
- else if (this_mask & BUFFER_BIT_BACK_LEFT)
- _mesa_DrawBuffer(GL_BACK_LEFT);
- else if (color_bit != 0)
- _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
- (color_bit - BUFFER_COLOR0 - 1));
- else
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- /* Control writing of the depth clear value to depth. */
- if (this_mask & BUFFER_BIT_DEPTH) {
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_Enable(GL_DEPTH_TEST);
- } else {
- _mesa_Disable(GL_DEPTH_TEST);
- _mesa_DepthMask(GL_FALSE);
- }
-
- /* Control writing of the stencil clear value to stencil. */
- if (this_mask & BUFFER_BIT_STENCIL) {
- _mesa_Enable(GL_STENCIL_TEST);
- _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
- GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
- ctx->Stencil.Clear,
- ctx->Stencil.WriteMask[0]);
- } else {
- _mesa_Disable(GL_STENCIL_TEST);
- }
-
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
-
- mask &= ~this_mask;
- }
-
- intel_meta_restore_transform(intel);
-
- _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
- if (saved_fp_enable)
- _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
- if (saved_vp_enable)
- _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
- if (saved_shader_program)
- _mesa_UseProgramObjectARB(saved_shader_program);
-
- _mesa_PopAttrib();
-
- /* restore current array object */
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
- _mesa_reference_array_object(ctx, &arraySave, NULL);
-}
-
static const char *buffer_names[] = {
[BUFFER_FRONT_LEFT] = "front",
[BUFFER_BACK_LEFT] = "back",
@@ -313,6 +82,7 @@ static const char *buffer_names[] = {
static void
intelClear(GLcontext *ctx, GLbitfield mask)
{
+ struct intel_context *intel = intel_context(ctx);
const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
@@ -412,7 +182,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
}
DBG("\n");
}
- intel_clear_tris(ctx, tri_mask);
+ meta_clear_tris(&intel->meta, tri_mask);
}
if (swrast_mask) {
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index f88b37d0f3..4abb525f78 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -67,10 +67,12 @@ int INTEL_DEBUG = (0);
#endif
-#define DRIVER_DATE "20090114"
+#define DRIVER_DATE "20090712 2009Q2 RC3"
#define DRIVER_DATE_GEM "GEM " DRIVER_DATE
+static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush);
+
static const GLubyte *
intelGetString(GLcontext * ctx, GLenum name)
{
@@ -159,6 +161,12 @@ intelGetString(GLcontext * ctx, GLenum name)
case PCI_CHIP_G41_G:
chipset = "Intel(R) G41";
break;
+ case PCI_CHIP_ILD_G:
+ chipset = "Intel(R) IGDNG_D";
+ break;
+ case PCI_CHIP_ILM_G:
+ chipset = "Intel(R) IGDNG_M";
+ break;
default:
chipset = "Unknown Intel Chipset";
break;
@@ -218,7 +226,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
struct intel_renderbuffer *stencil_rb;
i = 0;
- if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1])
+ if ((intel->is_front_buffer_rendering ||
+ intel->is_front_buffer_reading ||
+ !intel_fb->color_rb[1])
&& intel_fb->color_rb[0]) {
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
@@ -394,7 +404,16 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
if (!driContext->driScreenPriv->dri2.enabled)
return;
- if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) {
+ if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
+ /* If we're rendering to the fake front buffer, make sure all the pending
+ * drawing has landed on the real front buffer. Otherwise when we
+ * eventually get to DRI2GetBuffersWithFormat the stale real front
+ * buffer contents will get copied to the new fake front buffer.
+ */
+ if (intel->is_front_buffer_rendering) {
+ intel_flush(ctx, GL_FALSE);
+ }
+
intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
if (driContext->driDrawablePriv != driContext->driReadablePriv)
intel_update_renderbuffers(driContext, driContext->driReadablePriv);
@@ -526,7 +545,7 @@ intelFinish(GLcontext * ctx)
irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
- if (irb->region)
+ if (irb && irb->region)
dri_bo_wait_rendering(irb->region->buffer);
}
if (fb->_DepthBuffer) {
@@ -557,6 +576,7 @@ intelInitDriverFunctions(struct dd_function_table *functions)
intelInitClearFuncs(functions);
intelInitBufferFuncs(functions);
intelInitPixelFuncs(functions);
+ intelInitBufferObjectFuncs(functions);
}
@@ -652,6 +672,7 @@ intelInitContext(struct intel_context *intel,
*/
_mesa_init_point(ctx);
+ meta_init_metaops(ctx, &intel->meta);
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
if (IS_965(intelScreen->deviceID)) {
if (MAX_WIDTH > 8192)
@@ -717,7 +738,6 @@ intelInitContext(struct intel_context *intel,
intel->batch = intel_batchbuffer_alloc(intel);
- intel_bufferobj_init(intel);
intel_fbo_init(intel);
if (intel->ctx.Mesa_DXTn) {
@@ -729,6 +749,12 @@ intelInitContext(struct intel_context *intel,
}
intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
"texture_tiling");
+ if (intel->use_texture_tiling &&
+ !intel->intelScreen->kernel_exec_fencing) {
+ fprintf(stderr, "No kernel support for execution fencing, "
+ "disabling texture tiling");
+ intel->use_texture_tiling = GL_FALSE;
+ }
intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
intel->prim.primitive = ~0;
@@ -769,8 +795,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
INTEL_FIREVERTICES(intel);
- if (intel->clear.arrayObj)
- _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj);
+ meta_destroy_metaops(&intel->meta);
intel->vtbl.destroy(intel);
@@ -858,7 +883,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
/* free the Mesa context */
_mesa_free_context_data(&intel->ctx);
-
+ FREE(intel);
+ driContextPriv->driverPrivate = NULL;
}
}
@@ -975,7 +1001,6 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
int me = intel->hHWContext;
drmGetLock(intel->driFd, intel->hHWContext, flags);
- intel->locked = 1;
if (INTEL_DEBUG & DEBUG_LOCK)
_mesa_printf("%s - got contended lock\n", __progname);
@@ -1032,9 +1057,12 @@ void LOCK_HARDWARE( struct intel_context *intel )
struct intel_framebuffer *intel_fb = NULL;
struct intel_renderbuffer *intel_rb = NULL;
- _glthread_LOCK_MUTEX(lockMutex);
- assert(!intel->locked);
- intel->locked = 1;
+ intel->locked++;
+ if (intel->locked >= 2)
+ return;
+
+ if (!sPriv->dri2.enabled)
+ _glthread_LOCK_MUTEX(lockMutex);
if (intel->driDrawable) {
intel_fb = intel->driDrawable->driverPrivate;
@@ -1081,13 +1109,16 @@ void UNLOCK_HARDWARE( struct intel_context *intel )
{
__DRIscreen *sPriv = intel->driScreen;
- intel->vtbl.note_unlock( intel );
- intel->locked = 0;
+ intel->locked--;
+ if (intel->locked > 0)
+ return;
- if (!sPriv->dri2.enabled)
- DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
+ assert(intel->locked == 0);
- _glthread_UNLOCK_MUTEX(lockMutex);
+ if (!sPriv->dri2.enabled) {
+ DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
+ _glthread_UNLOCK_MUTEX(lockMutex);
+ }
if (INTEL_DEBUG & DEBUG_LOCK)
_mesa_printf("%s - unlocked\n", __progname);
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 7d3c80bb21..08bea88c95 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -33,6 +33,7 @@
#include "main/mtypes.h"
#include "main/mm.h"
#include "texmem.h"
+#include "dri_metaops.h"
#include "drm.h"
#include "intel_bufmgr.h"
@@ -91,7 +92,6 @@ struct intel_context
void (*new_batch) (struct intel_context * intel);
void (*emit_invarient_state) (struct intel_context * intel);
void (*note_fence) (struct intel_context *intel, GLuint fence);
- void (*note_unlock) (struct intel_context *intel);
void (*update_texture_state) (struct intel_context * intel);
void (*render_start) (struct intel_context * intel);
@@ -158,29 +158,7 @@ struct intel_context
void (*debug_batch)(struct intel_context *intel);
} vtbl;
- struct {
- struct gl_fragment_program *bitmap_fp;
- struct gl_vertex_program *passthrough_vp;
- struct gl_buffer_object *texcoord_vbo;
-
- struct gl_fragment_program *saved_fp;
- GLboolean saved_fp_enable;
- struct gl_vertex_program *saved_vp;
- GLboolean saved_vp_enable;
-
- struct gl_fragment_program *tex2d_fp;
-
- GLboolean saved_texcoord_enable;
- struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo;
- GLenum saved_texcoord_type;
- GLsizei saved_texcoord_size, saved_texcoord_stride;
- const void *saved_texcoord_ptr;
- int saved_active_texture;
-
- GLint saved_vp_x, saved_vp_y;
- GLsizei saved_vp_width, saved_vp_height;
- GLenum saved_matrix_mode;
- } meta;
+ struct dri_metaops meta;
GLint refcount;
GLuint Fallback;
@@ -192,7 +170,6 @@ struct intel_context
struct intel_region *front_region;
struct intel_region *back_region;
struct intel_region *depth_region;
- GLboolean internal_viewport_call;
/**
* This value indicates that the kernel memory manager is being used
@@ -225,13 +202,6 @@ struct intel_context
GLuint ClearColor565;
GLuint ClearColor8888;
- /* info for intel_clear_tris() */
- struct
- {
- struct gl_array_object *arrayObj;
- GLfloat vertices[4][3];
- GLfloat color[4][4];
- } clear;
/* Offsets of fields within the current vertex:
*/
@@ -304,6 +274,14 @@ struct intel_context
* easily.
*/
GLboolean is_front_buffer_rendering;
+ /**
+ * Track whether front-buffer is the current read target.
+ *
+ * This is closely associated with is_front_buffer_rendering, but may
+ * be set separately. The DRI2 fake front buffer must be referenced
+ * either way.
+ */
+ GLboolean is_front_buffer_reading;
GLboolean use_texture_tiling;
GLboolean use_early_z;
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 1e8b1878ab..7742609d24 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -34,6 +34,7 @@
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_array_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_vertex_shader
#define need_GL_ARB_window_pos
@@ -45,6 +46,7 @@
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_gpu_program_parameters
#define need_GL_EXT_point_parameters
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
@@ -66,6 +68,7 @@
* i965_dri.
*/
static const struct dri_extension card_extensions[] = {
+ { "GL_ARB_half_float_pixel", NULL },
{ "GL_ARB_multitexture", NULL },
{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
{ "GL_ARB_texture_border_clamp", NULL },
@@ -76,6 +79,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_ARB_texture_env_dot3", NULL },
{ "GL_ARB_texture_mirrored_repeat", NULL },
{ "GL_ARB_texture_rectangle", NULL },
+ { "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions},
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
{ "GL_ARB_window_pos", GL_ARB_window_pos_functions },
{ "GL_EXT_blend_color", GL_EXT_blend_color_functions },
@@ -86,6 +90,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_EXT_blend_subtract", NULL },
{ "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions },
{ "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_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 0ea413aee1..666893596e 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -516,6 +516,7 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,
irb->Base.BlueBits = texImage->TexFormat->BlueBits;
irb->Base.AlphaBits = texImage->TexFormat->AlphaBits;
irb->Base.DepthBits = texImage->TexFormat->DepthBits;
+ irb->Base.StencilBits = texImage->TexFormat->StencilBits;
irb->Base.Delete = intel_delete_renderbuffer;
irb->Base.AllocStorage = intel_nop_alloc_storage;
diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
index 1060fbd9e5..fe986092db 100644
--- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c
+++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
@@ -88,7 +88,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
return GL_FALSE;
- intel_meta_set_passthrough_transform(intel);
+ meta_set_passthrough_transform(&intel->meta);
/* XXX: Doing it right would involve setting up the transformation to do
* 0-1 mapping or something, and not changing the vertex data.
@@ -104,12 +104,12 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,
_mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);
_mesa_Enable(GL_VERTEX_ARRAY);
- intel_meta_set_default_texrect(intel);
+ meta_set_default_texrect(&intel->meta);
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- intel_meta_restore_texcoords(intel);
- intel_meta_restore_transform(intel);
+ meta_restore_texcoords(&intel->meta);
+ meta_restore_transform(&intel->meta);
return GL_TRUE;
}
@@ -153,9 +153,9 @@ intel_generate_mipmap_2d(GLcontext *ctx,
_mesa_GenFramebuffersEXT(1, &fb_name);
_mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name);
- intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp,
- intel_fp_tex2d);
- intel_meta_set_passthrough_vertex_program(intel);
+ meta_set_fragment_program(&intel->meta, &intel->meta.tex2d_fp,
+ intel_fp_tex2d);
+ meta_set_passthrough_vertex_program(&intel->meta);
max_levels = _mesa_max_texture_levels(ctx, texObj->Target);
start_level = texObj->BaseLevel;
@@ -202,8 +202,8 @@ intel_generate_mipmap_2d(GLcontext *ctx,
success = GL_TRUE;
fail:
- intel_meta_restore_fragment_program(intel);
- intel_meta_restore_vertex_program(intel);
+ meta_restore_fragment_program(&intel->meta);
+ meta_restore_vertex_program(&intel->meta);
_mesa_DeleteFramebuffersEXT(1, &fb_name);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 0d34f28311..c985da5aa2 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -101,6 +101,7 @@ intel_miptree_create_internal(struct intel_context *intel,
struct intel_mipmap_tree *
intel_miptree_create(struct intel_context *intel,
GLenum target,
+ GLenum base_format,
GLenum internal_format,
GLuint first_level,
GLuint last_level,
@@ -113,9 +114,14 @@ intel_miptree_create(struct intel_context *intel,
uint32_t tiling;
if (intel->use_texture_tiling && compress_byte == 0 &&
- intel->intelScreen->kernel_exec_fencing)
- tiling = I915_TILING_X;
- else
+ intel->intelScreen->kernel_exec_fencing) {
+ if (IS_965(intel->intelScreen->deviceID) &&
+ (base_format == GL_DEPTH_COMPONENT ||
+ base_format == GL_DEPTH_STENCIL_EXT))
+ tiling = I915_TILING_Y;
+ else
+ tiling = I915_TILING_X;
+ } else
tiling = I915_TILING_NONE;
mt = intel_miptree_create_internal(intel, target, internal_format,
@@ -347,23 +353,31 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
}
-
void
-intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
- GLuint level, GLuint img,
- GLuint x, GLuint y)
+intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt,
+ GLuint level, GLuint img,
+ GLuint x, GLuint y,
+ GLuint offset)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
assert(img < mt->level[level].nr_images);
- mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp;
+ mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp + offset;
DBG("%s level %d img %d pos %d,%d image_offset %x\n",
__FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
}
+void
+intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
+ GLuint level, GLuint img,
+ GLuint x, GLuint y)
+{
+ intel_miptree_set_image_offset_ex(mt, level, img, x, y, 0);
+}
+
/* Although we use the image_offset[] array to store relative offsets
* to cube faces, Mesa doesn't know anything about this and expects
@@ -473,11 +487,11 @@ intel_miptree_image_data(struct intel_context *intel,
0, 0, /* source x, y */
dst->level[level].width, height); /* width, height */
- src += src_image_pitch * dst->cpp;
+ src = (char *)src + src_image_pitch * dst->cpp;
}
}
-extern GLuint intel_compressed_alignment(GLenum);
+extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *);
/* Copy mipmap image between trees
*/
void
@@ -494,20 +508,37 @@ intel_miptree_image_copy(struct intel_context *intel,
const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level);
GLuint i;
+ GLboolean success;
if (dst->compressed) {
- GLuint alignment = intel_compressed_alignment(dst->internal_format);
+ GLuint align_w, align_h;
+
+ intel_get_texture_alignment_unit(dst->internal_format, &align_w, &align_h);
height = (height + 3) / 4;
- width = ((width + alignment - 1) & ~(alignment - 1));
+ width = ALIGN(width, align_w);
}
for (i = 0; i < depth; i++) {
- intel_region_copy(intel,
- dst->region, dst_offset + dst_depth_offset[i],
- 0,
- 0,
- src->region, src_offset + src_depth_offset[i],
- 0, 0, width, height);
+ success = intel_region_copy(intel,
+ dst->region, dst_offset + dst_depth_offset[i],
+ 0, 0,
+ src->region, src_offset + src_depth_offset[i],
+ 0, 0, width, height, GL_COPY);
+ if (!success) {
+ GLubyte *src_ptr, *dst_ptr;
+
+ src_ptr = intel_region_map(intel, src->region);
+ dst_ptr = intel_region_map(intel, dst->region);
+
+ _mesa_copy_rect(dst_ptr + dst_offset + dst_depth_offset[i],
+ dst->cpp,
+ dst->pitch,
+ 0, 0, width, height,
+ src_ptr + src_offset + src_depth_offset[i],
+ src->pitch,
+ 0, 0);
+ intel_region_unmap(intel, src->region);
+ intel_region_unmap(intel, dst->region);
+ }
}
-
}
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 3af9966827..c890b2a0d0 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -126,6 +126,7 @@ struct intel_mipmap_tree
struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
GLenum target,
+ GLenum base_format,
GLenum internal_format,
GLuint first_level,
GLuint last_level,
@@ -195,6 +196,11 @@ void intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d);
+void intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt,
+ GLuint level,
+ GLuint img, GLuint x, GLuint y,
+ GLuint offset);
+
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint level,
GLuint img, GLuint x, GLuint y);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c
index 36a684b3b8..a300141655 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel.c
@@ -177,246 +177,6 @@ intel_check_blit_format(struct intel_region * region,
}
void
-intel_meta_set_passthrough_transform(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
-
- intel->meta.saved_vp_x = ctx->Viewport.X;
- intel->meta.saved_vp_y = ctx->Viewport.Y;
- intel->meta.saved_vp_width = ctx->Viewport.Width;
- intel->meta.saved_vp_height = ctx->Viewport.Height;
- intel->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
-
- intel->internal_viewport_call = GL_TRUE;
- _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
- intel->internal_viewport_call = GL_FALSE;
-
- _mesa_MatrixMode(GL_PROJECTION);
- _mesa_PushMatrix();
- _mesa_LoadIdentity();
- _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
-
- _mesa_MatrixMode(GL_MODELVIEW);
- _mesa_PushMatrix();
- _mesa_LoadIdentity();
-}
-
-void
-intel_meta_restore_transform(struct intel_context *intel)
-{
- _mesa_MatrixMode(GL_PROJECTION);
- _mesa_PopMatrix();
- _mesa_MatrixMode(GL_MODELVIEW);
- _mesa_PopMatrix();
-
- _mesa_MatrixMode(intel->meta.saved_matrix_mode);
-
- intel->internal_viewport_call = GL_TRUE;
- _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y,
- intel->meta.saved_vp_width, intel->meta.saved_vp_height);
- intel->internal_viewport_call = GL_FALSE;
-}
-
-/**
- * Set up a vertex program to pass through the position and first texcoord
- * for pixel path.
- */
-void
-intel_meta_set_passthrough_vertex_program(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
- static const char *vp =
- "!!ARBvp1.0\n"
- "TEMP vertexClip;\n"
- "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n"
- "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n"
- "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n"
- "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n"
- "MOV result.position, vertexClip;\n"
- "MOV result.texcoord[0], vertex.texcoord[0];\n"
- "MOV result.color, vertex.color;\n"
- "END\n";
-
- assert(intel->meta.saved_vp == NULL);
-
- _mesa_reference_vertprog(ctx, &intel->meta.saved_vp,
- ctx->VertexProgram.Current);
- if (intel->meta.passthrough_vp == NULL) {
- GLuint prog_name;
- _mesa_GenPrograms(1, &prog_name);
- _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name);
- _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB,
- GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(vp), (const GLubyte *)vp);
- _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp,
- ctx->VertexProgram.Current);
- _mesa_DeletePrograms(1, &prog_name);
- }
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
- intel->meta.passthrough_vp);
- ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
- &intel->meta.passthrough_vp->Base);
-
- intel->meta.saved_vp_enable = ctx->VertexProgram.Enabled;
- _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-}
-
-/**
- * Restores the previous vertex program after
- * intel_meta_set_passthrough_vertex_program()
- */
-void
-intel_meta_restore_vertex_program(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
- intel->meta.saved_vp);
- _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, NULL);
- ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
- &ctx->VertexProgram.Current->Base);
-
- if (!intel->meta.saved_vp_enable)
- _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
-}
-
-/**
- * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the
- * program object.
- */
-void
-intel_meta_set_fragment_program(struct intel_context *intel,
- struct gl_fragment_program **prog,
- const char *prog_string)
-{
- GLcontext *ctx = &intel->ctx;
- assert(intel->meta.saved_fp == NULL);
-
- _mesa_reference_fragprog(ctx, &intel->meta.saved_fp,
- ctx->FragmentProgram.Current);
- if (*prog == NULL) {
- GLuint prog_name;
- _mesa_GenPrograms(1, &prog_name);
- _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name);
- _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,
- GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen(prog_string), (const GLubyte *)prog_string);
- _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current);
- /* Note that DeletePrograms unbinds the program on us */
- _mesa_DeletePrograms(1, &prog_name);
- }
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog);
- ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base));
-
- intel->meta.saved_fp_enable = ctx->FragmentProgram.Enabled;
- _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
-}
-
-/**
- * Restores the previous fragment program after
- * intel_meta_set_fragment_program()
- */
-void
-intel_meta_restore_fragment_program(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
- intel->meta.saved_fp);
- _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, NULL);
- ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
- &ctx->FragmentProgram.Current->Base);
-
- if (!intel->meta.saved_fp_enable)
- _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
-}
-
-static const float default_texcoords[4][2] = { { 0.0, 0.0 },
- { 1.0, 0.0 },
- { 1.0, 1.0 },
- { 0.0, 1.0 } };
-
-void
-intel_meta_set_default_texrect(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
- struct gl_client_array *old_texcoord_array;
-
- intel->meta.saved_active_texture = ctx->Texture.CurrentUnit;
- if (intel->meta.saved_array_vbo == NULL) {
- _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo,
- ctx->Array.ArrayBufferObj);
- }
-
- old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0];
- intel->meta.saved_texcoord_type = old_texcoord_array->Type;
- intel->meta.saved_texcoord_size = old_texcoord_array->Size;
- intel->meta.saved_texcoord_stride = old_texcoord_array->Stride;
- intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled;
- intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr;
- _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo,
- old_texcoord_array->BufferObj);
-
- _mesa_ClientActiveTextureARB(GL_TEXTURE0);
-
- if (intel->meta.texcoord_vbo == NULL) {
- GLuint vbo_name;
-
- _mesa_GenBuffersARB(1, &vbo_name);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name);
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords),
- default_texcoords, GL_STATIC_DRAW_ARB);
- _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo,
- ctx->Array.ArrayBufferObj);
- } else {
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
- intel->meta.texcoord_vbo->Name);
- }
- _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL);
-
- _mesa_Enable(GL_TEXTURE_COORD_ARRAY);
-}
-
-void
-intel_meta_restore_texcoords(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
-
- /* Restore the old TexCoordPointer */
- if (intel->meta.saved_texcoord_vbo) {
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
- intel->meta.saved_texcoord_vbo->Name);
- _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL);
- } else {
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- }
-
- _mesa_TexCoordPointer(intel->meta.saved_texcoord_size,
- intel->meta.saved_texcoord_type,
- intel->meta.saved_texcoord_stride,
- intel->meta.saved_texcoord_ptr);
- if (!intel->meta.saved_texcoord_enable)
- _mesa_Disable(GL_TEXTURE_COORD_ARRAY);
-
- _mesa_ClientActiveTextureARB(GL_TEXTURE0 +
- intel->meta.saved_active_texture);
-
- if (intel->meta.saved_array_vbo) {
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
- intel->meta.saved_array_vbo->Name);
- _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL);
- } else {
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- }
-}
-
-void
intelInitPixelFuncs(struct dd_function_table *functions)
{
functions->Accum = _swrast_Accum;
@@ -424,20 +184,7 @@ intelInitPixelFuncs(struct dd_function_table *functions)
functions->Bitmap = intelBitmap;
functions->CopyPixels = intelCopyPixels;
functions->DrawPixels = intelDrawPixels;
-#ifdef I915
- functions->ReadPixels = intelReadPixels;
-#endif
}
-}
-
-void
-intel_free_pixel_state(struct intel_context *intel)
-{
- GLcontext *ctx = &intel->ctx;
-
- _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL);
- _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL);
- _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL);
- _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL);
+ functions->ReadPixels = intelReadPixels;
}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h
index 6acf0813c8..96a6dd17b2 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.h
+++ b/src/mesa/drivers/dri/intel/intel_pixel.h
@@ -31,19 +31,6 @@
#include "main/mtypes.h"
void intelInitPixelFuncs(struct dd_function_table *functions);
-void intel_meta_set_passthrough_transform(struct intel_context *intel);
-void intel_meta_restore_transform(struct intel_context *intel);
-void intel_meta_set_passthrough_vertex_program(struct intel_context *intel);
-void intel_meta_restore_vertex_program(struct intel_context *intel);
-void intel_meta_set_fragment_program(struct intel_context *intel,
- struct gl_fragment_program **prog,
- const char *prog_string);
-void intel_meta_restore_fragment_program(struct intel_context *intel);
-void intel_free_pixel_state(struct intel_context *intel);
-void intel_meta_set_default_texrect(struct intel_context *intel);
-void intel_meta_set_default_texrect(struct intel_context *intel);
-void intel_meta_restore_texcoords(struct intel_context *intel);
-
GLboolean intel_check_blit_fragment_ops(GLcontext * ctx,
GLboolean src_alpha_is_one);
@@ -79,6 +66,4 @@ void intelBitmap(GLcontext * ctx,
const struct gl_pixelstore_attrib *unpack,
const GLubyte * pixels);
-void intel_clear_tris(GLcontext *ctx, GLbitfield mask);
-
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
index 80d3239189..540e7620a9 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -42,6 +42,7 @@
#include "main/varray.h"
#include "main/attrib.h"
#include "main/enable.h"
+#include "main/viewport.h"
#include "shader/arbprogram.h"
#include "glapi/dispatch.h"
#include "swrast/swrast.h"
@@ -194,7 +195,7 @@ do_blit_bitmap( GLcontext *ctx,
struct gl_framebuffer *fb = ctx->DrawBuffer;
GLfloat tmpColor[4];
GLubyte ubcolor[4];
- GLuint color8888, color565;
+ GLuint color;
unsigned int num_cliprects;
drm_clip_rect_t *cliprects;
int x_off, y_off;
@@ -232,8 +233,11 @@ do_blit_bitmap( GLcontext *ctx,
UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
- color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]);
- color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
+ if (dst->cpp == 2)
+ color = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
+ else
+ color = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1],
+ ubcolor[2], ubcolor[3]);
if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
return GL_FALSE;
@@ -307,21 +311,21 @@ do_blit_bitmap( GLcontext *ctx,
fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0)
continue;
- /*
- */
- intelEmitImmediateColorExpandBlit( intel,
- dst->cpp,
- (GLubyte *)stipple,
- sz,
- (dst->cpp == 2) ? color565 : color8888,
- dst->pitch,
- dst->buffer,
- 0,
- dst->tiling,
- box_x + px,
- box_y + py,
- w, h,
- logic_op);
+ if (!intelEmitImmediateColorExpandBlit(intel,
+ dst->cpp,
+ (GLubyte *)stipple,
+ sz,
+ color,
+ dst->pitch,
+ dst->buffer,
+ 0,
+ dst->tiling,
+ box_x + px,
+ box_y + py,
+ w, h,
+ logic_op)) {
+ return GL_FALSE;
+ }
}
}
}
@@ -408,6 +412,12 @@ intel_texture_bitmap(GLcontext * ctx,
return GL_FALSE;
}
+ if (ctx->Fog.Enabled) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "glBitmap() fallback: fog\n");
+ return GL_FALSE;
+ }
+
/* Check that we can load in a texture this big. */
if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) ||
height > (1 << (ctx->Const.MaxTextureLevels - 1))) {
@@ -466,15 +476,18 @@ intel_texture_bitmap(GLcontext * ctx,
GL_ALPHA, GL_UNSIGNED_BYTE, a8_bitmap);
_mesa_free(a8_bitmap);
- intel_meta_set_fragment_program(intel, &intel->meta.bitmap_fp, fp);
+ meta_set_fragment_program(&intel->meta, &intel->meta.bitmap_fp, fp);
_mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
ctx->Current.RasterColor);
- intel_meta_set_passthrough_vertex_program(intel);
- intel_meta_set_passthrough_transform(intel);
+ meta_set_passthrough_vertex_program(&intel->meta);
+ meta_set_passthrough_transform(&intel->meta);
/* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */
dst_z = -1.0 + 2.0 * ctx->Current.RasterPos[2];
+ /* RasterPos[2] already takes into account the DepthRange mapping. */
+ _mesa_DepthRange(0.0, 1.0);
+
vertices[0][0] = dst_x;
vertices[0][1] = dst_y;
vertices[0][2] = dst_z;
@@ -494,13 +507,13 @@ intel_texture_bitmap(GLcontext * ctx,
_mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
_mesa_Enable(GL_VERTEX_ARRAY);
- intel_meta_set_default_texrect(intel);
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ meta_set_default_texrect(&intel->meta);
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- intel_meta_restore_texcoords(intel);
- intel_meta_restore_transform(intel);
- intel_meta_restore_fragment_program(intel);
- intel_meta_restore_vertex_program(intel);
+ meta_restore_texcoords(&intel->meta);
+ meta_restore_transform(&intel->meta);
+ meta_restore_fragment_program(&intel->meta);
+ meta_restore_vertex_program(&intel->meta);
_mesa_PopClientAttrib();
_mesa_Disable(GL_TEXTURE_2D); /* asserted that it was disabled at entry */
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
index d50dd68092..5d52335dee 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
@@ -272,6 +272,12 @@ do_blit_copypixels(GLcontext * ctx,
drm_clip_rect_t *cliprects;
int x_off, y_off;
+ if (type == GL_DEPTH || type == GL_STENCIL) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "glCopyPixels() fallback: GL_DEPTH || GL_STENCIL\n");
+ return GL_FALSE;
+ }
+
/* Update draw buffer bounds */
_mesa_update_state(ctx);
@@ -362,14 +368,16 @@ do_blit_copypixels(GLcontext * ctx,
&clip_x, &clip_y, &clip_w, &clip_h))
continue;
- intelEmitCopyBlit(intel, dst->cpp,
- src->pitch, src->buffer, 0, src->tiling,
- dst->pitch, dst->buffer, 0, dst->tiling,
- clip_x + delta_x, clip_y + delta_y, /* srcx, srcy */
- clip_x, clip_y, /* dstx, dsty */
- clip_w, clip_h,
- ctx->Color.ColorLogicOpEnabled ?
- ctx->Color.LogicOp : GL_COPY);
+ if (!intel_region_copy(intel,
+ dst, 0, clip_x, clip_y,
+ src, 0, clip_x + delta_x, clip_y + delta_y,
+ clip_w, clip_h,
+ ctx->Color.ColorLogicOpEnabled ?
+ ctx->Color.LogicOp : GL_COPY)) {
+ DBG("%s: blit failure\n", __FUNCTION__);
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
}
}
out:
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
index 46d27f1a93..a6b6824164 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -45,6 +45,7 @@
#include "main/depth.h"
#include "main/hash.h"
#include "main/blend.h"
+#include "main/viewport.h"
#include "glapi/dispatch.h"
#include "swrast/swrast.h"
@@ -128,7 +129,7 @@ intel_texture_drawpixels(GLcontext * ctx,
}
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
- GL_CURRENT_BIT);
+ GL_CURRENT_BIT | GL_VIEWPORT_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
/* XXX: pixel store stuff */
@@ -149,11 +150,14 @@ intel_texture_drawpixels(GLcontext * ctx,
_mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format,
type, pixels);
- intel_meta_set_passthrough_transform(intel);
+ meta_set_passthrough_transform(&intel->meta);
/* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */
z = -1.0 + 2.0 * ctx->Current.RasterPos[2];
+ /* RasterPos[2] already takes into account the DepthRange mapping. */
+ _mesa_DepthRange(0.0, 1.0);
+
/* Create the vertex buffer based on the current raster pos. The x and y
* we're handed are ctx->Current.RasterPos[0,1] rounded to integers.
* We also apply the depth. However, the W component is already multiplied
@@ -178,12 +182,12 @@ intel_texture_drawpixels(GLcontext * ctx,
_mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
_mesa_Enable(GL_VERTEX_ARRAY);
- intel_meta_set_default_texrect(intel);
+ meta_set_default_texrect(&intel->meta);
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- intel_meta_restore_texcoords(intel);
- intel_meta_restore_transform(intel);
+ meta_restore_texcoords(&intel->meta);
+ meta_restore_transform(&intel->meta);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
_mesa_PopClientAttrib();
@@ -211,8 +215,9 @@ intel_stencil_drawpixels(GLcontext * ctx,
struct gl_renderbuffer *rb;
struct gl_pixelstore_attrib old_unpack;
GLstencil *stencil_pixels;
- int row;
+ int row, y1, y2;
GLint old_active_texture;
+ GLboolean rendering_to_fbo = ctx->DrawBuffer->Name != 0;
if (format != GL_STENCIL_INDEX)
return GL_FALSE;
@@ -347,24 +352,35 @@ intel_stencil_drawpixels(GLcontext * ctx,
ctx->Unpack = old_unpack;
_mesa_free(stencil_pixels);
- intel_meta_set_passthrough_transform(intel);
+ meta_set_passthrough_transform(&intel->meta);
+
+ /* Since we're rendering to the framebuffer as if it was an FBO,
+ * if it's the window system we have to flip the coordinates.
+ */
+ if (rendering_to_fbo) {
+ y1 = y;
+ y2 = y + height * ctx->Pixel.ZoomY;
+ } else {
+ y1 = irb->Base.Height - (y + height * ctx->Pixel.ZoomY);
+ y2 = irb->Base.Height - y;
+ }
vertices[0][0] = x;
- vertices[0][1] = y;
+ vertices[0][1] = y1;
vertices[1][0] = x + width * ctx->Pixel.ZoomX;
- vertices[1][1] = y;
+ vertices[1][1] = y1;
vertices[2][0] = x + width * ctx->Pixel.ZoomX;
- vertices[2][1] = y + height * ctx->Pixel.ZoomY;
+ vertices[2][1] = y2;
vertices[3][0] = x;
- vertices[3][1] = y + height * ctx->Pixel.ZoomY;
+ vertices[3][1] = y2;
_mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);
_mesa_Enable(GL_VERTEX_ARRAY);
- intel_meta_set_default_texrect(intel);
+ meta_set_default_texrect(&intel->meta);
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
- intel_meta_restore_texcoords(intel);
- intel_meta_restore_transform(intel);
+ meta_restore_texcoords(&intel->meta);
+ meta_restore_transform(&intel->meta);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
_mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
new file mode 100644
index 0000000000..8713463ace
--- /dev/null
+++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c
@@ -0,0 +1,324 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/image.h"
+#include "main/bufferobj.h"
+#include "main/state.h"
+#include "swrast/swrast.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_blit.h"
+#include "intel_buffers.h"
+#include "intel_regions.h"
+#include "intel_pixel.h"
+#include "intel_buffer_objects.h"
+
+/* For many applications, the new ability to pull the source buffers
+ * back out of the GTT and then do the packing/conversion operations
+ * in software will be as much of an improvement as trying to get the
+ * blitter and/or texture engine to do the work.
+ *
+ * This step is gated on private backbuffers.
+ *
+ * Obviously the frontbuffer can't be pulled back, so that is either
+ * an argument for blit/texture readpixels, or for blitting to a
+ * temporary and then pulling that back.
+ *
+ * When the destination is a pbo, however, it's not clear if it is
+ * ever going to be pulled to main memory (though the access param
+ * will be a good hint). So it sounds like we do want to be able to
+ * choose between blit/texture implementation on the gpu and pullback
+ * and cpu-based copying.
+ *
+ * Unless you can magically turn client memory into a PBO for the
+ * duration of this call, there will be a cpu-based copying step in
+ * any case.
+ */
+
+
+static GLboolean
+do_texture_readpixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack,
+ struct intel_region *dest_region)
+{
+#if 0
+ struct intel_context *intel = intel_context(ctx);
+ intelScreenPrivate *screen = intel->intelScreen;
+ GLint pitch = pack->RowLength ? pack->RowLength : width;
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ int textureFormat;
+ GLenum glTextureFormat;
+ int destFormat, depthFormat, destPitch;
+ drm_clip_rect_t tmp;
+
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+
+ if (ctx->_ImageTransferState ||
+ pack->SwapBytes || pack->LsbFirst || !pack->Invert) {
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel));
+
+ if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) {
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ fprintf(stderr, "%s: couldn't set dest %s/%s\n",
+ __FUNCTION__,
+ _mesa_lookup_enum_by_nr(type),
+ _mesa_lookup_enum_by_nr(format));
+ return GL_FALSE;
+ }
+
+ LOCK_HARDWARE(intel);
+
+ if (intel->driDrawable->numClipRects) {
+ intel->vtbl.install_meta_state(intel);
+ intel->vtbl.meta_no_depth_write(intel);
+ intel->vtbl.meta_no_stencil_write(intel);
+
+ if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
+ UNLOCK_HARDWARE(intel);
+ SET_STATE(i830, state);
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
+ return GL_TRUE;
+ }
+
+ y = dPriv->h - y - height;
+ x += dPriv->x;
+ y += dPriv->y;
+
+
+ /* Set the frontbuffer up as a large rectangular texture.
+ */
+ intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat);
+
+
+ intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat);
+
+
+ /* Set the 3d engine to draw into the destination region:
+ */
+
+ intel->vtbl.meta_draw_region(intel, dest_region);
+ intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */
+
+
+ /* Draw a single quad, no cliprects:
+ */
+ intel->vtbl.meta_disable_cliprects(intel);
+
+ intel->vtbl.draw_quad(intel,
+ 0, width, 0, height,
+ 0x00ff00ff, x, x + width, y, y + height);
+
+ intel->vtbl.leave_meta_state(intel);
+ }
+ UNLOCK_HARDWARE(intel);
+
+ intel_region_wait_fence(ctx, dest_region); /* required by GL */
+ return GL_TRUE;
+#endif
+
+ return GL_FALSE;
+}
+
+
+
+
+static GLboolean
+do_blit_readpixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_region *src = intel_readbuf_region(intel);
+ struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
+ GLuint dst_offset;
+ GLuint rowLength;
+
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s\n", __FUNCTION__);
+
+ if (!src)
+ return GL_FALSE;
+
+ if (pack->BufferObj->Name) {
+ /* XXX This validation should be done by core mesa:
+ */
+ if (!_mesa_validate_pbo_access(2, pack, width, height, 1,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels");
+ return GL_TRUE;
+ }
+ }
+ else {
+ /* PBO only for now:
+ */
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s - not PBO\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+
+ if (ctx->_ImageTransferState ||
+ !intel_check_blit_format(src, format, type)) {
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s - bad format for blit\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) {
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s: bad packing params\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ if (pack->RowLength > 0)
+ rowLength = pack->RowLength;
+ else
+ rowLength = width;
+
+ if (pack->Invert) {
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ else {
+ rowLength = -rowLength;
+ }
+
+ /* XXX 64-bit cast? */
+ dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height,
+ format, type, 0, 0, 0);
+
+
+ /* Although the blits go on the command buffer, need to do this and
+ * fire with lock held to guarentee cliprects are correct.
+ */
+ intelFlush(&intel->ctx);
+ LOCK_HARDWARE(intel);
+
+ if (intel->driDrawable->numClipRects) {
+ GLboolean all = (width * height * src->cpp == dst->Base.Size &&
+ x == 0 && dst_offset == 0);
+
+ dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
+ all ? INTEL_WRITE_FULL :
+ INTEL_WRITE_PART);
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ int nbox = dPriv->numClipRects;
+ drm_clip_rect_t *box = dPriv->pClipRects;
+ drm_clip_rect_t rect;
+ drm_clip_rect_t src_rect;
+ int i;
+
+ src_rect.x1 = dPriv->x + x;
+ src_rect.y1 = dPriv->y + dPriv->h - (y + height);
+ src_rect.x2 = src_rect.x1 + width;
+ src_rect.y2 = src_rect.y1 + height;
+
+
+
+ for (i = 0; i < nbox; i++) {
+ if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
+ continue;
+
+ if (!intelEmitCopyBlit(intel,
+ src->cpp,
+ src->pitch, src->buffer, 0, src->tiling,
+ rowLength, dst_buffer, dst_offset, GL_FALSE,
+ rect.x1,
+ rect.y1,
+ rect.x1 - src_rect.x1,
+ rect.y2 - src_rect.y2,
+ rect.x2 - rect.x1, rect.y2 - rect.y1,
+ GL_COPY)) {
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
+ }
+ }
+ UNLOCK_HARDWARE(intel);
+
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s - DONE\n", __FUNCTION__);
+
+ return GL_TRUE;
+}
+
+void
+intelReadPixels(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ intelFlush(ctx);
+
+#ifdef I915
+ if (do_blit_readpixels
+ (ctx, x, y, width, height, format, type, pack, pixels))
+ return;
+
+ if (do_texture_readpixels
+ (ctx, x, y, width, height, format, type, pack, pixels))
+ return;
+#else
+ (void)do_blit_readpixels;
+ (void)do_texture_readpixels;
+#endif
+
+ if (INTEL_DEBUG & DEBUG_PIXEL)
+ _mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
+
+ /* Update Mesa state before calling down into _swrast_ReadPixels, as
+ * the spans code requires the computed buffer states to be up to date,
+ * but _swrast_ReadPixels only updates Mesa state after setting up
+ * the spans code.
+ */
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels);
+}
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 49bcb3c1dd..7525cd9c4d 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -111,12 +111,15 @@ debug_backtrace(void)
GLubyte *
intel_region_map(struct intel_context *intel, struct intel_region *region)
{
+ intelFlush(&intel->ctx);
+
_DBG("%s %p\n", __FUNCTION__, region);
if (!region->map_refcount++) {
if (region->pbo)
intel_region_cow(intel, region);
- if (intel->intelScreen->kernel_exec_fencing)
+ if (region->tiling != I915_TILING_NONE &&
+ intel->intelScreen->kernel_exec_fencing)
drm_intel_gem_bo_map_gtt(region->buffer);
else
dri_bo_map(region->buffer, GL_TRUE);
@@ -131,7 +134,8 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region)
{
_DBG("%s %p\n", __FUNCTION__, region);
if (!--region->map_refcount) {
- if (intel->intelScreen->kernel_exec_fencing)
+ if (region->tiling != I915_TILING_NONE &&
+ intel->intelScreen->kernel_exec_fencing)
drm_intel_gem_bo_unmap_gtt(region->buffer);
else
dri_bo_unmap(region->buffer);
@@ -189,7 +193,7 @@ intel_region_alloc(struct intel_context *intel,
pitch, buffer);
if (tiling != I915_TILING_NONE) {
- assert(((pitch * cpp) & 511) == 0);
+ assert(((pitch * cpp) & 127) == 0);
drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp);
drm_intel_bo_get_tiling(buffer, &region->tiling, &region->bit_6_swizzle);
}
@@ -323,8 +327,6 @@ intel_region_data(struct intel_context *intel,
const void *src, GLuint src_pitch,
GLuint srcx, GLuint srcy, GLuint width, GLuint height)
{
- GLboolean locked = GL_FALSE;
-
_DBG("%s\n", __FUNCTION__);
if (intel == NULL)
@@ -338,39 +340,33 @@ intel_region_data(struct intel_context *intel,
intel_region_cow(intel, dst);
}
- if (!intel->locked) {
- LOCK_HARDWARE(intel);
- locked = GL_TRUE;
- }
-
+ LOCK_HARDWARE(intel);
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
dst->cpp,
dst->pitch,
dstx, dsty, width, height, src, src_pitch, srcx, srcy);
intel_region_unmap(intel, dst);
-
- if (locked)
- UNLOCK_HARDWARE(intel);
-
+ UNLOCK_HARDWARE(intel);
}
/* Copy rectangular sub-regions. Need better logic about when to
* push buffers into AGP - will currently do so whenever possible.
*/
-void
+GLboolean
intel_region_copy(struct intel_context *intel,
struct intel_region *dst,
GLuint dst_offset,
GLuint dstx, GLuint dsty,
struct intel_region *src,
GLuint src_offset,
- GLuint srcx, GLuint srcy, GLuint width, GLuint height)
+ GLuint srcx, GLuint srcy, GLuint width, GLuint height,
+ GLenum logicop)
{
_DBG("%s\n", __FUNCTION__);
if (intel == NULL)
- return;
+ return GL_FALSE;
if (dst->pbo) {
if (dstx == 0 &&
@@ -382,41 +378,12 @@ intel_region_copy(struct intel_context *intel,
assert(src->cpp == dst->cpp);
- intelEmitCopyBlit(intel,
- dst->cpp,
- src->pitch, src->buffer, src_offset, src->tiling,
- dst->pitch, dst->buffer, dst_offset, dst->tiling,
- srcx, srcy, dstx, dsty, width, height,
- GL_COPY);
-}
-
-/* Fill a rectangular sub-region. Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-void
-intel_region_fill(struct intel_context *intel,
- struct intel_region *dst,
- GLuint dst_offset,
- GLuint dstx, GLuint dsty,
- GLuint width, GLuint height, GLuint color)
-{
- _DBG("%s\n", __FUNCTION__);
-
- if (intel == NULL)
- return;
-
- if (dst->pbo) {
- if (dstx == 0 &&
- dsty == 0 && width == dst->pitch && height == dst->height)
- intel_region_release_pbo(intel, dst);
- else
- intel_region_cow(intel, dst);
- }
-
- intelEmitFillBlit(intel,
- dst->cpp,
- dst->pitch, dst->buffer, dst_offset, dst->tiling,
- dstx, dsty, width, height, color);
+ return intelEmitCopyBlit(intel,
+ dst->cpp,
+ src->pitch, src->buffer, src_offset, src->tiling,
+ dst->pitch, dst->buffer, dst_offset, dst->tiling,
+ srcx, srcy, dstx, dsty, width, height,
+ logicop);
}
/* Attach to a pbo, discarding our data. Effectively zero-copy upload
@@ -427,6 +394,8 @@ intel_region_attach_pbo(struct intel_context *intel,
struct intel_region *region,
struct intel_buffer_object *pbo)
{
+ dri_bo *buffer;
+
if (region->pbo == pbo)
return;
@@ -447,10 +416,13 @@ intel_region_attach_pbo(struct intel_context *intel,
region->buffer = NULL;
}
+ /* make sure pbo has a buffer of its own */
+ buffer = intel_bufferobj_buffer(intel, pbo, INTEL_WRITE_FULL);
+
region->pbo = pbo;
region->pbo->region = region;
- dri_bo_reference(pbo->buffer);
- region->buffer = pbo->buffer;
+ dri_bo_reference(buffer);
+ region->buffer = buffer;
}
@@ -480,10 +452,6 @@ void
intel_region_cow(struct intel_context *intel, struct intel_region *region)
{
struct intel_buffer_object *pbo = region->pbo;
- GLboolean was_locked = intel->locked;
-
- if (intel == NULL)
- return;
intel_region_release_pbo(intel, region);
@@ -494,20 +462,15 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region)
/* Now blit from the texture buffer to the new buffer:
*/
- was_locked = intel->locked;
- if (!was_locked)
- LOCK_HARDWARE(intel);
-
- intelEmitCopyBlit(intel,
- region->cpp,
- region->pitch, region->buffer, 0, region->tiling,
- region->pitch, pbo->buffer, 0, region->tiling,
- 0, 0, 0, 0,
- region->pitch, region->height,
- GL_COPY);
-
- if (!was_locked)
- UNLOCK_HARDWARE(intel);
+ 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));
+ UNLOCK_HARDWARE(intel);
}
dri_bo *
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index bd3c8e7325..0d379bdc6e 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -110,21 +110,15 @@ void intel_region_data(struct intel_context *intel,
/* Copy rectangular sub-regions
*/
-void intel_region_copy(struct intel_context *intel,
- struct intel_region *dest,
- GLuint dest_offset,
- GLuint destx, GLuint desty,
- struct intel_region *src,
- GLuint src_offset,
- GLuint srcx, GLuint srcy, GLuint width, GLuint height);
-
-/* Fill a rectangular sub-region
- */
-void intel_region_fill(struct intel_context *intel,
- struct intel_region *dest,
- GLuint dest_offset,
- GLuint destx, GLuint desty,
- GLuint width, GLuint height, GLuint color);
+GLboolean
+intel_region_copy(struct intel_context *intel,
+ struct intel_region *dest,
+ GLuint dest_offset,
+ GLuint destx, GLuint desty,
+ struct intel_region *src,
+ GLuint src_offset,
+ GLuint srcx, GLuint srcy, GLuint width, GLuint height,
+ GLenum logicop);
/* Helpers for zerocopy uploads, particularly texture image uploads:
*/
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 8da96ede64..6bbc995c1e 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -69,11 +69,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_DESC_END
DRI_CONF_OPT_END
-#ifdef I915
- DRI_CONF_TEXTURE_TILING(false)
-#else
- DRI_CONF_TEXTURE_TILING(true)
-#endif
+ DRI_CONF_TEXTURE_TILING(false)
DRI_CONF_OPT_BEGIN(early_z, bool, false)
DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
@@ -320,7 +316,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv)
dri_bufmgr_destroy(intelScreen->bufmgr);
intelUnmapScreenRegions(intelScreen);
- driDestroyOptionCache(&intelScreen->optionCache);
+ driDestroyOptionInfo(&intelScreen->optionCache);
FREE(intelScreen);
sPriv->private = NULL;
@@ -410,6 +406,30 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
static void
intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
{
+ struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate;
+ struct intel_renderbuffer *depth_rb;
+ struct intel_renderbuffer *stencil_rb;
+
+ if (intel_fb) {
+ if (intel_fb->color_rb[0]) {
+ intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
+ }
+
+ if (intel_fb->color_rb[1]) {
+ intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
+ }
+
+ depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+ if (depth_rb) {
+ intel_renderbuffer_set_region(depth_rb, NULL);
+ }
+
+ stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+ if (stencil_rb) {
+ intel_renderbuffer_set_region(stencil_rb, NULL);
+ }
+ }
+
_mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
}
@@ -578,7 +598,7 @@ intel_init_bufmgr(intelScreenPrivate *intelScreen)
GLboolean gem_supported;
struct drm_i915_getparam gp;
__DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
- int num_fences;
+ int num_fences = 0;
intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 260235b1eb..028b49c14d 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -73,11 +73,8 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat)
return NULL;
case GL_RGBA:
case GL_RGBA8:
- return intel_readbuf_region(intel);
case GL_RGB:
- if (intel->ctx.Visual.rgbBits == 16)
- return intel_readbuf_region(intel);
- return NULL;
+ return intel_readbuf_region(intel);
default:
return NULL;
}
@@ -99,14 +96,24 @@ do_copy_texsubimage(struct intel_context *intel,
if (!intelImage->mt || !src) {
if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "%s fail %p %p\n",
- __FUNCTION__, intelImage->mt, src);
+ fprintf(stderr, "%s fail %p %p (0x%08x)\n",
+ __FUNCTION__, intelImage->mt, src, internalFormat);
+ return GL_FALSE;
+ }
+
+ if (intelImage->mt->cpp != src->cpp) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "%s fail %d vs %d cpp\n",
+ __FUNCTION__, intelImage->mt->cpp, src->cpp);
return GL_FALSE;
}
intelFlush(ctx);
LOCK_HARDWARE(intel);
{
+ drm_intel_bo *dst_bo = intel_region_buffer(intel,
+ intelImage->mt->region,
+ INTEL_WRITE_PART);
GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
intelImage->face,
intelImage->level);
@@ -144,18 +151,21 @@ do_copy_texsubimage(struct intel_context *intel,
src_pitch = src->pitch;
}
- intelEmitCopyBlit(intel,
- intelImage->mt->cpp,
- src_pitch,
- src->buffer,
- 0,
- src->tiling,
- intelImage->mt->pitch,
- intelImage->mt->region->buffer,
- image_offset,
- intelImage->mt->region->tiling,
- x, y, dstx, dsty, width, height,
- GL_COPY);
+ if (!intelEmitCopyBlit(intel,
+ intelImage->mt->cpp,
+ src_pitch,
+ src->buffer,
+ 0,
+ src->tiling,
+ intelImage->mt->pitch,
+ dst_bo,
+ image_offset,
+ intelImage->mt->region->tiling,
+ x, y, dstx, dsty, width, height,
+ GL_COPY)) {
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
}
UNLOCK_HARDWARE(intel);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index e9a3823078..c5f5220837 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -131,6 +131,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
intelObj->mt = intel_miptree_create(intel,
intelObj->base.Target,
+ intelImage->base._BaseFormat,
intelImage->base.InternalFormat,
firstLevel,
lastLevel,
@@ -205,7 +206,7 @@ try_pbo_upload(struct intel_context *intel,
GLuint src_offset, src_stride;
GLuint dst_offset, dst_stride;
- if (!pbo ||
+ if (unpack->BufferObj->Name == 0 ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
DBG("%s: failure 1\n", __FUNCTION__);
@@ -235,12 +236,15 @@ try_pbo_upload(struct intel_context *intel,
INTEL_WRITE_FULL);
- intelEmitCopyBlit(intel,
- intelImage->mt->cpp,
- src_stride, src_buffer, src_offset, GL_FALSE,
- dst_stride, dst_buffer, dst_offset, GL_FALSE,
- 0, 0, 0, 0, width, height,
- GL_COPY);
+ if (!intelEmitCopyBlit(intel,
+ intelImage->mt->cpp,
+ src_stride, src_buffer, src_offset, GL_FALSE,
+ dst_stride, dst_buffer, dst_offset, GL_FALSE,
+ 0, 0, 0, 0, width, height,
+ GL_COPY)) {
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
}
UNLOCK_HARDWARE(intel);
@@ -260,7 +264,7 @@ try_pbo_zcopy(struct intel_context *intel,
GLuint src_offset, src_stride;
GLuint dst_offset, dst_stride;
- if (!pbo ||
+ if (unpack->BufferObj->Name == 0 ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
DBG("%s: failure 1\n", __FUNCTION__);
@@ -409,7 +413,9 @@ intelTexImage(GLcontext * ctx,
* a miptree, so create one just for our level and store it in the image.
* It'll get moved into the object miptree at validate time.
*/
- intelImage->mt = intel_miptree_create(intel, target, internalFormat,
+ intelImage->mt = intel_miptree_create(intel, target,
+ intelImage->base.TexFormat->BaseFormat,
+ internalFormat,
level, level,
width, height, depth,
intelImage->base.TexFormat->TexelBytes,
@@ -421,7 +427,7 @@ intelTexImage(GLcontext * ctx,
*/
if (dims <= 2 &&
intelImage->mt &&
- intel_buffer_object(unpack->BufferObj) &&
+ unpack->BufferObj->Name != 0 &&
check_pbo_format(internalFormat, format,
type, intelImage->base.TexFormat)) {
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index 2c1b722b7f..7d69ea4484 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -35,28 +35,39 @@
#include "intel_context.h"
#include "main/macros.h"
-GLuint intel_compressed_alignment(GLenum internalFormat)
+void intel_get_texture_alignment_unit(GLenum internalFormat, GLuint *w, GLuint *h)
{
- GLuint alignment = 4;
-
switch (internalFormat) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
- alignment = 8;
+ *w = 8;
+ *h = 4;
+ break;
+
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ *w = 4;
+ *h = 4;
break;
default:
+ *w = 4;
+ *h = 2;
break;
}
-
- return alignment;
}
void i945_miptree_layout_2d( struct intel_context *intel,
struct intel_mipmap_tree *mt,
uint32_t tiling )
{
- GLint align_h = 2, align_w = 4;
+ GLuint align_h = 2, align_w = 4;
GLuint level;
GLuint x = 0;
GLuint y = 0;
@@ -64,9 +75,9 @@ void i945_miptree_layout_2d( struct intel_context *intel,
GLuint height = mt->height0;
mt->pitch = mt->width0;
+ intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
if (mt->compressed) {
- align_w = intel_compressed_alignment(mt->internal_format);
mt->pitch = ALIGN(mt->width0, align_w);
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
index 7bc25b6bcb..c9de9b5678 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -41,4 +41,4 @@ static GLuint minify( GLuint d )
extern void i945_miptree_layout_2d(struct intel_context *intel,
struct intel_mipmap_tree *mt,
uint32_t tiling);
-extern GLuint intel_compressed_alignment(GLenum);
+extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index b5cb7597d1..a284d5475f 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -199,6 +199,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
if (!intelObj->mt) {
intelObj->mt = intel_miptree_create(intel,
intelObj->base.Target,
+ firstImage->base._BaseFormat,
firstImage->base.InternalFormat,
intelObj->firstLevel,
intelObj->lastLevel,
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index 451dcd1b55..4ae7bf5b97 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -771,6 +771,11 @@ static void r128DDLightModelfv( GLcontext *ctx, GLenum pname,
FLUSH_BATCH( rmesa );
updateSpecularLighting(ctx);
}
+
+ if ( pname == GL_LIGHT_MODEL_TWO_SIDE ) {
+ FLUSH_BATCH( rmesa );
+ r128ChooseRenderState( ctx );
+ }
}
static void r128DDShadeModel( GLcontext *ctx, GLenum mode )
diff --git a/src/mesa/drivers/dri/r128/r128_tris.c b/src/mesa/drivers/dri/r128/r128_tris.c
index bcc9ffa651..5b91271d74 100644
--- a/src/mesa/drivers/dri/r128/r128_tris.c
+++ b/src/mesa/drivers/dri/r128/r128_tris.c
@@ -426,7 +426,7 @@ r128_fallback_point( r128ContextPtr rmesa,
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
#define _R128_NEW_RENDER_STATE (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)
-static void r128ChooseRenderState(GLcontext *ctx)
+void r128ChooseRenderState(GLcontext *ctx)
{
r128ContextPtr rmesa = R128_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
diff --git a/src/mesa/drivers/dri/r128/r128_tris.h b/src/mesa/drivers/dri/r128/r128_tris.h
index d90ca31534..c0667edb61 100644
--- a/src/mesa/drivers/dri/r128/r128_tris.h
+++ b/src/mesa/drivers/dri/r128/r128_tris.h
@@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/mtypes.h"
extern void r128InitTriFuncs( GLcontext *ctx );
-
+extern void r128ChooseRenderState( GLcontext *ctx );
extern void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( rmesa, bit, mode ) r128Fallback( rmesa->glCtx, bit, mode )
diff --git a/src/mesa/drivers/dri/r200/.gitignore b/src/mesa/drivers/dri/r200/.gitignore
index 3773d8ea73..2f9cd1a987 100644
--- a/src/mesa/drivers/dri/r200/.gitignore
+++ b/src/mesa/drivers/dri/r200/.gitignore
@@ -1,3 +1,15 @@
+radeon_bocs_wrapper.h
+radeon_bo_legacy.[ch]
radeon_chipset.h
-radeon_screen.*
+radeon_cmdbuf.h
+radeon_common.[ch]
+radeon_common_context.[ch]
+radeon_cs_legacy.[ch]
+radeon_dma.[ch]
+radeon_fbo.c
+radeon_lock.[ch]
+radeon_mipmap_tree.[ch]
+radeon_screen.[ch]
+radeon_span.[ch]
+radeon_texture.[ch]
server
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 6a246edf7c..4686241957 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1)
EGL_SOURCES = server/radeon_egl.c
endif
+ifeq ($(RADEON_LDFLAGS),)
+CS_SOURCES = radeon_cs_space_drm.c
+endif
+
RADEON_COMMON_SOURCES = \
radeon_texture.c \
radeon_common_context.c \
@@ -42,7 +46,8 @@ DRIVER_SOURCES = r200_context.c \
r200_vertprog.c \
radeon_screen.c \
$(EGL_SOURCES) \
- $(RADEON_COMMON_SOURCES)
+ $(RADEON_COMMON_SOURCES) \
+ $(CS_SOURCES)
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
@@ -82,7 +87,8 @@ COMMON_SYMLINKS = \
radeon_texture.h \
radeon_dma.c \
radeon_dma.h \
- radeon_fbo.c
+ radeon_fbo.c \
+ $(CS_SOURCES)
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index df9dd83344..25e30eda52 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -225,6 +225,7 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
GLuint min_nr )
{
GLushort *retval;
+ int ret;
if (R200_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
@@ -239,10 +240,11 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
rmesa->radeon.tcl.elt_dma_offset = 0;
rmesa->tcl.elt_used = min_nr * 2;
- radeon_validate_bo(&rmesa->radeon, rmesa->radeon.tcl.elt_dma_bo,
- RADEON_GEM_DOMAIN_GTT, 0);
- if (radeon_revalidate_bos(rmesa->radeon.glCtx) == GL_FALSE)
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret) {
fprintf(stderr,"failure to revalidate BOs - badness\n");
+ }
radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 8924849d08..9a92a32079 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -357,6 +357,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
/* FIXME: When no memory manager is available we should set this
* to some reasonable value based on texture memory pool size */
ctx->Const.MaxTextureLevels = 12;
+ ctx->Const.Max3DTextureLevels = 9;
+ ctx->Const.MaxCubeTextureLevels = 12;
+ ctx->Const.MaxTextureRectSize = 2048;
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
@@ -388,6 +391,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
ctx->Const.MaxDrawBuffers = 1;
+ _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index 0b3398a730..4dbda39eb9 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -58,11 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R200_TIMEOUT 512
#define R200_IDLE_RETRY 16
-static void r200UserClear(GLcontext *ctx, GLuint mask)
-{
- radeon_clear_tris(ctx, mask);
-}
-
static void r200KernelClear(GLcontext *ctx, GLuint flags)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -196,7 +191,10 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
GLuint orig_mask = mask;
if ( R200_DEBUG & DEBUG_IOCTL ) {
- fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
+ if (rmesa->radeon.sarea)
+ fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
+ else
+ fprintf( stderr, "r200Clear %x radeon->sarea is NULL\n", mask);
}
{
@@ -250,7 +248,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
}
if (rmesa->radeon.radeonScreen->kernel_mm)
- r200UserClear(ctx, orig_mask);
+ radeonUserClear(ctx, orig_mask);
else {
r200KernelClear(ctx, flags);
rmesa->radeon.hw.all_dirty = GL_TRUE;
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index f8ebe0df57..5a6fd20d8c 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -574,6 +574,10 @@ static void r200FrontFace( GLcontext *ctx, GLenum mode )
R200_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW;
+ /* Winding is inverted when rendering to FBO */
+ if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+ mode = (mode == GL_CW) ? GL_CCW : GL_CW;
+
switch ( mode ) {
case GL_CW:
rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW;
@@ -709,14 +713,20 @@ static void r200ColorMask( GLcontext *ctx,
GLboolean b, GLboolean a )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
- ctx->Color.ColorMask[RCOMP],
- ctx->Color.ColorMask[GCOMP],
- ctx->Color.ColorMask[BCOMP],
- ctx->Color.ColorMask[ACOMP] );
-
+ GLuint mask;
+ struct radeon_renderbuffer *rrb;
GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ if (!rrb)
+ return;
+ mask = radeonPackColor( rrb->cpp,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] );
+
+
if (!(r && g && b && a))
flag |= R200_PLANE_MASK_ENABLE;
@@ -1720,11 +1730,16 @@ static void r200ClearColor( GLcontext *ctx, const GLfloat c[4] )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLubyte color[4];
+ struct radeon_renderbuffer *rrb;
+
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ if (!rrb)
+ return;
CLAMPED_FLOAT_TO_UBYTE(color[0], c[0]);
CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]);
CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]);
CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]);
- rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
+ rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
color[0], color[1],
color[2], color[3] );
}
@@ -2274,23 +2289,23 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
- int i;
+ int i, ret;
- radeon_validate_reset_bos(&rmesa->radeon);
+ radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -2301,17 +2316,17 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
if (t->image_override && t->bo)
- radeon_validate_bo(&rmesa->radeon, t->bo,
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
else if (t->mt->bo)
- radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- if (rmesa->radeon.dma.current)
- radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
-
- return radeon_revalidate_bos(ctx);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ return GL_TRUE;
}
GLboolean r200ValidateState( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index 8392009337..bc871d9904 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -484,8 +484,17 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10);
if (rrb->cpp == 4)
atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888;
- else
+ else switch (rrb->base._ActualFormat) {
+ case GL_RGB5:
atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565;
+ break;
+ case GL_RGBA4:
+ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB4444;
+ break;
+ case GL_RGB5_A1:
+ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB1555;
+ break;
+ }
cbpitch = (rrb->pitch / rrb->cpp);
if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
@@ -585,6 +594,8 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
radeon_mipmap_level *lvl;
int hastexture = 1;
+ if (!r200->state.texture.unit[i].unitneeded)
+ hastexture = 0;
if (!t)
hastexture = 0;
else {
@@ -620,6 +631,30 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
+ uint32_t dwords = 3;
+ int i = atom->idx, j;
+ radeonTexObj *t = r200->state.texture.unit[i].texobj;
+ radeon_mipmap_level *lvl;
+
+ BEGIN_BATCH_NO_AUTOSTATE(dwords + (3 * 5));
+ /* XXX that size won't really match with image_override... */
+ OUT_BATCH_TABLE(atom->cmd, 2);
+
+ if (t && !t->image_override) {
+ lvl = &t->mt->levels[0];
+ OUT_BATCH_TABLE((atom->cmd + 2), 1);
+ for (j = 1; j <= 5; j++) {
+ OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset,
+ RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ }
+ }
+ END_BATCH();
+}
+
+static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ BATCH_LOCALS(&r200->radeon);
uint32_t dwords = 2;
int i = atom->idx, j;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
@@ -752,7 +787,10 @@ void r200InitState( r200ContextPtr rmesa )
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++)
- rmesa->hw.cube[i].emit = cube_emit;
+ if (rmesa->radeon.radeonScreen->kernel_mm)
+ rmesa->hw.cube[i].emit = cube_emit_cs;
+ else
+ rmesa->hw.cube[i].emit = cube_emit;
}
else {
ALLOC_STATE( cube[0], never, CUBE_STATE_SIZE, "CUBE/tex-0", 0 );
diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
index ed1995e147..4e53672aee 100644
--- a/src/mesa/drivers/dri/r200/r200_texstate.c
+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
@@ -834,7 +834,7 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
rImage->mt = NULL;
}
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
- rb->width, rb->height, 1, 0, rb->cpp);
+ rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
texImage->RowStride = rb->pitch / rb->cpp;
texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
internalFormat,
@@ -866,8 +866,8 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
break;
}
- t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT)
- | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT);
+ t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
+ | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
t->pp_txpitch = pitch_val;
t->pp_txpitch -= 32;
diff --git a/src/mesa/drivers/dri/r300/.gitignore b/src/mesa/drivers/dri/r300/.gitignore
index 3689a6a78e..2f9cd1a987 100644
--- a/src/mesa/drivers/dri/r300/.gitignore
+++ b/src/mesa/drivers/dri/r300/.gitignore
@@ -1,4 +1,15 @@
+radeon_bocs_wrapper.h
+radeon_bo_legacy.[ch]
radeon_chipset.h
+radeon_cmdbuf.h
+radeon_common.[ch]
+radeon_common_context.[ch]
+radeon_cs_legacy.[ch]
+radeon_dma.[ch]
+radeon_fbo.c
+radeon_lock.[ch]
+radeon_mipmap_tree.[ch]
radeon_screen.[ch]
-radeon_span.h
+radeon_span.[ch]
+radeon_texture.[ch]
server
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index bdb09624be..a77209074a 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1)
EGL_SOURCES = server/radeon_egl.c
endif
+ifeq ($(RADEON_LDFLAGS),)
+CS_SOURCES = radeon_cs_space_drm.c
+endif
+
COMMON_SOURCES = \
../../common/driverfuncs.c \
../common/mm.c \
@@ -59,7 +63,8 @@ DRIVER_SOURCES = \
r300_emit.c \
r300_swtcl.c \
$(RADEON_COMMON_SOURCES) \
- $(EGL_SOURCES)
+ $(EGL_SOURCES) \
+ $(CS_SOURCES)
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
@@ -100,7 +105,8 @@ COMMON_SYMLINKS = \
radeon_mipmap_tree.h \
radeon_texture.c \
radeon_texture.h \
- radeon_fbo.c
+ radeon_fbo.c \
+ $(CS_SOURCES)
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 0261a5b1d8..af535037d0 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -232,8 +232,8 @@ void r300_emit_scissor(GLcontext *ctx)
} else {
x1 = 0;
y1 = 0;
- x2 = rrb->width - 1;
- y2 = rrb->height - 1;
+ x2 = rrb->base.Width - 1;
+ y2 = rrb->base.Height - 1;
}
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
x1 += R300_SCISSORS_OFFSET;
@@ -264,11 +264,22 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
return;
}
+ if (RADEON_DEBUG & DEBUG_STATE)
+ fprintf(stderr,"rrb is %p %d %dx%d\n", rrb, offset, rrb->base.Width, rrb->base.Height);
cbpitch = (rrb->pitch / rrb->cpp);
if (rrb->cpp == 4)
cbpitch |= R300_COLOR_FORMAT_ARGB8888;
- else
+ else switch (rrb->base._ActualFormat) {
+ case GL_RGB5:
cbpitch |= R300_COLOR_FORMAT_RGB565;
+ break;
+ case GL_RGBA4:
+ cbpitch |= R300_COLOR_FORMAT_ARGB4444;
+ break;
+ case GL_RGB5_A1:
+ cbpitch |= R300_COLOR_FORMAT_ARGB1555;
+ break;
+ }
if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
cbpitch |= R300_COLOR_TILE_ENABLE;
@@ -289,14 +300,14 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
BEGIN_BATCH_NO_AUTOSTATE(3);
OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
OUT_BATCH(0);
- OUT_BATCH(((rrb->width - 1) << R300_SCISSORS_X_SHIFT) |
- ((rrb->height - 1) << R300_SCISSORS_Y_SHIFT));
+ OUT_BATCH(((rrb->base.Width - 1) << R300_SCISSORS_X_SHIFT) |
+ ((rrb->base.Height - 1) << R300_SCISSORS_Y_SHIFT));
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(16);
for (i = 0; i < 4; i++) {
OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
OUT_BATCH((0 << R300_CLIPRECT_X_SHIFT) | (0 << R300_CLIPRECT_Y_SHIFT));
- OUT_BATCH(((rrb->width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->height - 1) << R300_CLIPRECT_Y_SHIFT));
+ OUT_BATCH(((rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT));
}
OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
OUT_BATCH(0xAAAA);
@@ -308,15 +319,15 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) |
(R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT));
- OUT_BATCH(((rrb->width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) |
- ((rrb->height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT));
+ OUT_BATCH(((rrb->base.Width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) |
+ ((rrb->base.Height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT));
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(16);
for (i = 0; i < 4; i++) {
OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
OUT_BATCH((R300_SCISSORS_OFFSET << R300_CLIPRECT_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_CLIPRECT_Y_SHIFT));
- OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->width - 1) << R300_CLIPRECT_X_SHIFT) |
- ((R300_SCISSORS_OFFSET + rrb->height - 1) << R300_CLIPRECT_Y_SHIFT));
+ OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) |
+ ((R300_SCISSORS_OFFSET + rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT));
}
OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
OUT_BATCH(0xAAAA);
@@ -333,23 +344,33 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
BATCH_LOCALS(&r300->radeon);
struct radeon_renderbuffer *rrb;
uint32_t zbpitch;
+ uint32_t dw;
rrb = radeon_get_depthbuffer(&r300->radeon);
if (!rrb)
return;
zbpitch = (rrb->pitch / rrb->cpp);
- if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
- zbpitch |= R300_DEPTHMACROTILE_ENABLE;
- }
- if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
- zbpitch |= R300_DEPTHMICROTILE_TILED;
+ if (!r300->radeon.radeonScreen->kernel_mm) {
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
+ zbpitch |= R300_DEPTHMACROTILE_ENABLE;
+ }
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
+ zbpitch |= R300_DEPTHMICROTILE_TILED;
+ }
}
- BEGIN_BATCH_NO_AUTOSTATE(6);
+ dw = 6;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ dw += 2;
+ BEGIN_BATCH_NO_AUTOSTATE(dw);
OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, zbpitch);
+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1);
+ if (!r300->radeon.radeonScreen->kernel_mm)
+ OUT_BATCH(zbpitch);
+ else
+ OUT_BATCH_RELOC(cbpitch, rrb->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
}
@@ -503,7 +524,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1);
r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0;
r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL, 1);
- if (is_r500) {
+ if (is_r500 && !r300->radeon.radeonScreen->kernel_mm) {
ALLOC_STATE(vap_index_offset, always, 2, 0);
r300->hw.vap_index_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_VAP_INDEX_OFFSET, 1);
r300->hw.vap_index_offset.cmd[1] = 0;
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 394521a051..6f3aab986d 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -124,6 +124,7 @@ const struct dri_extension card_extensions[] = {
{"GL_EXT_texture_lod_bias", NULL},
{"GL_EXT_texture_mirror_clamp", NULL},
{"GL_EXT_texture_rectangle", NULL},
+ {"GL_EXT_texture_sRGB", NULL},
{"GL_EXT_vertex_array_bgra", NULL},
{"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions},
{"GL_ATI_texture_env_combine3", NULL},
@@ -269,10 +270,16 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
ctx->Const.MaxTextureLodBias = 16.0;
- if (screen->chip_family >= CHIP_FAMILY_RV515)
+ if (screen->chip_family >= CHIP_FAMILY_RV515) {
ctx->Const.MaxTextureLevels = 13;
- else
+ ctx->Const.MaxCubeTextureLevels = 13;
+ ctx->Const.MaxTextureRectSize = 4096;
+ }
+ else {
ctx->Const.MaxTextureLevels = 12;
+ ctx->Const.MaxCubeTextureLevels = 12;
+ ctx->Const.MaxTextureRectSize = 2048;
+ }
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
@@ -409,6 +416,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300InitConstValues(ctx, screen);
+ _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 026c33c67c..f7af7d4e57 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -405,12 +405,13 @@ struct r300_hw_state {
#undef TAG
struct r300_vertex_program {
+ struct gl_vertex_program *Base;
struct r300_vertex_program *next;
struct r300_vertex_program_key {
- GLuint InputsRead;
- GLuint OutputsWritten;
- GLuint OutputsAdded;
+ GLuint FpReads;
+ GLuint FogAttr;
+ GLuint WPosAttr;
} key;
struct r300_vertex_shader_hw_code {
@@ -426,13 +427,17 @@ struct r300_vertex_program {
int pos_end;
int num_temporaries; /* Number of temp vars used by program */
- int wpos_idx;
int inputs[VERT_ATTRIB_MAX];
int outputs[VERT_RESULT_MAX];
};
struct r300_vertex_program_cont {
- struct gl_vertex_program mesa_program; /* Must be first */
+ /* This is the unmodified vertex program mesa provided us with.
+ * We need to keep it unchanged because we may need to create another
+ * hw specific vertex program based on this.
+ */
+ struct gl_vertex_program mesa_program;
+ /* This is the list of hw specific vertex programs derived from mesa_program */
struct r300_vertex_program *progs;
};
@@ -546,7 +551,7 @@ struct r500_fragment_program_code {
* to render with that program.
*/
struct r300_fragment_program {
- struct gl_fragment_program Base;
+ struct gl_program *Base;
GLboolean translated;
GLboolean error;
@@ -559,6 +564,23 @@ struct r300_fragment_program {
GLboolean writes_depth;
GLuint optimization;
+
+ struct r300_fragment_program *next;
+
+ /* attribute that we are sending the WPOS in */
+ gl_frag_attrib wpos_attr;
+ /* attribute that we are sending the fog coordinate in */
+ gl_frag_attrib fog_attr;
+};
+
+struct r300_fragment_program_cont {
+ /* This is the unmodified fragment program mesa provided us with.
+ * We need to keep it unchanged because we may need to create another
+ * hw specific fragment program based on this.
+ */
+ struct gl_fragment_program Base;
+ /* This is the list of hw specific fragment programs derived from Base */
+ struct r300_fragment_program *progs;
};
struct r300_fragment_program_compiler {
@@ -633,6 +655,7 @@ struct r300_context {
struct r300_hw_state hw;
struct r300_vertex_program *selected_vp;
+ struct r300_fragment_program *selected_fp;
/* Vertex buffers
*/
@@ -664,11 +687,7 @@ extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
-extern void r300SelectVertexShader(r300ContextPtr r300);
extern void r300InitShaderFuncs(struct dd_function_table *functions);
-extern int r300VertexProgUpdateParams(GLcontext * ctx,
- struct r300_vertex_program_cont *vp,
- float *dst);
extern void r300InitShaderFunctions(r300ContextPtr r300);
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index cc5650fb7c..9769ff5399 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -195,6 +195,11 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st
}
GLfloat *dst_ptr, *tmp;
+
+ /* Convert value for first element only */
+ if (input->StrideB == 0)
+ count = 1;
+
tmp = dst_ptr = _mesa_malloc(sizeof(GLfloat) * input->Size * count);
switch (input->Type) {
@@ -228,13 +233,17 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st
type = GL_FLOAT;
r300_attr.free_needed = GL_TRUE;
r300_attr.data = tmp;
- r300_attr.stride = sizeof(GLfloat) * input->Size;
+ if (input->StrideB == 0) {
+ r300_attr.stride = 0;
+ } else {
+ r300_attr.stride = sizeof(GLfloat) * input->Size;
+ }
r300_attr.dwords = input->Size;
} else {
type = input->Type;
r300_attr.free_needed = GL_FALSE;
r300_attr.data = (GLvoid *)src_ptr;
- r300_attr.stride = stride;
+ r300_attr.stride = input->StrideB;
r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4;
}
@@ -332,7 +341,7 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar
{
int i, tmp;
- tmp = r300->selected_vp->key.InputsRead;
+ tmp = r300->selected_vp->Base->Base.InputsRead;
i = 0;
vbuf->num_attribs = 0;
while (tmp) {
@@ -417,12 +426,18 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
r300FixupIndexBuffer(ctx, ib, bo, &nr_bo);
+ /* ensure we have the cmd buf space in advance to cover
+ * the state + DMA AOS pointers */
+ rcommonEnsureCmdBufSpace(&r300->radeon,
+ r300->radeon.hw.max_state_size + (50*sizeof(int)),
+ __FUNCTION__);
+
r300SetVertexFormat(ctx, arrays, max_index + 1, bo, &nr_bo);
if (r300->fallback)
return GL_FALSE;
- r300SetupVAP(ctx, r300->selected_vp->key.InputsRead, r300->selected_vp->key.OutputsWritten);
+ r300SetupVAP(ctx, r300->selected_vp->Base->Base.InputsRead, r300->selected_vp->Base->Base.OutputsWritten);
r300UpdateShaderStates(r300);
@@ -442,8 +457,6 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
return GL_TRUE;
}
-/* TODO: rebase if number of indices in any of primitives is > 8192 for 32bit indices or 16384 for 16bit indices */
-
static void r300DrawPrims(GLcontext *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
@@ -452,12 +465,25 @@ static void r300DrawPrims(GLcontext *ctx,
GLuint min_index,
GLuint max_index)
{
+ struct split_limits limits;
GLboolean retval;
+ if (ib)
+ limits.max_verts = 0xffffffff;
+ else
+ limits.max_verts = 65535;
+
+ limits.max_indices = 65535;
+ limits.max_vb_size = 1024*1024;
+
if (min_index) {
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
return;
}
+ if ((ib && ib->count > 65535)) {
+ vbo_split_prims (ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims, &limits);
+ return;
+ }
/* Make an attempt at drawing */
retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index c3817721dc..feb3370f37 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -81,17 +81,17 @@ GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead)
return vic_1;
}
-GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
+GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes)
{
GLuint ret = 0;
if (vp_writes & (1 << VERT_RESULT_HPOS))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
- if (vp_writes & (1 << VERT_RESULT_COL0) && fp_reads & FRAG_BIT_COL0)
+ if (vp_writes & (1 << VERT_RESULT_COL0))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT;
- if (vp_writes & (1 << VERT_RESULT_COL1) && fp_reads & FRAG_BIT_COL1)
+ if (vp_writes & (1 << VERT_RESULT_COL1))
ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
/* Two sided lighting works only if all 4 colors are written */
@@ -105,26 +105,17 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
return ret;
}
-GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads)
+GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes)
{
GLuint i, ret = 0, first_free_texcoord = 0;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- if (vp_writes & (1 << (VERT_RESULT_TEX0 + i)) && fp_reads & FRAG_BIT_TEX(i)) {
+ if (vp_writes & (1 << (VERT_RESULT_TEX0 + i))) {
ret |= (4 << (3 * first_free_texcoord));
++first_free_texcoord;
}
}
- if (fp_reads & FRAG_BIT_WPOS) {
- ret |= (4 << (3 * first_free_texcoord));
- ++first_free_texcoord;
- }
-
- if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) {
- ret |= 4 << (3 * first_free_texcoord);
- }
-
if (first_free_texcoord > 8) {
fprintf(stderr, "\tout of free texcoords\n");
_mesa_exit(-1);
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 2fb8b82d3a..3f8c60ffae 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -225,7 +225,7 @@ extern void r300EmitCacheFlush(r300ContextPtr rmesa);
extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead);
extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead);
-extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads);
-extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads);
+extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes);
+extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
index abc8757ba1..f5c4c0f4a0 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
@@ -50,13 +50,6 @@
#include "radeon_program.h"
#include "radeon_program_alu.h"
-static void update_params(GLcontext *ctx, struct gl_fragment_program *fp)
-{
- /* Ask Mesa nicely to fill in ParameterValues for us */
- if (fp->Base.Parameters)
- _mesa_load_state_parameters(ctx, fp->Base.Parameters);
-}
-
static void nqssadce_init(struct nqssadce_state* s)
{
s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW;
@@ -74,10 +67,12 @@ static void nqssadce_init(struct nqssadce_state* s)
*/
static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
{
- GLuint InputsRead = compiler->fp->Base.Base.InputsRead;
+ GLuint InputsRead = compiler->fp->Base->InputsRead;
- if (!(InputsRead & FRAG_BIT_WPOS))
+ if (!(InputsRead & FRAG_BIT_WPOS)) {
+ compiler->fp->wpos_attr = FRAG_ATTRIB_MAX;
return;
+ }
static gl_state_index tokens[STATE_LENGTH] = {
STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
@@ -85,10 +80,23 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;
+
+ for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
+ {
+ if (!(InputsRead & (1 << i))) {
+ InputsRead &= ~(1 << FRAG_ATTRIB_WPOS);
+ InputsRead |= 1 << i;
+ compiler->fp->Base->InputsRead = InputsRead;
+ compiler->fp->wpos_attr = i;
+ break;
+ }
+ }
+
GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);
_mesa_insert_instructions(compiler->program, 0, 3);
fpi = compiler->program->Instructions;
+ i = 0;
/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;
@@ -99,7 +107,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
fpi[i].DstReg.CondMask = COND_TR;
fpi[i].SrcReg[0].File = PROGRAM_INPUT;
- fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
+ fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
i++;
@@ -111,7 +119,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
fpi[i].DstReg.CondMask = COND_TR;
fpi[i].SrcReg[0].File = PROGRAM_INPUT;
- fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
+ fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
@@ -154,6 +162,57 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
}
}
+
+/**
+ * Rewrite fragment.fogcoord to use a texture coordinate slot.
+ * Note that fogcoord is forced into an X001 pattern, and this enforcement
+ * is done here.
+ *
+ * See also the counterpart rewriting for vertex programs.
+ */
+static void rewriteFog(struct r300_fragment_program_compiler *compiler)
+{
+ struct r300_fragment_program *fp = compiler->fp;
+ GLuint InputsRead;
+ int i;
+
+ InputsRead = fp->Base->InputsRead;
+
+ if (!(InputsRead & FRAG_BIT_FOGC)) {
+ fp->fog_attr = FRAG_ATTRIB_MAX;
+ return;
+ }
+
+ for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
+ {
+ if (!(InputsRead & (1 << i))) {
+ InputsRead &= ~(1 << FRAG_ATTRIB_FOGC);
+ InputsRead |= 1 << i;
+ fp->Base->InputsRead = InputsRead;
+ fp->fog_attr = i;
+ break;
+ }
+ }
+
+ {
+ struct prog_instruction *inst;
+
+ inst = compiler->program->Instructions;
+ while (inst->Opcode != OPCODE_END) {
+ const int src_regs = _mesa_num_inst_src_regs(inst->Opcode);
+ for (i = 0; i < src_regs; ++i) {
+ if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) {
+ inst->SrcReg[i].Index = fp->fog_attr;
+ inst->SrcReg[i].Swizzle = combine_swizzles(
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE),
+ inst->SrcReg[i].Swizzle);
+ }
+ }
+ ++inst;
+ }
+ }
+}
+
static GLuint build_dtm(GLuint depthmode)
{
switch(depthmode) {
@@ -175,7 +234,7 @@ static GLuint build_func(GLuint comparefunc)
*/
static void build_state(
r300ContextPtr r300,
- struct r300_fragment_program *fp,
+ struct gl_fragment_program *fp,
struct r300_fragment_program_external_state *state)
{
int unit;
@@ -183,7 +242,7 @@ static void build_state(
_mesa_bzero(state, sizeof(*state));
for(unit = 0; unit < 16; ++unit) {
- if (fp->Base.Base.ShadowSamplers & (1 << unit)) {
+ if (fp->Base.ShadowSamplers & (1 << unit)) {
struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current;
state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode);
@@ -192,100 +251,149 @@ static void build_state(
}
}
-void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp)
+static void rewrite_depth_out(struct gl_program *prog)
{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp;
- struct r300_fragment_program_external_state state;
+ struct prog_instruction *inst;
- build_state(r300, r300_fp, &state);
- if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) {
- /* TODO: cache compiled programs */
- r300_fp->translated = GL_FALSE;
- _mesa_memcpy(&r300_fp->state, &state, sizeof(state));
- }
-
- if (!r300_fp->translated) {
- struct r300_fragment_program_compiler compiler;
+ for (inst = prog->Instructions; inst->Opcode != OPCODE_END; ++inst) {
+ if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != FRAG_RESULT_DEPTH)
+ continue;
- compiler.r300 = r300;
- compiler.fp = r300_fp;
- compiler.code = &r300_fp->code;
- compiler.program = _mesa_clone_program(ctx, &fp->Base);
+ if (inst->DstReg.WriteMask & WRITEMASK_Z) {
+ inst->DstReg.WriteMask = WRITEMASK_W;
+ } else {
+ inst->DstReg.WriteMask = 0;
+ continue;
+ }
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- fflush(stdout);
- _mesa_printf("Fragment Program: Initial program:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
+ switch (inst->Opcode) {
+ case OPCODE_FRC:
+ case OPCODE_MOV:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ break;
+ case OPCODE_ADD:
+ case OPCODE_MAX:
+ case OPCODE_MIN:
+ case OPCODE_MUL:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
+ break;
+ case OPCODE_CMP:
+ case OPCODE_MAD:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
+ inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
+ break;
+ default:
+ // Scalar instructions needn't be reswizzled
+ break;
}
+ }
+}
- insert_WPOS_trailer(&compiler);
+void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_fragment_program_compiler compiler;
+
+ compiler.r300 = r300;
+ compiler.fp = fp;
+ compiler.code = &fp->code;
+ compiler.program = fp->Base;
+
+ if (RADEON_DEBUG & DEBUG_PIXEL) {
+ fflush(stdout);
+ _mesa_printf("Fragment Program: Initial program:\n");
+ _mesa_print_program(compiler.program);
+ fflush(stdout);
+ }
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct radeon_program_transformation transformations[] = {
- { &r500_transform_TEX, &compiler },
- { &radeonTransformALU, 0 },
- { &radeonTransformDeriv, 0 },
- { &radeonTransformTrigScale, 0 }
- };
- radeonLocalTransform(ctx, compiler.program, 4, transformations);
- } else {
- struct radeon_program_transformation transformations[] = {
- { &r300_transform_TEX, &compiler },
- { &radeonTransformALU, 0 },
- { &radeonTransformTrigSimple, 0 }
- };
- radeonLocalTransform(ctx, compiler.program, 3, transformations);
- }
+ insert_WPOS_trailer(&compiler);
+
+ rewriteFog(&compiler);
+
+ rewrite_depth_out(compiler.program);
+
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ struct radeon_program_transformation transformations[] = {
+ { &r500_transform_TEX, &compiler },
+ { &radeonTransformALU, 0 },
+ { &radeonTransformDeriv, 0 },
+ { &radeonTransformTrigScale, 0 }
+ };
+ radeonLocalTransform(ctx, compiler.program, 4, transformations);
+ } else {
+ struct radeon_program_transformation transformations[] = {
+ { &r300_transform_TEX, &compiler },
+ { &radeonTransformALU, 0 },
+ { &radeonTransformTrigSimple, 0 }
+ };
+ radeonLocalTransform(ctx, compiler.program, 3, transformations);
+ }
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Fragment Program: After native rewrite:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
- }
+ if (RADEON_DEBUG & DEBUG_PIXEL) {
+ _mesa_printf("Fragment Program: After native rewrite:\n");
+ _mesa_print_program(compiler.program);
+ fflush(stdout);
+ }
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct radeon_nqssadce_descr nqssadce = {
- .Init = &nqssadce_init,
- .IsNativeSwizzle = &r500FPIsNativeSwizzle,
- .BuildSwizzle = &r500FPBuildSwizzle,
- .RewriteDepthOut = GL_TRUE
- };
- radeonNqssaDce(ctx, compiler.program, &nqssadce);
- } else {
- struct radeon_nqssadce_descr nqssadce = {
- .Init = &nqssadce_init,
- .IsNativeSwizzle = &r300FPIsNativeSwizzle,
- .BuildSwizzle = &r300FPBuildSwizzle,
- .RewriteDepthOut = GL_TRUE
- };
- radeonNqssaDce(ctx, compiler.program, &nqssadce);
- }
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadce_init,
+ .IsNativeSwizzle = &r500FPIsNativeSwizzle,
+ .BuildSwizzle = &r500FPBuildSwizzle
+ };
+ radeonNqssaDce(ctx, compiler.program, &nqssadce);
+ } else {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadce_init,
+ .IsNativeSwizzle = &r300FPIsNativeSwizzle,
+ .BuildSwizzle = &r300FPBuildSwizzle
+ };
+ radeonNqssaDce(ctx, compiler.program, &nqssadce);
+ }
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Compiler: after NqSSA-DCE:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
- }
+ if (RADEON_DEBUG & DEBUG_PIXEL) {
+ _mesa_printf("Compiler: after NqSSA-DCE:\n");
+ _mesa_print_program(compiler.program);
+ fflush(stdout);
+ }
- if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler))
- r300_fp->error = GL_TRUE;
+ if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler))
+ fp->error = GL_TRUE;
- /* Subtle: Rescue any parameters that have been added during transformations */
- _mesa_free_parameter_list(fp->Base.Parameters);
- fp->Base.Parameters = compiler.program->Parameters;
- compiler.program->Parameters = 0;
+ fp->translated = GL_TRUE;
- _mesa_reference_program(ctx, &compiler.program, NULL);
+ if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
+ r300->vtbl.FragmentProgramDump(&fp->code);
+}
- r300_fp->translated = GL_TRUE;
+struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_fragment_program_cont *fp_list;
+ struct r300_fragment_program *fp;
+ struct r300_fragment_program_external_state state;
- r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ fp_list = (struct r300_fragment_program_cont *)ctx->FragmentProgram._Current;
+ build_state(r300, ctx->FragmentProgram._Current, &state);
- if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
- r300->vtbl.FragmentProgramDump(&r300_fp->code);
+ fp = fp_list->progs;
+ while (fp) {
+ if (_mesa_memcmp(&fp->state, &state, sizeof(state)) == 0) {
+ return r300->selected_fp = fp;
+ }
+ fp = fp->next;
}
- update_params(ctx, fp);
+ fp = _mesa_calloc(sizeof(struct r300_fragment_program));
+
+ fp->state = state;
+ fp->translated = GL_FALSE;
+ fp->Base = _mesa_clone_program(ctx, &ctx->FragmentProgram._Current->Base);
+
+ fp->next = fp_list->progs;
+ fp_list->progs = fp;
+
+ return r300->selected_fp = fp;
}
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.h b/src/mesa/drivers/dri/r300/r300_fragprog_common.h
index 85ea86fecb..5e103ee408 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.h
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.h
@@ -30,6 +30,10 @@
#include "main/mtypes.h"
-extern void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp);
+#include "r300_context.h"
+
+extern void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp);
+
+struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 104079b4db..ddabd53992 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -68,11 +68,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void r300EmitClearState(GLcontext * ctx);
-static void r300UserClear(GLcontext *ctx, GLuint mask)
-{
- radeon_clear_tris(ctx, mask);
-}
-
static void r300ClearBuffer(r300ContextPtr r300, int flags,
struct radeon_renderbuffer *rrb,
struct radeon_renderbuffer *rrbd)
@@ -540,19 +535,50 @@ static void r300EmitClearState(GLcontext * ctx)
}
}
-static void r300KernelClear(GLcontext *ctx, GLuint flags)
+static int r300KernelClear(GLcontext *ctx, GLuint flags)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
struct radeon_framebuffer *rfb = dPriv->driverPrivate;
struct radeon_renderbuffer *rrb;
struct radeon_renderbuffer *rrbd;
- int bits = 0;
+ int bits = 0, ret;
/* Make sure it fits there. */
+ radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
+
+ if (flags & BUFFER_BIT_COLOR0) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ if (flags & BUFFER_BIT_FRONT_LEFT) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ if (flags & BUFFER_BIT_BACK_LEFT) {
+ rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+ if (rrbd) {
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+ rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs);
+ if (ret)
+ return -1;
+
rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
if (flags || bits)
r300EmitClearState(ctx);
+
rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
if (rrbd && (flags & BUFFER_BIT_DEPTH))
bits |= CLEARBUFFER_DEPTH;
@@ -582,6 +608,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags)
r300ClearBuffer(r300, bits, NULL, rrbd);
COMMIT_BATCH();
+ return 0;
}
/**
@@ -593,7 +620,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
GLbitfield swrast_mask = 0, tri_mask = 0;
- int i;
+ int i, ret;
struct gl_framebuffer *fb = ctx->DrawBuffer;
if (RADEON_DEBUG & DEBUG_IOCTL)
@@ -614,6 +641,8 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
if (colorMask == ~0)
tri_mask |= (mask & BUFFER_BITS_COLOR);
+ else
+ tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
/* HW stencil */
@@ -643,12 +672,18 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask;
+ ret = 0;
if (tri_mask) {
if (r300->radeon.radeonScreen->kernel_mm)
- r300UserClear(ctx, tri_mask);
- else
- r300KernelClear(ctx, tri_mask);
+ radeonUserClear(ctx, tri_mask);
+ else {
+ /* if kernel clear fails due to size restraints fallback */
+ ret = r300KernelClear(ctx, tri_mask);
+ if (ret < 0)
+ swrast_mask |= tri_mask;
+ }
}
+
if (swrast_mask) {
if (RADEON_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n",
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index c22616b95f..357c600af9 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -1467,6 +1467,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_TX_FORMAT_3D (1 << 25)
# define R300_TX_FORMAT_CUBIC_MAP (2 << 25)
+# define R300_TX_FORMAT_GAMMA (1 << 21)
+
/* gap */
/* Floating point formats */
/* Note - hardware supports both 16 and 32 bit floating point */
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 1356305a21..08d67b73ed 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -243,7 +243,6 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
offset);
-
if (!rmesa->radeon.radeonScreen->kernel_mm) {
BEGIN_BATCH(sz+2+(nr * 2));
OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1);
@@ -360,31 +359,15 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
if (type < 0 || num_verts <= 0)
return;
- /* Make space for at least 64 dwords.
+ /* Make space for at least 128 dwords.
* This is supposed to ensure that we can get all rendering
* commands into a single command buffer.
*/
rcommonEnsureCmdBufSpace(&rmesa->radeon, 128, __FUNCTION__);
if (rmesa->ind_buf.ptr) {
- if (num_verts > 65535) {
- /* not implemented yet */
- WARN_ONCE("Too many elts\n");
- return;
- }
- /* Note: The following is incorrect, but it's the best I can do
- * without a major refactoring of how DMA memory is handled.
- * The problem: Ensuring that both vertex arrays *and* index
- * arrays are at the right position, and then ensuring that
- * the LOAD_VBPNTR, DRAW_INDX and INDX_BUFFER packets are emitted
- * at once.
- *
- * So why is the following incorrect? Well, it seems like
- * allocating the index array might actually evict the vertex
- * arrays. *sigh*
- */
r300EmitElts(ctx, num_verts);
- r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start);
+ r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, 0);
if (rmesa->radeon.radeonScreen->kernel_mm) {
BEGIN_BATCH_NO_AUTOSTATE(2);
OUT_BATCH_REGSEQ(R300_VAP_VF_MAX_VTX_INDX, 1);
@@ -469,7 +452,8 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
if (mode) {
if ((fallback_warn & bit) == 0) {
- _mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit));
+ if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ _mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit));
fallback_warn |= bit;
}
rmesa->fallback |= bit;
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index 0133b83796..62228a3786 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -32,22 +32,45 @@
#include "r300_context.h"
#include "r300_fragprog_common.h"
+static void freeFragProgCache(GLcontext *ctx, struct r300_fragment_program_cont *cache)
+{
+ struct r300_fragment_program *tmp, *fp = cache->progs;
+
+ while (fp) {
+ tmp = fp->next;
+ _mesa_reference_program(ctx, &fp->Base, NULL);
+ _mesa_free(fp);
+ fp = tmp;
+ }
+}
+
+static void freeVertProgCache(GLcontext *ctx, struct r300_vertex_program_cont *cache)
+{
+ struct r300_vertex_program *tmp, *vp = cache->progs;
+
+ while (vp) {
+ tmp = vp->next;
+ _mesa_reference_vertprog(ctx, &vp->Base, NULL);
+ _mesa_free(vp);
+ vp = tmp;
+ }
+}
+
static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
GLuint id)
{
struct r300_vertex_program_cont *vp;
- struct r300_fragment_program *fp;
+ struct r300_fragment_program_cont *fp;
switch (target) {
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
vp = CALLOC_STRUCT(r300_vertex_program_cont);
- return _mesa_init_vertex_program(ctx, &vp->mesa_program,
- target, id);
+ return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
- fp = CALLOC_STRUCT(r300_fragment_program);
+ fp = CALLOC_STRUCT(r300_fragment_program_cont);
return _mesa_init_fragment_program(ctx, &fp->Base, target, id);
default:
@@ -59,21 +82,35 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target,
static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
+ struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog;
+ struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog;
+
+ switch (prog->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ freeVertProgCache(ctx, vp);
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ freeFragProgCache(ctx, fp);
+ break;
+ }
+
_mesa_delete_program(ctx, prog);
}
static void
r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
- struct r300_vertex_program_cont *vp = (void *)prog;
- struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog;
+ struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog;
+ struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog;
switch (target) {
case GL_VERTEX_PROGRAM_ARB:
+ freeVertProgCache(ctx, vp);
vp->progs = NULL;
break;
case GL_FRAGMENT_PROGRAM_ARB:
- r300_fp->translated = GL_FALSE;
+ freeFragProgCache(ctx, fp);
+ fp->progs = NULL;
break;
}
@@ -85,13 +122,18 @@ static GLboolean
r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct r300_fragment_program *fp = (struct r300_fragment_program *)prog;
+ struct r300_fragment_program *fp = r300SelectFragmentShader(ctx);
if (!fp->translated)
- r300TranslateFragmentShader(ctx, &fp->Base);
+ r300TranslateFragmentShader(ctx, fp);
return !fp->error;
- } else
- return GL_TRUE;
+ } else {
+ struct r300_vertex_program *vp = r300SelectVertexShader(ctx);
+ if (!vp->translated)
+ r300TranslateVertexShader(vp);
+
+ return !vp->error;
+ }
}
void r300InitShaderFuncs(struct dd_function_table *functions)
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index c0eda977db..12fbf281d9 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -434,6 +434,10 @@ static void r300UpdateCulling(GLcontext * ctx)
break;
}
+ /* Winding is inverted when rendering to FBO */
+ if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+ val ^= R300_FRONT_FACE_CW;
+
R300_STATECHANGE(r300, cul);
r300->hw.cul.cmd[R300_CUL_CULL] = val;
}
@@ -452,9 +456,9 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
{
- struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
- return (fp && fp->writes_depth);
+ return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth;
}
static void r300SetEarlyZState(GLcontext * ctx)
@@ -1093,24 +1097,25 @@ r300FetchStateParameter(GLcontext * ctx,
* Update R300's own internal state parameters.
* For now just STATE_R300_WINDOW_DIMENSION
*/
-void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
+static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
{
- struct r300_fragment_program *fp;
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct gl_program_parameter_list *paramList;
GLuint i;
if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
return;
- fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;
- if (!fp)
+ if (!ctx->FragmentProgram._Current || !rmesa->selected_fp)
return;
- paramList = fp->Base.Base.Parameters;
+ paramList = rmesa->selected_fp->Base->Parameters;
if (!paramList)
return;
+ _mesa_load_state_parameters(ctx, paramList);
+
for (i = 0; i < paramList->NumParameters; i++) {
if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
r300FetchStateParameter(ctx,
@@ -1225,8 +1230,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
- struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
- struct r300_fragment_program_code *code = &fp->code.r300;
+ struct r300_fragment_program_code *code = &r300->selected_fp->code.r300;
R300_STATECHANGE(r300, fpt);
@@ -1266,9 +1270,9 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
- struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
- struct r500_fragment_program_code *code = &fp->code.r500;
+ struct r500_fragment_program_code *code = &r300->selected_fp->code.r500;
/* find all the texture instructions and relocate the texture units */
for (i = 0; i < code->inst_end + 1; i++) {
@@ -1316,8 +1320,6 @@ static void r300SetupTextures(GLcontext * ctx)
int hw_tmu = 0;
int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */
int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
- struct r300_fragment_program *fp = (struct r300_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
R300_STATECHANGE(r300, txe);
R300_STATECHANGE(r300, tex.filter);
@@ -1420,7 +1422,7 @@ static void r300SetupTextures(GLcontext * ctx)
cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
- if (fp->Base.UsesKill && last_hw_tmu < 0) {
+ if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
// The KILL operation requires the first texture unit
// to be enabled.
r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
@@ -1458,11 +1460,11 @@ static void r300SetupRSUnit(GLcontext * ctx)
hw_tcl_on = r300->options.hw_tcl_enabled;
if (hw_tcl_on)
- OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
+ OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
else
RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
- InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+ InputsRead = r300->selected_fp->Base->InputsRead;
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
@@ -1521,29 +1523,6 @@ static void r300SetupRSUnit(GLcontext * ctx)
++fp_reg;
}
- if (InputsRead & FRAG_BIT_WPOS) {
- r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count);
- r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
- InputsRead &= ~FRAG_BIT_WPOS;
- rs_tex_count += 4;
- ++tex_ip;
- ++fp_reg;
- }
-
- if (InputsRead & FRAG_BIT_FOGC) {
- if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
- r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0);
- r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count);
- r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
- InputsRead &= ~FRAG_BIT_FOGC;
- rs_tex_count += 4;
- ++tex_ip;
- ++fp_reg;
- } else {
- WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
- }
- }
-
/* Setup default color if no color or tex was set */
if (rs_tex_count == 0 && col_ip == 0) {
r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0);
@@ -1575,11 +1554,11 @@ static void r500SetupRSUnit(GLcontext * ctx)
hw_tcl_on = r300->options.hw_tcl_enabled;
if (hw_tcl_on)
- OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
+ OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
else
RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
- InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+ InputsRead = r300->selected_fp->Base->InputsRead;
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
@@ -1642,36 +1621,6 @@ static void r500SetupRSUnit(GLcontext * ctx)
++fp_reg;
}
- if (InputsRead & FRAG_BIT_WPOS) {
- r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) |
- ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) |
- ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) |
- ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT);
-
- r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
- InputsRead &= ~FRAG_BIT_WPOS;
- rs_tex_count += 4;
- ++tex_ip;
- ++fp_reg;
- }
-
- if (InputsRead & FRAG_BIT_FOGC) {
- if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
- r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) |
- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
- (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
- (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT);
-
- r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
- InputsRead &= ~FRAG_BIT_FOGC;
- rs_tex_count += 4;
- ++tex_ip;
- ++fp_reg;
- } else {
- WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
- }
- }
-
/* Setup default color if no color or tex was set */
if (rs_tex_count == 0 && col_ip == 0) {
r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0);
@@ -2036,43 +1985,51 @@ static void r300ResetHwState(r300ContextPtr r300)
void r300UpdateShaders(r300ContextPtr rmesa)
{
- GLcontext *ctx;
- struct r300_fragment_program *fp;
- int i;
-
- ctx = rmesa->radeon.glCtx;
- fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+ GLcontext *ctx = rmesa->radeon.glCtx;
/* should only happenen once, just after context is created */
/* TODO: shouldn't we fallback to sw here? */
- if (!fp) {
+ if (!ctx->FragmentProgram._Current) {
_mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
return;
}
- if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) {
- for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
- rmesa->temp_attrib[i] =
- TNL_CONTEXT(ctx)->vb.AttribPtr[i];
- TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
- &rmesa->dummy_attrib[i];
- }
+ {
+ struct r300_fragment_program *fp;
- _tnl_UpdateFixedFunctionProgram(ctx);
+ fp = r300SelectFragmentShader(ctx);
+ if (!fp->translated)
+ r300TranslateFragmentShader(ctx, fp);
- for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
- TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
- rmesa->temp_attrib[i];
- }
-
- r300SelectVertexShader(rmesa);
- r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error);
+ r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error);
}
- if (!fp->translated || rmesa->radeon.NewGLState)
- r300TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
+ if (rmesa->options.hw_tcl_enabled) {
+ struct r300_vertex_program *vp;
+
+ if (rmesa->radeon.NewGLState) {
+ int i;
+ for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+ rmesa->temp_attrib[i] =
+ TNL_CONTEXT(ctx)->vb.AttribPtr[i];
+ TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
+ &rmesa->dummy_attrib[i];
+ }
+
+ _tnl_UpdateFixedFunctionProgram(ctx);
+
+ for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+ TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
+ rmesa->temp_attrib[i];
+ }
+ }
+
+ vp = r300SelectVertexShader(ctx);
+ if (!vp->translated)
+ r300TranslateVertexShader(vp);
- r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error);
+ r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error);
+ }
r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
rmesa->radeon.NewGLState = 0;
@@ -2102,7 +2059,7 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx,
static void r300SetupPixelShader(GLcontext *ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+ struct r300_fragment_program *fp = rmesa->selected_fp;
struct r300_fragment_program_code *code;
int i, k;
@@ -2148,8 +2105,7 @@ static void r300SetupPixelShader(GLcontext *ctx)
R300_STATECHANGE(rmesa, fpp);
rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4);
for (i = 0; i < code->const_nr; i++) {
- const GLfloat *constant = get_fragmentprogram_constant(ctx,
- &fp->Base.Base, code->constant[i]);
+ const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]);
@@ -2174,7 +2130,7 @@ static void r300SetupPixelShader(GLcontext *ctx)
static void r500SetupPixelShader(GLcontext *ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+ struct r300_fragment_program *fp = rmesa->selected_fp;
int i;
struct r500_fragment_program_code *code;
@@ -2210,8 +2166,7 @@ static void r500SetupPixelShader(GLcontext *ctx)
R300_STATECHANGE(rmesa, r500fp_const);
for (i = 0; i < code->const_nr; i++) {
- const GLfloat *constant = get_fragmentprogram_constant(ctx,
- &fp->Base.Base, code->constant[i]);
+ const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]);
@@ -2274,20 +2229,17 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
- rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
- rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
+ rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
+ rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten);
}
void r300UpdateShaderStates(r300ContextPtr rmesa)
{
GLcontext *ctx;
ctx = rmesa->radeon.glCtx;
- struct r300_fragment_program *r300_fp;
-
- r300_fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
/* should only happenen once, just after context is created */
- if (!r300_fp)
+ if (!ctx->FragmentProgram._Current)
return;
r300SetEarlyZState(ctx);
@@ -2323,8 +2275,6 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
R300_STATECHANGE(r300, cb);
}
- r300UpdateStateParameters(ctx, new_state);
-
r300->radeon.NewGLState |= new_state;
}
diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h
index 2328289420..d46bf9f179 100644
--- a/src/mesa/drivers/dri/r300/r300_state.h
+++ b/src/mesa/drivers/dri/r300/r300_state.h
@@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
void r300UpdateViewportOffset (GLcontext * ctx);
void r300UpdateDrawBuffer (GLcontext * ctx);
-void r300UpdateStateParameters (GLcontext * ctx, GLuint new_state);
void r300UpdateShaders (r300ContextPtr rmesa);
void r300UpdateShaderStates (r300ContextPtr rmesa);
void r300InitState (r300ContextPtr r300);
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
index ce4179208e..56ed519cf4 100644
--- a/src/mesa/drivers/dri/r300/r300_swtcl.c
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
@@ -76,7 +76,7 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
GLuint InputsRead = 0;
GLuint OutputsWritten = 0;
int num_attrs = 0;
- GLuint fp_reads = ctx->FragmentProgram._Current->Base.InputsRead;
+ GLuint fp_reads = rmesa->selected_fp->Base->InputsRead;
struct vertex_attribute *attrs = rmesa->vbuf.attribs;
rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
@@ -150,6 +150,22 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0);
}
+ if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
+ int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
+
+ VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
+ VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
+ RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
+ }
+
+ if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
+ int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
+
+ VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
+ VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
+ RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
+ }
+
/**
* Sending only one texcoord component may lead to lock up,
* so for all textures always output 4 texcoord components to RS.
@@ -192,31 +208,9 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
}
}
- /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
- if (fp_reads & FRAG_BIT_WPOS) {
- if (first_free_tex >= ctx->Const.MaxTextureUnits) {
- fprintf(stderr, "\tout of free texcoords to write w pos\n");
- _mesa_exit(-1);
- }
-
- InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
- OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
- EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
- ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW, 0);
- ++first_free_tex;
- }
-
- if (fp_reads & FRAG_BIT_FOGC) {
- if (first_free_tex >= ctx->Const.MaxTextureUnits) {
- fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
- _mesa_exit(-1);
- }
-
- InputsRead |= 1 << VERT_ATTRIB_FOG;
- OutputsWritten |= 1 << VERT_RESULT_FOGC;
- GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
- EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
- ADD_ATTR(VERT_ATTRIB_FOG, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0);
+ if (first_free_tex >= ctx->Const.MaxTextureUnits) {
+ fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
+ _mesa_exit(-1);
}
R300_NEWPRIM(rmesa);
@@ -497,11 +491,13 @@ void r300RenderStart(GLcontext *ctx)
r300ContextPtr rmesa = R300_CONTEXT( ctx );
r300ChooseRenderState(ctx);
+
+ r300UpdateShaders(rmesa);
+
r300PrepareVertices(ctx);
r300ValidateBuffers(ctx);
- r300UpdateShaders(rmesa);
r300UpdateShaderStates(rmesa);
r300EmitCacheFlush(rmesa);
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 6d6a90aa88..6f489ace7b 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -119,6 +119,10 @@ static const struct tx_table {
_ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
_ASSIGN(S8_Z24, R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8)),
_ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
+ /* EXT_texture_sRGB */
+ _ASSIGN(SRGBA8, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA),
+ _ASSIGN(SLA8, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA),
+ _ASSIGN(SL8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA),
/* *INDENT-ON* */
};
@@ -277,21 +281,24 @@ GLboolean r300ValidateBuffers(GLcontext * ctx)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
int i;
+ int ret;
- radeon_validate_reset_bos(&rmesa->radeon);
+ radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
}
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -307,17 +314,19 @@ GLboolean r300ValidateBuffers(GLcontext * ctx)
}
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
if (t->image_override && t->bo)
- radeon_validate_bo(&rmesa->radeon, t->bo,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
-
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
else if (t->mt->bo)
- radeon_validate_bo(&rmesa->radeon, t->mt->bo,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- if (rmesa->radeon.dma.current)
- radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
- return radeon_revalidate_bos(ctx);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ return GL_TRUE;
}
void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
@@ -433,7 +442,7 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
rImage->mt = NULL;
}
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
- rb->width, rb->height, 1, 0, rb->cpp);
+ rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
texImage->RowStride = rb->pitch / rb->cpp;
texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
internalFormat,
@@ -469,15 +478,15 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
break;
}
pitch_val--;
- t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
- ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
+ t->pp_txsize = ((rb->base.Width - 1) << R300_TX_WIDTHMASK_SHIFT) |
+ ((rb->base.Height - 1) << R300_TX_HEIGHTMASK_SHIFT);
t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
t->pp_txpitch |= pitch_val;
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- if (rb->width > 2048)
+ if (rb->base.Width > 2048)
t->pp_txpitch |= R500_TXWIDTH_BIT11;
- if (rb->height > 2048)
+ if (rb->base.Height > 2048)
t->pp_txpitch |= R500_TXHEIGHT_BIT11;
}
t->validated = GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index c41a8fdd62..de32013032 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -32,12 +32,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/macros.h"
#include "main/enums.h"
#include "shader/program.h"
+#include "shader/programopt.h"
#include "shader/prog_instruction.h"
+#include "shader/prog_optimize.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#include "tnl/tnl.h"
+#include "radeon_nqssadce.h"
#include "r300_context.h"
#include "r300_state.h"
@@ -71,15 +74,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
} while (0)
-int r300VertexProgUpdateParams(GLcontext * ctx,
- struct r300_vertex_program_cont *vp, float *dst)
+static int r300VertexProgUpdateParams(GLcontext * ctx, struct gl_vertex_program *vp, float *dst)
{
int pi;
- struct gl_vertex_program *mesa_vp = &vp->mesa_program;
float *dst_o = dst;
struct gl_program_parameter_list *paramList;
- if (mesa_vp->IsNVProgram) {
+ if (vp->IsNVProgram) {
_mesa_load_tracked_matrices(ctx);
for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) {
@@ -91,16 +92,18 @@ int r300VertexProgUpdateParams(GLcontext * ctx,
return dst - dst_o;
}
- assert(mesa_vp->Base.Parameters);
- _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters);
+ if (!vp->Base.Parameters)
+ return 0;
- if (mesa_vp->Base.Parameters->NumParameters * 4 >
+ _mesa_load_state_parameters(ctx, vp->Base.Parameters);
+
+ if (vp->Base.Parameters->NumParameters * 4 >
VSF_MAX_FRAGMENT_LENGTH) {
fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__);
_mesa_exit(-1);
}
- paramList = mesa_vp->Base.Parameters;
+ paramList = vp->Base.Parameters;
for (pi = 0; pi < paramList->NumParameters; pi++) {
switch (paramList->Parameters[pi].Type) {
case PROGRAM_STATE_VAR:
@@ -933,10 +936,14 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
{
int i;
int cur_reg;
+ GLuint OutputsWritten, InputsRead;
+
+ OutputsWritten = vp->Base->Base.OutputsWritten;
+ InputsRead = vp->Base->Base.InputsRead;
cur_reg = -1;
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
- if (vp->key.InputsRead & (1 << i))
+ if (InputsRead & (1 << i))
vp->inputs[i] = ++cur_reg;
else
vp->inputs[i] = -1;
@@ -946,13 +953,13 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
for (i = 0; i < VERT_RESULT_MAX; i++)
vp->outputs[i] = -1;
- assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
+ assert(OutputsWritten & (1 << VERT_RESULT_HPOS));
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) {
+ if (OutputsWritten & (1 << VERT_RESULT_HPOS)) {
vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
}
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
+ if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
}
@@ -962,46 +969,46 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
* pretend it does by skipping output index reg so the colors
* get written into appropriate output vectors.
*/
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) {
+ if (OutputsWritten & (1 << VERT_RESULT_COL0)) {
vp->outputs[VERT_RESULT_COL0] = cur_reg++;
- } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) ||
- vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) {
+ } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) ||
+ OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) {
+ if (OutputsWritten & (1 << VERT_RESULT_COL1)) {
vp->outputs[VERT_RESULT_COL1] = cur_reg++;
- } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) ||
- vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) {
+ } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) ||
+ OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) {
+ if (OutputsWritten & (1 << VERT_RESULT_BFC0)) {
vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
- } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) {
+ } else if (OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) {
+ if (OutputsWritten & (1 << VERT_RESULT_BFC1)) {
vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
- } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) {
+ } else if (OutputsWritten & (1 << VERT_RESULT_BFC0)) {
cur_reg++;
}
for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) {
- if (vp->key.OutputsWritten & (1 << i)) {
+ if (OutputsWritten & (1 << i)) {
vp->outputs[i] = cur_reg++;
}
}
- if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) {
+ if (OutputsWritten & (1 << VERT_RESULT_FOGC)) {
vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
}
}
-static void r300TranslateVertexShader(struct r300_vertex_program *vp,
- struct prog_instruction *vpi)
+void r300TranslateVertexShader(struct r300_vertex_program *vp)
{
+ struct prog_instruction *vpi = vp->Base->Base.Instructions;
int i;
GLuint *inst;
unsigned long num_operands;
@@ -1191,313 +1198,463 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
}
}
-/* DP4 version seems to trigger some hw peculiarity */
-//#define PREFER_DP4
+static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id)
+{
+ struct prog_instruction *vpi;
+
+ _mesa_insert_instructions(prog, prog->NumInstructions - 1, 2);
+
+ vpi = &prog->Instructions[prog->NumInstructions - 3];
+
+ vpi->Opcode = OPCODE_MOV;
+
+ vpi->DstReg.File = PROGRAM_OUTPUT;
+ vpi->DstReg.Index = VERT_RESULT_HPOS;
+ vpi->DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi->DstReg.CondMask = COND_TR;
+
+ vpi->SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi->SrcReg[0].Index = temp_index;
+ vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ ++vpi;
+
+ vpi->Opcode = OPCODE_MOV;
-static void position_invariant(struct gl_program *prog)
+ vpi->DstReg.File = PROGRAM_OUTPUT;
+ vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
+ vpi->DstReg.WriteMask = WRITEMASK_XYZW;
+ vpi->DstReg.CondMask = COND_TR;
+
+ vpi->SrcReg[0].File = PROGRAM_TEMPORARY;
+ vpi->SrcReg[0].Index = temp_index;
+ vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ ++vpi;
+
+ vpi->Opcode = OPCODE_END;
+}
+
+static void pos_as_texcoord(struct gl_program *prog, int tex_id)
{
struct prog_instruction *vpi;
- struct gl_program_parameter_list *paramList;
- int i;
+ GLuint tempregi = prog->NumTemporaries;
- gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 };
+ prog->NumTemporaries++;
- /* tokens[4] = matrix modifier */
-#ifdef PREFER_DP4
- tokens[4] = 0; /* not transposed or inverted */
-#else
- tokens[4] = STATE_MATRIX_TRANSPOSE;
-#endif
- paramList = prog->Parameters;
-
- vpi = _mesa_alloc_instructions(prog->NumInstructions + 4);
- _mesa_init_instructions(vpi, prog->NumInstructions + 4);
-
- for (i = 0; i < 4; i++) {
- GLint idx;
- tokens[2] = tokens[3] = i; /* matrix row[i]..row[i] */
- idx = _mesa_add_state_reference(paramList, tokens);
-#ifdef PREFER_DP4
- vpi[i].Opcode = OPCODE_DP4;
- vpi[i].StringPos = 0;
- vpi[i].Data = 0;
-
- vpi[i].DstReg.File = PROGRAM_OUTPUT;
- vpi[i].DstReg.Index = VERT_RESULT_HPOS;
- vpi[i].DstReg.WriteMask = 1 << i;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = idx;
- vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- vpi[i].SrcReg[1].File = PROGRAM_INPUT;
- vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
- vpi[i].SrcReg[1].Swizzle = SWIZZLE_XYZW;
-#else
- if (i == 0)
- vpi[i].Opcode = OPCODE_MUL;
- else
- vpi[i].Opcode = OPCODE_MAD;
+ for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) {
+ if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS) {
+ vpi->DstReg.File = PROGRAM_TEMPORARY;
+ vpi->DstReg.Index = tempregi;
+ }
+ }
- vpi[i].Data = 0;
+ insert_wpos(prog, tempregi, tex_id);
- if (i == 3)
- vpi[i].DstReg.File = PROGRAM_OUTPUT;
- else
- vpi[i].DstReg.File = PROGRAM_TEMPORARY;
- vpi[i].DstReg.Index = 0;
- vpi[i].DstReg.WriteMask = 0xf;
- vpi[i].DstReg.CondMask = COND_TR;
-
- vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
- vpi[i].SrcReg[0].Index = idx;
- vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- vpi[i].SrcReg[1].File = PROGRAM_INPUT;
- vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
- vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
-
- if (i > 0) {
- vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
- vpi[i].SrcReg[2].Index = 0;
- vpi[i].SrcReg[2].Swizzle = SWIZZLE_XYZW;
+ prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
+}
+
+/**
+ * The fogcoord attribute is special in that only the first component
+ * is relevant, and the remaining components are always fixed (when read
+ * from by the fragment program) to yield an X001 pattern.
+ *
+ * We need to enforce this either in the vertex program or in the fragment
+ * program, and this code chooses not to enforce it in the vertex program.
+ * This is slightly cheaper, as long as the fragment program does not use
+ * weird swizzles.
+ *
+ * And it seems that usually, weird swizzles are not used, so...
+ *
+ * See also the counterpart rewriting for fragment programs.
+ */
+static void fog_as_texcoord(struct gl_program *prog, int tex_id)
+{
+ struct prog_instruction *vpi;
+
+ vpi = prog->Instructions;
+ while (vpi->Opcode != OPCODE_END) {
+ if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) {
+ vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
+ vpi->DstReg.WriteMask = WRITEMASK_X;
}
-#endif
+
+ ++vpi;
}
- _mesa_copy_instructions(&vpi[i], prog->Instructions,
- prog->NumInstructions);
+ prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC);
+ prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
+}
- free(prog->Instructions);
+static int translateABS(struct gl_program *prog, int pos)
+{
+ struct prog_instruction *inst;
- prog->Instructions = vpi;
+ inst = &prog->Instructions[pos];
- prog->NumInstructions += 4;
- vpi = &prog->Instructions[prog->NumInstructions - 1];
+ inst->Opcode = OPCODE_MAX;
+ inst->SrcReg[1] = inst->SrcReg[0];
+ inst->SrcReg[1].Negate ^= NEGATE_XYZW;
- assert(vpi->Opcode == OPCODE_END);
+ return 0;
}
-static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog,
- GLuint temp_index)
+static int translateDP3(struct gl_program *prog, int pos)
{
- struct prog_instruction *vpi;
- struct prog_instruction *vpi_insert;
- int i = 0;
+ struct prog_instruction *inst;
- vpi = _mesa_alloc_instructions(prog->NumInstructions + 2);
- _mesa_init_instructions(vpi, prog->NumInstructions + 2);
- /* all but END */
- _mesa_copy_instructions(vpi, prog->Instructions,
- prog->NumInstructions - 1);
- /* END */
- _mesa_copy_instructions(&vpi[prog->NumInstructions + 1],
- &prog->Instructions[prog->NumInstructions - 1],
- 1);
- vpi_insert = &vpi[prog->NumInstructions - 1];
+ inst = &prog->Instructions[pos];
- vpi_insert[i].Opcode = OPCODE_MOV;
+ inst->Opcode = OPCODE_DP4;
+ inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
- vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
- vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
- vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
- vpi_insert[i].DstReg.CondMask = COND_TR;
+ return 0;
+}
+
+static int translateDPH(struct gl_program *prog, int pos)
+{
+ struct prog_instruction *inst;
+
+ inst = &prog->Instructions[pos];
+
+ inst->Opcode = OPCODE_DP4;
+ inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
- vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
- vpi_insert[i].SrcReg[0].Index = temp_index;
- vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
- i++;
+ return 0;
+}
- vpi_insert[i].Opcode = OPCODE_MOV;
+static int translateFLR(struct gl_program *prog, int pos)
+{
+ struct prog_instruction *inst;
+ struct prog_dst_register dst;
+ int tmp_idx;
- vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
- vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx;
- vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
- vpi_insert[i].DstReg.CondMask = COND_TR;
+ tmp_idx = prog->NumTemporaries++;
- vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
- vpi_insert[i].SrcReg[0].Index = temp_index;
- vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
- i++;
+ _mesa_insert_instructions(prog, pos + 1, 1);
- free(prog->Instructions);
+ inst = &prog->Instructions[pos];
+ dst = inst->DstReg;
- prog->Instructions = vpi;
+ inst->Opcode = OPCODE_FRC;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = tmp_idx;
+ ++inst;
- prog->NumInstructions += i;
- vpi = &prog->Instructions[prog->NumInstructions - 1];
+ inst->Opcode = OPCODE_ADD;
+ inst->DstReg = dst;
+ inst->SrcReg[0] = (inst-1)->SrcReg[0];
+ inst->SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[1].Index = tmp_idx;
+ inst->SrcReg[1].Negate = NEGATE_XYZW;
- assert(vpi->Opcode == OPCODE_END);
+ return 1;
}
-static void pos_as_texcoord(struct r300_vertex_program *vp,
- struct gl_program *prog)
+static int translateSUB(struct gl_program *prog, int pos)
{
- struct prog_instruction *vpi;
- GLuint tempregi = prog->NumTemporaries;
- /* should do something else if no temps left... */
- prog->NumTemporaries++;
+ struct prog_instruction *inst;
- for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) {
- if (vpi->DstReg.File == PROGRAM_OUTPUT
- && vpi->DstReg.Index == VERT_RESULT_HPOS) {
- vpi->DstReg.File = PROGRAM_TEMPORARY;
- vpi->DstReg.Index = tempregi;
- }
- }
- insert_wpos(vp, prog, tempregi);
+ inst = &prog->Instructions[pos];
+
+ inst->Opcode = OPCODE_ADD;
+ inst->SrcReg[1].Negate ^= NEGATE_XYZW;
+
+ return 0;
}
-static struct r300_vertex_program *build_program(struct r300_vertex_program_key
- *wanted_key, struct gl_vertex_program
- *mesa_vp, GLint wpos_idx)
+static int translateSWZ(struct gl_program *prog, int pos)
{
- struct r300_vertex_program *vp;
+ prog->Instructions[pos].Opcode = OPCODE_MOV;
- vp = _mesa_calloc(sizeof(*vp));
- _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
- vp->wpos_idx = wpos_idx;
+ return 0;
+}
- if (mesa_vp->IsPositionInvariant) {
- position_invariant(&mesa_vp->Base);
- }
+static int translateXPD(struct gl_program *prog, int pos)
+{
+ struct prog_instruction *inst;
+ int tmp_idx;
+
+ tmp_idx = prog->NumTemporaries++;
+
+ _mesa_insert_instructions(prog, pos + 1, 1);
+
+ inst = &prog->Instructions[pos];
+
+ *(inst+1) = *inst;
+
+ inst->Opcode = OPCODE_MUL;
+ inst->DstReg.File = PROGRAM_TEMPORARY;
+ inst->DstReg.Index = tmp_idx;
+ inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W);
+ inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W);
+ ++inst;
+
+ inst->Opcode = OPCODE_MAD;
+ inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W);
+ inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W);
+ inst->SrcReg[1].Negate ^= NEGATE_XYZW;
+ inst->SrcReg[2].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[2].Index = tmp_idx;
+
+ return 1;
+}
+
+static void translateInsts(struct gl_program *prog)
+{
+ struct prog_instruction *inst;
+ int i;
+
+ for (i = 0; i < prog->NumInstructions; ++i) {
+ inst = &prog->Instructions[i];
- if (wpos_idx > -1) {
- pos_as_texcoord(vp, &mesa_vp->Base);
+ switch (inst->Opcode) {
+ case OPCODE_ABS:
+ i += translateABS(prog, i);
+ break;
+ case OPCODE_DP3:
+ i += translateDP3(prog, i);
+ break;
+ case OPCODE_DPH:
+ i += translateDPH(prog, i);
+ break;
+ case OPCODE_FLR:
+ i += translateFLR(prog, i);
+ break;
+ case OPCODE_SUB:
+ i += translateSUB(prog, i);
+ break;
+ case OPCODE_SWZ:
+ i += translateSWZ(prog, i);
+ break;
+ case OPCODE_XPD:
+ i += translateXPD(prog, i);
+ break;
+ default:
+ break;
+ }
}
+}
- if (RADEON_DEBUG & DEBUG_VERTS) {
- fprintf(stderr, "Vertex program after native rewrite:\n");
- _mesa_print_program(&mesa_vp->Base);
- fflush(stdout);
+#define ADD_OUTPUT(fp_attr, vp_result) \
+ do { \
+ if ((FpReads & (1 << (fp_attr))) && !(prog->OutputsWritten & (1 << (vp_result)))) { \
+ OutputsAdded |= 1 << (vp_result); \
+ count++; \
+ } \
+ } while (0)
+
+static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ GLuint OutputsAdded, FpReads;
+ int i, count;
+
+ OutputsAdded = 0;
+ count = 0;
+ FpReads = r300->selected_fp->Base->InputsRead;
+
+ ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0);
+ ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1);
+
+ for (i = 0; i < 7; ++i) {
+ ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i);
}
/* Some outputs may be artificially added, to match the inputs of the fragment program.
* Issue 16 of vertex program spec says that all vertex attributes that are unwritten by
* vertex program are undefined, so just use MOV [vertex_result], CONST[0]
*/
- {
- int i, count = 0;
+ if (count > 0) {
+ struct prog_instruction *inst;
+
+ _mesa_insert_instructions(prog, prog->NumInstructions - 1, count);
+ inst = &prog->Instructions[prog->NumInstructions - 1 - count];
+
for (i = 0; i < VERT_RESULT_MAX; ++i) {
- if (vp->key.OutputsAdded & (1 << i)) {
- ++count;
+ if (OutputsAdded & (1 << i)) {
+ inst->Opcode = OPCODE_MOV;
+
+ inst->DstReg.File = PROGRAM_OUTPUT;
+ inst->DstReg.Index = i;
+ inst->DstReg.WriteMask = WRITEMASK_XYZW;
+ inst->DstReg.CondMask = COND_TR;
+
+ inst->SrcReg[0].File = PROGRAM_CONSTANT;
+ inst->SrcReg[0].Index = 0;
+ inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ ++inst;
}
}
- if (count > 0) {
- struct prog_instruction *inst;
+ prog->OutputsWritten |= OutputsAdded;
+ }
+}
- _mesa_insert_instructions(&mesa_vp->Base, mesa_vp->Base.NumInstructions - 1, count);
- inst = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions - 1 - count];
+#undef ADD_OUTPUT
- for (i = 0; i < VERT_RESULT_MAX; ++i) {
- if (vp->key.OutputsAdded & (1 << i)) {
- inst->Opcode = OPCODE_MOV;
+static void nqssadceInit(struct nqssadce_state* s)
+{
+ r300ContextPtr r300 = R300_CONTEXT(s->Ctx);
+ GLuint fp_reads;
- inst->DstReg.File = PROGRAM_OUTPUT;
- inst->DstReg.Index = i;
- inst->DstReg.WriteMask = WRITEMASK_XYZW;
- inst->DstReg.CondMask = COND_TR;
+ fp_reads = r300->selected_fp->Base->InputsRead;
+ {
+ if (fp_reads & FRAG_BIT_COL0) {
+ s->Outputs[VERT_RESULT_COL0].Sourced = WRITEMASK_XYZW;
+ s->Outputs[VERT_RESULT_BFC0].Sourced = WRITEMASK_XYZW;
+ }
- inst->SrcReg[0].File = PROGRAM_CONSTANT;
- inst->SrcReg[0].Index = 0;
- inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ if (fp_reads & FRAG_BIT_COL1) {
+ s->Outputs[VERT_RESULT_COL1].Sourced = WRITEMASK_XYZW;
+ s->Outputs[VERT_RESULT_BFC1].Sourced = WRITEMASK_XYZW;
+ }
+ }
- ++inst;
- }
+ {
+ int i;
+ for (i = 0; i < 8; ++i) {
+ if (fp_reads & FRAG_BIT_TEX(i)) {
+ s->Outputs[VERT_RESULT_TEX0 + i].Sourced = WRITEMASK_XYZW;
}
}
}
- assert(mesa_vp->Base.NumInstructions);
- vp->num_temporaries = mesa_vp->Base.NumTemporaries;
- r300TranslateVertexShader(vp, mesa_vp->Base.Instructions);
-
- return vp;
+ s->Outputs[VERT_RESULT_HPOS].Sourced = WRITEMASK_XYZW;
+ if (s->Program->OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ s->Outputs[VERT_RESULT_PSIZ].Sourced = WRITEMASK_X;
}
-static void add_outputs(struct r300_vertex_program_key *key, GLint vert)
+static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
{
- if (key->OutputsWritten & (1 << vert))
- return;
+ (void) opcode;
+ (void) reg;
- key->OutputsWritten |= 1 << vert;
- key->OutputsAdded |= 1 << vert;
+ return GL_TRUE;
}
-void r300SelectVertexShader(r300ContextPtr r300)
+static struct r300_vertex_program *build_program(GLcontext *ctx,
+ struct r300_vertex_program_key *wanted_key,
+ const struct gl_vertex_program *mesa_vp)
{
- GLcontext *ctx = ctx = r300->radeon.glCtx;
- GLuint InputsRead;
- struct r300_vertex_program_key wanted_key = { 0 };
- GLint i;
- struct r300_vertex_program_cont *vpc;
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_vertex_program *vp;
- GLint wpos_idx;
+ struct gl_program *prog;
- vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
- wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
- wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
- InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
-
- wpos_idx = -1;
- if (InputsRead & FRAG_BIT_WPOS) {
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
- if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
- break;
+ vp = _mesa_calloc(sizeof(*vp));
+ vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base);
+ _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
- if (i == ctx->Const.MaxTextureUnits) {
- fprintf(stderr, "\tno free texcoord found\n");
- _mesa_exit(-1);
- }
+ prog = &vp->Base->Base;
+
+ if (RADEON_DEBUG & DEBUG_VERTS) {
+ fprintf(stderr, "Initial vertex program:\n");
+ _mesa_print_program(prog);
+ fflush(stdout);
+ }
- wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
- wpos_idx = i;
+ if (vp->Base->IsPositionInvariant) {
+ _mesa_insert_mvp_code(ctx, vp->Base);
}
- if (vpc->mesa_program.IsPositionInvariant) {
- wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS);
- wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS);
- } else {
- add_outputs(&wanted_key, VERT_RESULT_HPOS);
+ if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
+ pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0);
}
- if (InputsRead & FRAG_BIT_COL0) {
- add_outputs(&wanted_key, VERT_RESULT_COL0);
+ if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
+ fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0);
}
- if (InputsRead & FRAG_BIT_COL1) {
- add_outputs(&wanted_key, VERT_RESULT_COL1);
+ addArtificialOutputs(ctx, prog);
+
+ translateInsts(prog);
+
+ if (RADEON_DEBUG & DEBUG_VERTS) {
+ fprintf(stderr, "Vertex program after native rewrite:\n");
+ _mesa_print_program(prog);
+ fflush(stdout);
}
- if (InputsRead & FRAG_BIT_FOGC) {
- add_outputs(&wanted_key, VERT_RESULT_FOGC);
+ {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadceInit,
+ .IsNativeSwizzle = &swizzleIsNative,
+ .BuildSwizzle = NULL
+ };
+ radeonNqssaDce(ctx, prog, &nqssadce);
+
+ /* We need this step for reusing temporary registers */
+ _mesa_optimize_program(ctx, prog);
+
+ if (RADEON_DEBUG & DEBUG_VERTS) {
+ fprintf(stderr, "Vertex program after NQSSADCE:\n");
+ _mesa_print_program(prog);
+ fflush(stdout);
+ }
}
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- if (InputsRead & (FRAG_BIT_TEX0 << i)) {
- add_outputs(&wanted_key, VERT_RESULT_TEX0 + i);
+ assert(prog->NumInstructions);
+ {
+ struct prog_instruction *inst;
+ int max, i, tmp;
+
+ inst = prog->Instructions;
+ max = -1;
+ while (inst->Opcode != OPCODE_END) {
+ tmp = _mesa_num_inst_src_regs(inst->Opcode);
+ for (i = 0; i < tmp; ++i) {
+ if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) {
+ if ((int) inst->SrcReg[i].Index > max) {
+ max = inst->SrcReg[i].Index;
+ }
+ }
+ }
+
+ if (_mesa_num_inst_dst_regs(inst->Opcode)) {
+ if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ if ((int) inst->DstReg.Index > max) {
+ max = inst->DstReg.Index;
+ }
+ }
+ }
+ ++inst;
}
+
+ /* We actually want highest index of used temporary register,
+ * not the number of temporaries used.
+ * These values aren't always the same.
+ */
+ vp->num_temporaries = max + 1;
}
- for (vp = vpc->progs; vp; vp = vp->next)
+ return vp;
+}
+
+struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_vertex_program_key wanted_key = { 0 };
+ struct r300_vertex_program_cont *vpc;
+ struct r300_vertex_program *vp;
+
+ vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+ wanted_key.FpReads = r300->selected_fp->Base->InputsRead;
+ wanted_key.FogAttr = r300->selected_fp->fog_attr;
+ wanted_key.WPosAttr = r300->selected_fp->wpos_attr;
+
+ for (vp = vpc->progs; vp; vp = vp->next) {
if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key))
== 0) {
- r300->selected_vp = vp;
- return;
+ return r300->selected_vp = vp;
}
-
- if (RADEON_DEBUG & DEBUG_VERTS) {
- fprintf(stderr, "Initial vertex program:\n");
- _mesa_print_program(&vpc->mesa_program.Base);
- fflush(stdout);
}
- vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
+ vp = build_program(ctx, &wanted_key, &vpc->mesa_program);
vp->next = vpc->progs;
vpc->progs = vp;
- r300->selected_vp = vp;
+
+ return r300->selected_vp = vp;
}
#define bump_vpu_count(ptr, new_count) do { \
@@ -1544,25 +1701,22 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
struct r300_vertex_program *prog = rmesa->selected_vp;
int inst_count = 0;
int param_count = 0;
-
+
/* Reset state, in case we don't use something */
((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
-
+
R300_STATECHANGE(rmesa, vpp);
- param_count = r300VertexProgUpdateParams(ctx,
- (struct r300_vertex_program_cont *)
- ctx->VertexProgram._Current,
- (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
+ param_count = r300VertexProgUpdateParams(ctx, prog->Base, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
param_count /= 4;
r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code));
inst_count = (prog->hw_code.length / 4) - 1;
- r300VapCntl(rmesa, _mesa_bitcount(prog->key.InputsRead),
- _mesa_bitcount(prog->key.OutputsWritten), prog->num_temporaries);
+ r300VapCntl(rmesa, _mesa_bitcount(prog->Base->Base.InputsRead),
+ _mesa_bitcount(prog->Base->Base.OutputsWritten), prog->num_temporaries);
R300_STATECHANGE(rmesa, pvs);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h
index b552e3fb1b..2dab11c337 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.h
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.h
@@ -34,4 +34,8 @@
void r300SetupVertexProgram(r300ContextPtr rmesa);
+struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx);
+
+void r300TranslateVertexShader(struct r300_vertex_program *vp);
+
#endif
diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.c b/src/mesa/drivers/dri/r300/radeon_nqssadce.c
index 4a2e1cba40..840c9733b1 100644
--- a/src/mesa/drivers/dri/r300/radeon_nqssadce.c
+++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.c
@@ -46,6 +46,7 @@ static struct register_state *get_reg_state(struct nqssadce_state* s, GLuint fil
switch(file) {
case PROGRAM_TEMPORARY: return &s->Temps[index];
case PROGRAM_OUTPUT: return &s->Outputs[index];
+ case PROGRAM_ADDRESS: return &s->Address;
default: return 0;
}
}
@@ -56,7 +57,7 @@ static struct register_state *get_reg_state(struct nqssadce_state* s, GLuint fil
*
* @note Works correctly only for X, Y, Z, W swizzles, not for constant swizzles.
*/
-static struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg)
+struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg)
{
struct prog_src_register tmp = srcreg;
int i;
@@ -114,47 +115,19 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s,
deswz_source = sourced;
}
- struct register_state *regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index);
+ struct register_state *regstate;
+
+ if (inst->SrcReg[src].RelAddr)
+ regstate = get_reg_state(s, PROGRAM_ADDRESS, 0);
+ else
+ regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index);
+
if (regstate)
regstate->Sourced |= deswz_source & 0xf;
return inst;
}
-
-static void rewrite_depth_out(struct prog_instruction *inst)
-{
- if (inst->DstReg.WriteMask & WRITEMASK_Z) {
- inst->DstReg.WriteMask = WRITEMASK_W;
- } else {
- inst->DstReg.WriteMask = 0;
- return;
- }
-
- switch (inst->Opcode) {
- case OPCODE_FRC:
- case OPCODE_MOV:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- break;
- case OPCODE_ADD:
- case OPCODE_MAX:
- case OPCODE_MIN:
- case OPCODE_MUL:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
- break;
- case OPCODE_CMP:
- case OPCODE_MAD:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
- inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
- break;
- default:
- // Scalar instructions needn't be reswizzled
- break;
- }
-}
-
static void unalias_srcregs(struct prog_instruction *inst, GLuint oldindex, GLuint newindex)
{
int nsrc = _mesa_num_inst_src_regs(inst->Opcode);
@@ -189,11 +162,6 @@ static void process_instruction(struct nqssadce_state* s)
return;
if (inst->Opcode != OPCODE_KIL) {
- if (s->Descr->RewriteDepthOut) {
- if (inst->DstReg.File == PROGRAM_OUTPUT && inst->DstReg.Index == FRAG_RESULT_DEPTH)
- rewrite_depth_out(inst);
- }
-
struct register_state *regstate = get_reg_state(s, inst->DstReg.File, inst->DstReg.Index);
if (!regstate) {
_mesa_problem(s->Ctx, "NqssaDce: bad destination register (%i[%i])\n",
@@ -217,6 +185,7 @@ static void process_instruction(struct nqssadce_state* s)
* might change the instruction stream under us, so we have
* to be careful with the inst pointer. */
switch (inst->Opcode) {
+ case OPCODE_ARL:
case OPCODE_DDX:
case OPCODE_DDY:
case OPCODE_FRC:
@@ -227,6 +196,8 @@ static void process_instruction(struct nqssadce_state* s)
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_MUL:
+ case OPCODE_SGE:
+ case OPCODE_SLT:
inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask);
inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask);
break;
@@ -258,12 +229,51 @@ static void process_instruction(struct nqssadce_state* s)
case OPCODE_TXP:
inst = track_used_srcreg(s, inst, 0, 0xf);
break;
+ case OPCODE_DST:
+ inst = track_used_srcreg(s, inst, 0, 0x6);
+ inst = track_used_srcreg(s, inst, 1, 0xa);
+ break;
+ case OPCODE_EXP:
+ case OPCODE_LOG:
+ case OPCODE_POW:
+ inst = track_used_srcreg(s, inst, 0, 0x3);
+ break;
+ case OPCODE_LIT:
+ inst = track_used_srcreg(s, inst, 0, 0xb);
+ break;
default:
_mesa_problem(s->Ctx, "NqssaDce: Unknown opcode %d\n", inst->Opcode);
return;
}
}
+static void calculateInputsOutputs(struct gl_program *p)
+{
+ struct prog_instruction *inst;
+ GLuint InputsRead, OutputsWritten;
+
+ inst = p->Instructions;
+ InputsRead = 0;
+ OutputsWritten = 0;
+ while (inst->Opcode != OPCODE_END)
+ {
+ int i, num_src_regs;
+
+ num_src_regs = _mesa_num_inst_src_regs(inst->Opcode);
+ for (i = 0; i < num_src_regs; ++i) {
+ if (inst->SrcReg[i].File == PROGRAM_INPUT)
+ InputsRead |= 1 << inst->SrcReg[i].Index;
+ }
+
+ if (inst->DstReg.File == PROGRAM_OUTPUT)
+ OutputsWritten |= 1 << inst->DstReg.Index;
+
+ ++inst;
+ }
+
+ p->InputsRead = InputsRead;
+ p->OutputsWritten = OutputsWritten;
+}
void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr)
{
@@ -280,4 +290,6 @@ void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce
s.IP--;
process_instruction(&s);
}
+
+ calculateInputsOutputs(p);
}
diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.h b/src/mesa/drivers/dri/r300/radeon_nqssadce.h
index a4f94abcb6..8626f21c25 100644
--- a/src/mesa/drivers/dri/r300/radeon_nqssadce.h
+++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.h
@@ -58,6 +58,7 @@ struct nqssadce_state {
*/
struct register_state Temps[MAX_PROGRAM_TEMPS];
struct register_state Outputs[VERT_RESULT_MAX];
+ struct register_state Address;
};
@@ -83,14 +84,10 @@ struct radeon_nqssadce_descr {
*/
void (*BuildSwizzle)(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src);
- /**
- * Rewrite instructions that write to DEPR.z to write to DEPR.w
- * instead (rewriting is done *before* the WriteMask test).
- */
- GLboolean RewriteDepthOut;
void *Data;
};
void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr);
+struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg);
#endif /* __RADEON_PROGRAM_NQSSADCE_H_ */
diff --git a/src/mesa/drivers/dri/r300/radeon_program.h b/src/mesa/drivers/dri/r300/radeon_program.h
index b411f69bc8..88474d43a2 100644
--- a/src/mesa/drivers/dri/r300/radeon_program.h
+++ b/src/mesa/drivers/dri/r300/radeon_program.h
@@ -52,6 +52,38 @@ enum {
#define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO)
#define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
+static inline GLuint get_swz(GLuint swz, GLuint idx)
+{
+ if (idx & 0x4)
+ return idx;
+ return GET_SWZ(swz, idx);
+}
+
+static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, GLuint swz_z, GLuint swz_w)
+{
+ GLuint ret = 0;
+
+ ret |= get_swz(src, swz_x);
+ ret |= get_swz(src, swz_y) << 3;
+ ret |= get_swz(src, swz_z) << 6;
+ ret |= get_swz(src, swz_w) << 9;
+
+ return ret;
+}
+
+static inline GLuint combine_swizzles(GLuint src, GLuint swz)
+{
+ GLuint ret = 0;
+
+ ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_X));
+ ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Y)) << 3;
+ ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Z)) << 6;
+ ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_W)) << 9;
+
+ return ret;
+}
+
+
/**
* Transformation context that is passed to local transformations.
*
diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c
index 906d36e522..d6fb474cf2 100644
--- a/src/mesa/drivers/dri/r300/radeon_program_pair.c
+++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c
@@ -870,7 +870,7 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
_mesa_bzero(&s, sizeof(s));
s.Ctx = ctx;
- s.Program = program;
+ s.Program = _mesa_clone_program(ctx, program);
s.Handler = handler;
s.UserData = userdata;
s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE;
@@ -904,6 +904,8 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
_mesa_free(s.ValuePool);
_mesa_free(s.ReaderPool);
+ _mesa_reference_program(ctx, &s.Program, NULL);
+
return !s.Error;
}
diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c
index 7f25cb1868..ed51e428e9 100644
--- a/src/mesa/drivers/dri/r600/r600_emit.c
+++ b/src/mesa/drivers/dri/r600/r600_emit.c
@@ -98,13 +98,12 @@ shader_again_alloc:
goto shader_again_alloc;
}
- radeon_validate_bo(radeonctx, pbo, RADEON_GEM_DOMAIN_GTT, 0);
+ if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs,
+ pbo,
+ RADEON_GEM_DOMAIN_GTT, 0))
+ fprintf(stderr,"failure to revalidate BOs - badness\n");
+
- if (radeon_revalidate_bos(radeonctx->glCtx) == GL_FALSE)
- {
- fprintf(stderr,"failure to revalidate BOs - badness\n");
- }
-
radeon_bo_map(pbo, 1);
radeon_bo_ref(pbo);
diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c
index 5a249d4f14..f56cc970d4 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -541,23 +541,26 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
context_t *rmesa = R700_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
int i;
+ int ret;
- radeon_validate_reset_bos(&rmesa->radeon);
+ radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
}
-
+
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
radeonTexObj *t;
@@ -571,17 +574,19 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
}
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
if (t->image_override && t->bo)
- radeon_validate_bo(&rmesa->radeon, t->bo,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
-
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
else if (t->mt->bo)
- radeon_validate_bo(&rmesa->radeon, t->mt->bo,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- if (rmesa->radeon.dma.current)
- radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
- return radeon_revalidate_bos(ctx);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ return GL_TRUE;
}
void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
@@ -714,7 +719,7 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
rImage->mt = NULL;
}
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
- rb->width, rb->height, 1, 0, rb->cpp);
+ rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
texImage->RowStride = rb->pitch / rb->cpp;
texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
internalFormat,
@@ -779,9 +784,9 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, PITCH_shift, PITCH_mask);
- SETfield(t->SQ_TEX_RESOURCE0, rb->width - 1,
+ SETfield(t->SQ_TEX_RESOURCE0, rb->base.Width - 1,
TEX_WIDTH_shift, TEX_WIDTH_mask);
- SETfield(t->SQ_TEX_RESOURCE1, rb->height - 1,
+ SETfield(t->SQ_TEX_RESOURCE1, rb->base.Height - 1,
TEX_HEIGHT_shift, TEX_HEIGHT_mask);
t->validated = GL_TRUE;
diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c
index 7696795676..e484845cc6 100644
--- a/src/mesa/drivers/dri/r600/r700_clear.c
+++ b/src/mesa/drivers/dri/r600/r700_clear.c
@@ -44,11 +44,6 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask)
return GL_FALSE;
}
-static void r700UserClear(GLcontext *ctx, GLuint mask)
-{
- radeon_clear_tris(ctx, mask);
-}
-
#define R600_NEWPRIM( rmesa ) \
do { \
if ( rmesa->radeon.dma.flush ) \
@@ -80,6 +75,8 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
if (colorMask == ~0)
tri_mask |= (mask & BUFFER_BITS_COLOR);
+ else
+ tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
/* HW stencil */
@@ -109,8 +106,10 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask;
- if (tri_mask)
- r700UserClear(ctx, tri_mask);
+ if (tri_mask) {
+ radeonUserClear(ctx, tri_mask);
+ }
+
if (swrast_mask) {
if (RADEON_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n",
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index ba409ba813..b59ad68f44 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -10,6 +10,10 @@ LIBNAME = radeon_dri.so
MINIGLX_SOURCES = server/radeon_dri.c
+ifeq ($(RADEON_LDFLAGS),)
+CS_SOURCES = radeon_cs_space_drm.c
+endif
+
RADEON_COMMON_SOURCES = \
radeon_texture.c \
radeon_common_context.c \
@@ -38,7 +42,8 @@ DRIVER_SOURCES = \
C_SOURCES = \
$(COMMON_SOURCES) \
- $(DRIVER_SOURCES)
+ $(DRIVER_SOURCES) \
+ $(CS_SOURCES)
DRIVER_DEFINES = -DRADEON_COMMON=0
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
index 5720957c78..655b52a669 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
@@ -82,6 +82,7 @@ struct radeon_bo_funcs {
int (*bo_map)(struct radeon_bo *bo, int write);
int (*bo_unmap)(struct radeon_bo *bo);
int (*bo_wait)(struct radeon_bo *bo);
+ int (*bo_is_static)(struct radeon_bo *bo);
};
struct radeon_bo_manager {
@@ -185,6 +186,7 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo,
{
return bo->bom->funcs->bo_wait(bo);
}
+
#ifdef RADEON_DEBUG_BO
#define radeon_bo_open(bom, h, s, a, d, f, u)\
_radeon_bo_open(bom, h, s, a, d, f, u, __FILE__, __FUNCTION__, __LINE__)
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index 94c2d97825..992eb4611b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -562,12 +562,21 @@ static int bo_unmap(struct radeon_bo *bo)
return 0;
}
+
+static int bo_is_static(struct radeon_bo *bo)
+{
+ struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+ return bo_legacy->static_bo;
+}
+
static struct radeon_bo_funcs bo_legacy_funcs = {
bo_open,
bo_ref,
bo_unref,
bo_map,
- bo_unmap
+ bo_unmap,
+ NULL,
+ bo_is_static,
};
static int bo_vram_validate(struct radeon_bo *bo,
@@ -895,9 +904,3 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
return bo->size;
}
-int radeon_legacy_bo_is_static(struct radeon_bo *bo)
-{
- struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
- return bo_legacy->static_bo;
-}
-
diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
index 6f1a0b4535..e0c70dd9a1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
@@ -1,21 +1,6 @@
#ifndef RADEON_CS_WRAPPER_H
#define RADEON_CS_WRAPPER_H
-#ifndef RADEON_PARAM_DEVICE_ID
-#define RADEON_PARAM_DEVICE_ID 16
-#endif
-
-#ifndef RADEON_INFO_DEVICE_ID
-#define RADEON_INFO_DEVICE_ID 0
-#endif
-#ifndef RADEON_INFO_NUM_GB_PIPES
-#define RADEON_INFO_NUM_GB_PIPES 0
-#endif
-
-#ifndef DRM_RADEON_INFO
-#define DRM_RADEON_INFO 0x1
-#endif
-
#ifdef HAVE_LIBDRM_RADEON
#include "radeon_bo.h"
@@ -50,6 +35,21 @@ struct drm_radeon_info {
};
#endif
+#ifndef RADEON_PARAM_DEVICE_ID
+#define RADEON_PARAM_DEVICE_ID 16
+#endif
+
+#ifndef RADEON_INFO_DEVICE_ID
+#define RADEON_INFO_DEVICE_ID 0
+#endif
+#ifndef RADEON_INFO_NUM_GB_PIPES
+#define RADEON_INFO_NUM_GB_PIPES 0
+#endif
+
+#ifndef DRM_RADEON_INFO
+#define DRM_RADEON_INFO 0x1
+#endif
+
static inline uint32_t radeon_gem_name_bo(struct radeon_bo *dummy)
{
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 59ae7814aa..dde615a4d9 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/glheader.h"
#include "main/imports.h"
#include "main/context.h"
+#include "main/arrayobj.h"
#include "main/api_arrayelt.h"
#include "main/enums.h"
#include "main/colormac.h"
@@ -221,7 +222,7 @@ void radeonUpdateScissor( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- if ( radeon_get_drawable(rmesa) ) {
+ if ( !ctx->DrawBuffer->Name ) {
__DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
int x = ctx->Scissor.X;
@@ -233,9 +234,14 @@ void radeonUpdateScissor( GLcontext *ctx )
rmesa->state.scissor.rect.y1 = y + dPriv->y;
rmesa->state.scissor.rect.x2 = w + dPriv->x + 1;
rmesa->state.scissor.rect.y2 = h + dPriv->y + 1;
-
- radeonRecalcScissorRects( rmesa );
+ } else {
+ rmesa->state.scissor.rect.x1 = ctx->Scissor.X;
+ rmesa->state.scissor.rect.y1 = ctx->Scissor.Y;
+ rmesa->state.scissor.rect.x2 = ctx->Scissor.X + ctx->Scissor.Width;
+ rmesa->state.scissor.rect.y2 = ctx->Scissor.Y + ctx->Scissor.Height;
}
+
+ radeonRecalcScissorRects( rmesa );
}
/* =============================================================
@@ -739,7 +745,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
}
if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
- rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
+ rrbStencil = radeon_renderbuffer(fb->_StencilBuffer->Wrapped);
if (rrbStencil && rrbStencil->bo) {
radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
/* need to re-compute stencil hw state */
@@ -771,9 +777,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
(ctx->Depth.Test && fb->Visual.depthBits > 0));
/* Need to update the derived ctx->Stencil._Enabled first */
- _mesa_update_stencil(ctx);
ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
- (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));
+ (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
} else {
ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
}
@@ -844,6 +849,17 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
void radeonReadBuffer( GLcontext *ctx, GLenum mode )
{
+ if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
+ struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
+ const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading;
+ rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
+ || (mode == GL_FRONT);
+
+ if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) {
+ radeon_update_renderbuffers(rmesa->dri.context,
+ rmesa->dri.context->driReadablePriv);
+ }
+ }
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
if (ctx->ReadBuffer == ctx->DrawBuffer) {
/* This will update FBO completeness status.
@@ -887,9 +903,14 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he
if (!driContext->driScreenPriv->dri2.enabled)
return;
- radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
- if (driContext->driDrawablePriv != driContext->driReadablePriv)
- radeon_update_renderbuffers(driContext, driContext->driReadablePriv);
+ if (!radeon->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
+ if (radeon->is_front_buffer_rendering) {
+ radeonFlush(ctx);
+ }
+ radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
+ if (driContext->driDrawablePriv != driContext->driReadablePriv)
+ radeon_update_renderbuffers(driContext, driContext->driReadablePriv);
+ }
old_viewport = ctx->Driver.Viewport;
ctx->Driver.Viewport = NULL;
@@ -989,52 +1010,17 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty)
COMMIT_BATCH();
}
-GLboolean radeon_revalidate_bos(GLcontext *ctx)
+static GLboolean radeon_revalidate_bos(GLcontext *ctx)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
- int flushed = 0;
int ret;
-again:
- ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count);
- if (ret == RADEON_CS_SPACE_OP_TO_BIG)
+
+ ret = radeon_cs_space_check(radeon->cmdbuf.cs);
+ if (ret == RADEON_CS_SPACE_FLUSH)
return GL_FALSE;
- if (ret == RADEON_CS_SPACE_FLUSH) {
- if (ctx->Driver.Flush)
- ctx->Driver.Flush(ctx); /* +r6/r7 */
- if (flushed)
- return GL_FALSE;
- flushed = 1;
- goto again;
- }
return GL_TRUE;
}
-void radeon_validate_reset_bos(radeonContextPtr radeon)
-{
- int i;
-
- for (i = 0; i < radeon->state.validated_bo_count; i++) {
- radeon_bo_unref(radeon->state.bos[i].bo);
- radeon->state.bos[i].bo = NULL;
- radeon->state.bos[i].read_domains = 0;
- radeon->state.bos[i].write_domain = 0;
- radeon->state.bos[i].new_accounted = 0;
- }
- radeon->state.validated_bo_count = 0;
-}
-
-void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
-{
- radeon_bo_ref(bo);
- radeon->state.bos[radeon->state.validated_bo_count].bo = bo;
- radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains;
- radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain;
- radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0;
- radeon->state.validated_bo_count++;
-
- assert(radeon->state.validated_bo_count < RADEON_MAX_BOS);
-}
-
void radeonEmitState(radeonContextPtr radeon)
{
if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
@@ -1249,6 +1235,9 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa)
assert(rmesa->cmdbuf.cs != NULL);
rmesa->cmdbuf.size = size;
+ radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
+ (void (*)(void *))radeonFlush, rmesa->glCtx);
+
if (!rmesa->radeonScreen->kernel_mm) {
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
@@ -1296,228 +1285,8 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
}
-
-
-static void
-radeon_meta_set_passthrough_transform(radeonContextPtr radeon)
-{
- GLcontext *ctx = radeon->glCtx;
-
- radeon->meta.saved_vp_x = ctx->Viewport.X;
- radeon->meta.saved_vp_y = ctx->Viewport.Y;
- radeon->meta.saved_vp_width = ctx->Viewport.Width;
- radeon->meta.saved_vp_height = ctx->Viewport.Height;
- radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
-
- _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
-
- _mesa_MatrixMode(GL_PROJECTION);
- _mesa_PushMatrix();
- _mesa_LoadIdentity();
- _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
-
- _mesa_MatrixMode(GL_MODELVIEW);
- _mesa_PushMatrix();
- _mesa_LoadIdentity();
-}
-
-static void
-radeon_meta_restore_transform(radeonContextPtr radeon)
-{
- _mesa_MatrixMode(GL_PROJECTION);
- _mesa_PopMatrix();
- _mesa_MatrixMode(GL_MODELVIEW);
- _mesa_PopMatrix();
-
- _mesa_MatrixMode(radeon->meta.saved_matrix_mode);
-
- _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y,
- radeon->meta.saved_vp_width, radeon->meta.saved_vp_height);
-}
-
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering. The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-
-
-void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
+void radeonUserClear(GLcontext *ctx, GLuint mask)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat vertices[4][3];
- GLfloat color[4][4];
- GLfloat dst_z;
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- int i;
- GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
- GLboolean saved_shader_program = 0;
- unsigned int saved_active_texture;
-
- assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
- BUFFER_BIT_STENCIL)) == 0);
-
- _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
- GL_CURRENT_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_POLYGON_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT |
- GL_CURRENT_BIT);
- _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- saved_active_texture = ctx->Texture.CurrentUnit;
-
- /* Disable existing GL state we don't want to apply to a clear. */
- _mesa_Disable(GL_ALPHA_TEST);
- _mesa_Disable(GL_BLEND);
- _mesa_Disable(GL_CULL_FACE);
- _mesa_Disable(GL_FOG);
- _mesa_Disable(GL_POLYGON_SMOOTH);
- _mesa_Disable(GL_POLYGON_STIPPLE);
- _mesa_Disable(GL_POLYGON_OFFSET_FILL);
- _mesa_Disable(GL_LIGHTING);
- _mesa_Disable(GL_CLIP_PLANE0);
- _mesa_Disable(GL_CLIP_PLANE1);
- _mesa_Disable(GL_CLIP_PLANE2);
- _mesa_Disable(GL_CLIP_PLANE3);
- _mesa_Disable(GL_CLIP_PLANE4);
- _mesa_Disable(GL_CLIP_PLANE5);
- _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
- saved_fp_enable = GL_TRUE;
- _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
- saved_vp_enable = GL_TRUE;
- _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
- saved_shader_program = ctx->Shader.CurrentProgram->Name;
- _mesa_UseProgramObjectARB(0);
- }
-
- if (ctx->Texture._EnabledUnits != 0) {
- int i;
-
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
- _mesa_Disable(GL_TEXTURE_1D);
- _mesa_Disable(GL_TEXTURE_2D);
- _mesa_Disable(GL_TEXTURE_3D);
- if (ctx->Extensions.ARB_texture_cube_map)
- _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
- if (ctx->Extensions.NV_texture_rectangle)
- _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
- if (ctx->Extensions.MESA_texture_array) {
- _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
- _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
- }
- }
- }
-
-#if FEATURE_ARB_vertex_buffer_object
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
-#endif
-
- radeon_meta_set_passthrough_transform(rmesa);
-
- for (i = 0; i < 4; i++) {
- color[i][0] = ctx->Color.ClearColor[0];
- color[i][1] = ctx->Color.ClearColor[1];
- color[i][2] = ctx->Color.ClearColor[2];
- color[i][3] = ctx->Color.ClearColor[3];
- }
-
- /* convert clear Z from [0,1] to NDC coord in [-1,1] */
-
- dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
- /* Prepare the vertices, which are the same regardless of which buffer we're
- * drawing to.
- */
- vertices[0][0] = fb->_Xmin;
- vertices[0][1] = fb->_Ymin;
- vertices[0][2] = dst_z;
- vertices[1][0] = fb->_Xmax;
- vertices[1][1] = fb->_Ymin;
- vertices[1][2] = dst_z;
- vertices[2][0] = fb->_Xmax;
- vertices[2][1] = fb->_Ymax;
- vertices[2][2] = dst_z;
- vertices[3][0] = fb->_Xmin;
- vertices[3][1] = fb->_Ymax;
- vertices[3][2] = dst_z;
-
- _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
- _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
- _mesa_Enable(GL_COLOR_ARRAY);
- _mesa_Enable(GL_VERTEX_ARRAY);
-
- while (mask != 0) {
- GLuint this_mask = 0;
- GLuint color_bit;
-
- color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
- if (color_bit != 0)
- this_mask |= (1 << (color_bit - 1));
-
- /* Clear depth/stencil in the same pass as color. */
- this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
- /* Select the current color buffer and use the color write mask if
- * we have one, otherwise don't write any color channels.
- */
- if (this_mask & BUFFER_BIT_FRONT_LEFT)
- _mesa_DrawBuffer(GL_FRONT_LEFT);
- else if (this_mask & BUFFER_BIT_BACK_LEFT)
- _mesa_DrawBuffer(GL_BACK_LEFT);
- else if (color_bit != 0)
- _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
- (color_bit - BUFFER_COLOR0 - 1));
- else
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- /* Control writing of the depth clear value to depth. */
- if (this_mask & BUFFER_BIT_DEPTH) {
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_DepthMask(GL_TRUE);
- _mesa_Enable(GL_DEPTH_TEST);
- } else {
- _mesa_Disable(GL_DEPTH_TEST);
- _mesa_DepthMask(GL_FALSE);
- }
-
- /* Control writing of the stencil clear value to stencil. */
- if (this_mask & BUFFER_BIT_STENCIL) {
- _mesa_Enable(GL_STENCIL_TEST);
- _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, ctx->Stencil.Clear,
- ctx->Stencil.WriteMask[0]);
- } else {
- _mesa_Disable(GL_STENCIL_TEST);
- }
-
- CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
-
- mask &= ~this_mask;
- }
-
- radeon_meta_restore_transform(rmesa);
-
- _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
- if (saved_fp_enable)
- _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
- if (saved_vp_enable)
- _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
- if (saved_shader_program)
- _mesa_UseProgramObjectARB(saved_shader_program);
-
- _mesa_PopClientAttrib();
- _mesa_PopAttrib();
+ meta_clear_tris(&rmesa->meta, mask);
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index 2cefb53fe0..cebae18b2d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -5,23 +5,7 @@
#include "radeon_dma.h"
#include "radeon_texture.h"
-#ifndef HAVE_LIBDRM_RADEON
-#ifndef RADEON_DEBUG_BO
-#define RADEON_DEBUG_BO 1
-#endif
-#endif
-
-#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
- BUFFER_BIT_FRONT_LEFT | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
-
+void radeonUserClear(GLcontext *ctx, GLuint mask);
void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
@@ -52,10 +36,6 @@ void radeon_get_cliprects(radeonContextPtr radeon,
struct drm_clip_rect **cliprects,
unsigned int *num_cliprects,
int *x_off, int *y_off);
-GLboolean radeon_revalidate_bos(GLcontext *ctx);
-void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain);
-void radeon_validate_reset_bos(radeonContextPtr radeon);
-
void radeon_fbo_init(struct radeon_context *radeon);
void
radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 1c7faf048d..bbe7225ee6 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -190,6 +190,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
ctx = radeon->glCtx;
driContextPriv->driverPrivate = radeon;
+ meta_init_metaops(ctx, &radeon->meta);
/* DRI fields */
radeon->dri.context = driContextPriv;
radeon->dri.screen = sPriv;
@@ -286,7 +287,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
}
radeonReleaseArrays(radeon->glCtx, ~0);
-
+ meta_destroy_metaops(&radeon->meta);
if (radeon->vtbl.free_context)
radeon->vtbl.free_context(radeon->glCtx);
_swsetup_DestroyContext( radeon->glCtx );
@@ -596,8 +597,10 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
struct radeon_renderbuffer *stencil_rb;
i = 0;
- if ((radeon->is_front_buffer_rendering || !draw->color_rb[1])
- && draw->color_rb[0]) {
+ if ((radeon->is_front_buffer_rendering ||
+ radeon->is_front_buffer_reading ||
+ !draw->color_rb[1])
+ && draw->color_rb[0]) {
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
}
@@ -715,8 +718,8 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
rb->cpp = buffers[i].cpp;
rb->pitch = buffers[i].pitch;
- rb->width = drawable->w;
- rb->height = drawable->h;
+ rb->base.Width = drawable->w;
+ rb->base.Height = drawable->h;
rb->has_surface = 0;
if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index 43e705ee59..e4a8da0596 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -13,6 +13,7 @@
#include "dri_util.h"
#include "tnl/t_vertex.h"
+#include "dri_metaops.h"
struct radeon_context;
#include "radeon_bocs_wrapper.h"
@@ -83,8 +84,6 @@ struct radeon_renderbuffer
unsigned int cpp;
/* unsigned int offset; */
unsigned int pitch;
- unsigned int width;
- unsigned int height;
uint32_t draw_offset; /* FBO */
/* boo Xorg 6.8.2 compat */
@@ -482,19 +481,16 @@ struct radeon_context {
*/
GLboolean is_front_buffer_rendering;
- struct {
- struct gl_fragment_program *bitmap_fp;
- struct gl_vertex_program *passthrough_vp;
-
- struct gl_fragment_program *saved_fp;
- GLboolean saved_fp_enable;
- struct gl_vertex_program *saved_vp;
- GLboolean saved_vp_enable;
+ /**
+ * Track whether front-buffer is the current read target.
+ *
+ * This is closely associated with is_front_buffer_rendering, but may
+ * be set separately. The DRI2 fake front buffer must be referenced
+ * either way.
+ */
+ GLboolean is_front_buffer_reading;
- GLint saved_vp_x, saved_vp_y;
- GLsizei saved_vp_width, saved_vp_height;
- GLenum saved_matrix_mode;
- } meta;
+ struct dri_metaops meta;
struct {
void (*get_lock)(radeonContextPtr radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 8f780c443c..c457fb654e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -285,8 +285,10 @@ r100CreateContext( const __GLcontextModes *glVisual,
/* FIXME: When no memory manager is available we should set this
* to some reasonable value based on texture memory pool size */
- /* FIXME: does r100 support 2048x2048 texture ? */
ctx->Const.MaxTextureLevels = 12;
+ ctx->Const.Max3DTextureLevels = 9;
+ ctx->Const.MaxCubeTextureLevels = 12;
+ ctx->Const.MaxTextureRectSize = 2048;
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
@@ -316,6 +318,8 @@ r100CreateContext( const __GLcontextModes *glVisual,
ctx->Const.MaxDrawBuffers = 1;
+ _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
@@ -361,7 +365,7 @@ r100CreateContext( const __GLcontextModes *glVisual,
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
}
- if (rmesa->radeon.dri.drmMinor >= 9)
+ if (rmesa->radeon.radeonScreen->kernel_mm || rmesa->radeon.dri.drmMinor >= 9)
_mesa_enable_extension( ctx, "GL_NV_texture_rectangle");
/* XXX these should really go right after _mesa_init_driver_functions() */
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
index 984725a6c9..ee403d173c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
@@ -56,6 +56,8 @@ struct radeon_cs_space_check {
uint32_t new_accounted;
};
+#define MAX_SPACE_BOS (32)
+
struct radeon_cs_manager;
struct radeon_cs {
@@ -72,7 +74,10 @@ struct radeon_cs {
const char *section_file;
const char *section_func;
int section_line;
-
+ struct radeon_cs_space_check bos[MAX_SPACE_BOS];
+ int bo_count;
+ void (*space_flush_fn)(void *);
+ void *space_flush_data;
};
/* cs functions */
@@ -98,16 +103,14 @@ struct radeon_cs_funcs {
int (*cs_erase)(struct radeon_cs *cs);
int (*cs_need_flush)(struct radeon_cs *cs);
void (*cs_print)(struct radeon_cs *cs, FILE *file);
- int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos,
- int num_bo);
};
struct radeon_cs_manager {
struct radeon_cs_funcs *funcs;
int fd;
- uint32_t vram_limit, gart_limit;
- uint32_t vram_write_used, gart_write_used;
- uint32_t read_used;
+ int32_t vram_limit, gart_limit;
+ int32_t vram_write_used, gart_write_used;
+ int32_t read_used;
};
static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
@@ -171,13 +174,6 @@ static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
cs->csm->funcs->cs_print(cs, file);
}
-static inline int radeon_cs_space_check(struct radeon_cs *cs,
- struct radeon_cs_space_check *bos,
- int num_bo)
-{
- return cs->csm->funcs->cs_space_check(cs, bos, num_bo);
-}
-
static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
{
@@ -204,4 +200,38 @@ static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
cs->section_cdw+=2;
}
}
+
+static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
+{
+ cs->space_flush_fn = fn;
+ cs->space_flush_data = data;
+}
+
+
+/*
+ * add a persistent BO to the list
+ * a persistent BO is one that will be referenced across flushes,
+ * i.e. colorbuffer, textures etc.
+ * They get reset when a new "operation" happens, where an operation
+ * is a state emission with a color/textures etc followed by a bunch of vertices.
+ */
+void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
+/* reset the persistent BO list */
+void radeon_cs_space_reset_bos(struct radeon_cs *cs);
+
+/* do a space check with the current persistent BO list */
+int radeon_cs_space_check(struct radeon_cs *cs);
+
+/* do a space check with the current persistent BO list and a temporary BO
+ * a temporary BO is like a DMA buffer, which gets flushed with the
+ * command buffer */
+int radeon_cs_space_check_with_bo(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domains,
+ uint32_t write_domain);
+
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index a2727ef6f7..4f1065ebcf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -373,113 +373,6 @@ static void cs_print(struct radeon_cs *cs, FILE *file)
{
}
-static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
-{
- struct radeon_cs_manager *csm = cs->csm;
- int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
- uint32_t read_domains, write_domain;
- int i;
- struct radeon_bo *bo;
-
- /* check the totals for this operation */
-
- if (num_bo == 0)
- return 0;
-
- /* prepare */
- for (i = 0; i < num_bo; i++)
- {
- bo = bos[i].bo;
-
- bos[i].new_accounted = 0;
- read_domains = bos[i].read_domains;
- write_domain = bos[i].write_domain;
-
- /* pinned bos don't count */
- if (radeon_legacy_bo_is_static(bo))
- continue;
-
- /* already accounted this bo */
- if (write_domain && (write_domain == bo->space_accounted))
- continue;
-
- if (read_domains && ((read_domains << 16) == bo->space_accounted))
- continue;
-
- if (bo->space_accounted == 0)
- {
- if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- this_op_vram_write += bo->size;
- else if (write_domain == RADEON_GEM_DOMAIN_GTT)
- this_op_gart_write += bo->size;
- else
- this_op_read += bo->size;
- bos[i].new_accounted = (read_domains << 16) | write_domain;
- }
- else
- {
- uint16_t old_read, old_write;
-
- old_read = bo->space_accounted >> 16;
- old_write = bo->space_accounted & 0xffff;
-
- if (write_domain && (old_read & write_domain))
- {
- bos[i].new_accounted = write_domain;
- /* moving from read to a write domain */
- if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- {
- this_op_read -= bo->size;
- this_op_vram_write += bo->size;
- }
- else if (write_domain == RADEON_GEM_DOMAIN_VRAM)
- {
- this_op_read -= bo->size;
- this_op_gart_write += bo->size;
- }
- }
- else if (read_domains & old_write)
- {
- bos[i].new_accounted = bo->space_accounted & 0xffff;
- }
- else
- {
- /* rewrite the domains */
- if (write_domain != old_write)
- fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
- if (read_domains != old_read)
- fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
- return RADEON_CS_SPACE_FLUSH;
- }
- }
- }
-
- if (this_op_read < 0)
- this_op_read = 0;
-
- /* check sizes - operation first */
- if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
- (this_op_vram_write > csm->vram_limit)) {
- return RADEON_CS_SPACE_OP_TO_BIG;
- }
-
- if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
- ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
- return RADEON_CS_SPACE_FLUSH;
- }
-
- csm->gart_write_used += this_op_gart_write;
- csm->vram_write_used += this_op_vram_write;
- csm->read_used += this_op_read;
- /* commit */
- for (i = 0; i < num_bo; i++) {
- bo = bos[i].bo;
- bo->space_accounted = bos[i].new_accounted;
- }
-
- return RADEON_CS_SPACE_OK;
-}
-
static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
cs_create,
cs_write_reloc,
@@ -490,7 +383,6 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = {
cs_erase,
cs_need_flush,
cs_print,
- cs_check_space
};
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
new file mode 100644
index 0000000000..5a8df7bb8c
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright © 2009 Red Hat 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ */
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "radeon_bocs_wrapper.h"
+
+struct rad_sizes {
+ int32_t op_read;
+ int32_t op_gart_write;
+ int32_t op_vram_write;
+};
+
+static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct rad_sizes *sizes)
+{
+ uint32_t read_domains, write_domain;
+ struct radeon_bo *bo;
+
+ bo = sc->bo;
+ sc->new_accounted = 0;
+ read_domains = sc->read_domains;
+ write_domain = sc->write_domain;
+
+ /* legacy needs a static check */
+ if (radeon_bo_is_static(bo)) {
+ bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain;
+ return 0;
+ }
+
+ /* already accounted this bo */
+ if (write_domain && (write_domain == bo->space_accounted)) {
+ sc->new_accounted = bo->space_accounted;
+ return 0;
+ }
+ if (read_domains && ((read_domains << 16) == bo->space_accounted)) {
+ sc->new_accounted = bo->space_accounted;
+ return 0;
+ }
+
+ if (bo->space_accounted == 0) {
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM)
+ sizes->op_vram_write += bo->size;
+ else if (write_domain == RADEON_GEM_DOMAIN_GTT)
+ sizes->op_gart_write += bo->size;
+ else
+ sizes->op_read += bo->size;
+ sc->new_accounted = (read_domains << 16) | write_domain;
+ } else {
+ uint16_t old_read, old_write;
+
+ old_read = bo->space_accounted >> 16;
+ old_write = bo->space_accounted & 0xffff;
+
+ if (write_domain && (old_read & write_domain)) {
+ sc->new_accounted = write_domain;
+ /* moving from read to a write domain */
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ sizes->op_read -= bo->size;
+ sizes->op_vram_write += bo->size;
+ } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ sizes->op_read -= bo->size;
+ sizes->op_gart_write += bo->size;
+ }
+ } else if (read_domains & old_write) {
+ sc->new_accounted = bo->space_accounted & 0xffff;
+ } else {
+ /* rewrite the domains */
+ if (write_domain != old_write)
+ fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
+ if (read_domains != old_read)
+ fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
+ return RADEON_CS_SPACE_FLUSH;
+ }
+ }
+ return 0;
+}
+
+static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space_check *new_tmp)
+{
+ struct radeon_cs_manager *csm = cs->csm;
+ int i;
+ struct radeon_bo *bo;
+ struct rad_sizes sizes;
+ int ret;
+
+ /* check the totals for this operation */
+
+ if (cs->bo_count == 0 && !new_tmp)
+ return 0;
+
+ memset(&sizes, 0, sizeof(struct rad_sizes));
+
+ /* prepare */
+ for (i = 0; i < cs->bo_count; i++) {
+ ret = radeon_cs_setup_bo(&cs->bos[i], &sizes);
+ if (ret)
+ return ret;
+ }
+
+ if (new_tmp) {
+ ret = radeon_cs_setup_bo(new_tmp, &sizes);
+ if (ret)
+ return ret;
+ }
+
+ if (sizes.op_read < 0)
+ sizes.op_read = 0;
+
+ /* check sizes - operation first */
+ if ((sizes.op_read + sizes.op_gart_write > csm->gart_limit) ||
+ (sizes.op_vram_write > csm->vram_limit)) {
+ return RADEON_CS_SPACE_OP_TO_BIG;
+ }
+
+ if (((csm->vram_write_used + sizes.op_vram_write) > csm->vram_limit) ||
+ ((csm->read_used + csm->gart_write_used + sizes.op_gart_write + sizes.op_read) > csm->gart_limit)) {
+ return RADEON_CS_SPACE_FLUSH;
+ }
+
+ csm->gart_write_used += sizes.op_gart_write;
+ csm->vram_write_used += sizes.op_vram_write;
+ csm->read_used += sizes.op_read;
+ /* commit */
+ for (i = 0; i < cs->bo_count; i++) {
+ bo = cs->bos[i].bo;
+ bo->space_accounted = cs->bos[i].new_accounted;
+ }
+ if (new_tmp)
+ new_tmp->bo->space_accounted = new_tmp->new_accounted;
+
+ return RADEON_CS_SPACE_OK;
+}
+
+void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
+{
+ int i;
+ for (i = 0; i < cs->bo_count; i++) {
+ if (cs->bos[i].bo == bo &&
+ cs->bos[i].read_domains == read_domains &&
+ cs->bos[i].write_domain == write_domain)
+ return;
+ }
+ radeon_bo_ref(bo);
+ i = cs->bo_count;
+ cs->bos[i].bo = bo;
+ cs->bos[i].read_domains = read_domains;
+ cs->bos[i].write_domain = write_domain;
+ cs->bos[i].new_accounted = 0;
+ cs->bo_count++;
+
+ assert(cs->bo_count < MAX_SPACE_BOS);
+}
+
+static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs_space_check *tmp_bo)
+{
+ int ret;
+ int flushed = 0;
+
+again:
+ ret = radeon_cs_do_space_check(cs, tmp_bo);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG)
+ return -1;
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ (*cs->space_flush_fn)(cs->space_flush_data);
+ if (flushed)
+ return -1;
+ flushed = 1;
+ goto again;
+ }
+ return 0;
+}
+
+int radeon_cs_space_check_with_bo(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domains, uint32_t write_domain)
+{
+ struct radeon_cs_space_check temp_bo;
+ int ret = 0;
+
+ if (bo) {
+ temp_bo.bo = bo;
+ temp_bo.read_domains = read_domains;
+ temp_bo.write_domain = write_domain;
+ temp_bo.new_accounted = 0;
+ }
+
+ ret = radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL);
+ return ret;
+}
+
+int radeon_cs_space_check(struct radeon_cs *cs)
+{
+ return radeon_cs_check_space_internal(cs, NULL);
+}
+
+void radeon_cs_space_reset_bos(struct radeon_cs *cs)
+{
+ int i;
+ for (i = 0; i < cs->bo_count; i++) {
+ radeon_bo_unref(cs->bos[i].bo);
+ cs->bos[i].bo = NULL;
+ cs->bos[i].read_domains = 0;
+ cs->bos[i].write_domain = 0;
+ cs->bos[i].new_accounted = 0;
+ }
+ cs->bo_count = 0;
+}
+
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index 2fbf89bf6d..48114a0012 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -204,10 +204,10 @@ again_alloc:
rmesa->dma.current_used = 0;
rmesa->dma.current_vertexptr = 0;
- radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0);
-
- if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE)
- fprintf(stderr,"failure to revalidate BOs - badness\n");
+ if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs,
+ rmesa->dma.current,
+ RADEON_GEM_DOMAIN_GTT, 0))
+ fprintf(stderr,"failure to revalidate BOs - badness\n");
if (!rmesa->dma.current) {
/* Cmd buff have been flushed in radeon_revalidate_bos */
@@ -305,7 +305,7 @@ restart:
if (!rmesa->dma.flush) {
/* make sure we have enough space to use this in cmdbuf */
rcommonEnsureCmdBufSpace(rmesa,
- rmesa->hw.max_state_size + (12*sizeof(int)),
+ rmesa->hw.max_state_size + (20*sizeof(int)),
__FUNCTION__);
/* if cmdbuf flushed DMA restart */
if (!rmesa->dma.current)
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index ea18f1ee2d..f28efa33e9 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -146,8 +146,8 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
- rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT;
- rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
+ rb->_ActualFormat = GL_DEPTH_COMPONENT24;
+ rb->DataType = GL_UNSIGNED_INT;
rb->DepthBits = 24;
cpp = 4;
break;
@@ -316,7 +316,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
rrb->base.DataType = GL_UNSIGNED_SHORT;
break;
case GL_DEPTH_COMPONENT24:
- rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
+ rrb->base._ActualFormat = GL_DEPTH_COMPONENT24;
rrb->base._BaseFormat = GL_DEPTH_COMPONENT;
rrb->base.DepthBits = 24;
rrb->base.DataType = GL_UNSIGNED_INT;
@@ -410,6 +410,20 @@ restart:
rrb->base.DataType = GL_UNSIGNED_SHORT;
DBG("Render to RGB5 texture OK\n");
}
+ else if (texImage->TexFormat == &_mesa_texformat_argb1555) {
+ rrb->cpp = 2;
+ rrb->base._ActualFormat = GL_RGB5_A1;
+ rrb->base._BaseFormat = GL_RGBA;
+ rrb->base.DataType = GL_UNSIGNED_BYTE;
+ DBG("Render to ARGB1555 texture OK\n");
+ }
+ else if (texImage->TexFormat == &_mesa_texformat_argb4444) {
+ rrb->cpp = 2;
+ rrb->base._ActualFormat = GL_RGBA4;
+ rrb->base._BaseFormat = GL_RGBA;
+ rrb->base.DataType = GL_UNSIGNED_BYTE;
+ DBG("Render to ARGB1555 texture OK\n");
+ }
else if (texImage->TexFormat == &_mesa_texformat_z16) {
rrb->cpp = 2;
rrb->base._ActualFormat = GL_DEPTH_COMPONENT16;
@@ -448,6 +462,7 @@ restart:
rrb->base.BlueBits = texImage->TexFormat->BlueBits;
rrb->base.AlphaBits = texImage->TexFormat->AlphaBits;
rrb->base.DepthBits = texImage->TexFormat->DepthBits;
+ rrb->base.StencilBits = texImage->TexFormat->StencilBits;
rrb->base.Delete = radeon_delete_renderbuffer;
rrb->base.AllocStorage = radeon_nop_alloc_storage;
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 01c45df2df..a5e4df7941 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -445,11 +445,6 @@ void radeonEmitAOS( r100ContextPtr rmesa,
*/
#define RADEON_MAX_CLEARS 256
-static void radeonUserClear(GLcontext *ctx, GLuint mask)
-{
- radeon_clear_tris(ctx, mask);
-}
-
static void radeonKernelClear(GLcontext *ctx, GLuint flags)
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index e28f28662b..b2a468b4fd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -51,54 +51,63 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
-static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb,
+/* radeon tiling on r300-r500 has 4 states,
+ macro-linear/micro-linear
+ macro-linear/micro-tiled
+ macro-tiled /micro-linear
+ macro-tiled /micro-tiled
+ 1 byte surface
+ 2 byte surface - two types - we only provide 8x2 microtiling
+ 4 byte surface
+ 8/16 byte (unused)
+*/
+
+static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
GLint x, GLint y)
{
GLubyte *ptr = rrb->bo->ptr;
uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
GLint offset;
- GLint nmacroblkpl;
- GLint nmicroblkpl;
if (rrb->has_surface || !(rrb->bo->flags & mask)) {
offset = x * rrb->cpp + y * rrb->pitch;
} else {
offset = 0;
if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
- if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
- nmacroblkpl = rrb->pitch >> 5;
- offset += ((y >> 4) * nmacroblkpl) << 11;
- offset += ((y & 15) >> 1) << 8;
- offset += (y & 1) << 4;
- offset += (x >> 5) << 11;
- offset += ((x & 31) >> 2) << 5;
- offset += (x & 3) << 2;
+ if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
+ offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 5)) << 11;
+ offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 10;
+ offset += (((y >> 4) ^ (x >> 4)) & 0x1) << 9;
+ offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 8;
+ offset += (((y >> 3) ^ (x >> 3)) & 0x1) << 7;
+ offset += ((y >> 1) & 0x1) << 6;
+ offset += ((x >> 2) & 0x1) << 5;
+ offset += (y & 1) << 4;
+ offset += (x & 3) << 2;
} else {
- nmacroblkpl = rrb->pitch >> 6;
- offset += ((y >> 3) * nmacroblkpl) << 11;
- offset += (y & 7) << 8;
- offset += (x >> 6) << 11;
- offset += ((x & 63) >> 3) << 5;
- offset += (x & 7) << 2;
+ offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 6)) << 11;
+ offset += (((y >> 2) ^ (x >> 6)) & 0x1) << 10;
+ offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 9;
+ offset += (((y >> 1) ^ (x >> 5)) & 0x1) << 8;
+ offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 7;
+ offset += (y & 1) << 6;
+ offset += (x & 15) << 2;
}
} else {
- nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
- offset += (y * nmicroblkpl) << 5;
- offset += (x >> 3) << 5;
- offset += (x & 7) << 2;
+ offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 2)) << 5;
+ offset += (y & 1) << 4;
+ offset += (x & 3) << 2;
}
}
return &ptr[offset];
}
-static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
- GLint x, GLint y)
+static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
{
GLubyte *ptr = rrb->bo->ptr;
uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
GLint offset;
- GLint nmacroblkpl;
- GLint nmicroblkpl;
if (rrb->has_surface || !(rrb->bo->flags & mask)) {
offset = x * rrb->cpp + y * rrb->pitch;
@@ -106,73 +115,29 @@ static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
offset = 0;
if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
- nmacroblkpl = rrb->pitch >> 6;
- offset += ((y >> 4) * nmacroblkpl) << 11;
- offset += ((y & 15) >> 1) << 8;
- offset += (y & 1) << 4;
- offset += (x >> 6) << 11;
- offset += ((x & 63) >> 3) << 5;
- offset += (x & 7) << 1;
+ offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 6)) << 11;
+ offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 10;
+ offset += (((y >> 4) ^ (x >> 5)) & 0x1) << 9;
+ offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 8;
+ offset += (((y >> 3) ^ (x >> 4)) & 0x1) << 7;
+ offset += ((y >> 1) & 0x1) << 6;
+ offset += ((x >> 3) & 0x1) << 5;
+ offset += (y & 1) << 4;
+ offset += (x & 3) << 2;
} else {
- nmacroblkpl = rrb->pitch >> 7;
- offset += ((y >> 3) * nmacroblkpl) << 11;
- offset += (y & 7) << 8;
- offset += (x >> 7) << 11;
- offset += ((x & 127) >> 4) << 5;
+ offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 7)) << 11;
+ offset += (((y >> 2) ^ (x >> 7)) & 0x1) << 10;
+ offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 9;
+ offset += (((y >> 1) ^ (x >> 6)) & 0x1) << 8;
+ offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 7;
+ offset += (y & 1) << 6;
+ offset += ((x >> 4) & 0x1) << 5;
offset += (x & 15) << 2;
}
} else {
- nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
- offset += (y * nmicroblkpl) << 5;
- offset += (x >> 4) << 5;
- offset += (x & 15) << 2;
- }
- }
- return &ptr[offset];
-}
-
-static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb,
- GLint x, GLint y)
-{
- GLubyte *ptr = rrb->bo->ptr;
- uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
- GLint offset;
- GLint microblkxs;
- GLint macroblkxs;
- GLint nmacroblkpl;
- GLint nmicroblkpl;
-
- if (rrb->has_surface || !(rrb->bo->flags & mask)) {
- offset = x * rrb->cpp + y * rrb->pitch;
- } else {
- offset = 0;
- if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
- if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
- microblkxs = 16 / rrb->cpp;
- macroblkxs = 128 / rrb->cpp;
- nmacroblkpl = rrb->pitch / macroblkxs;
- offset += ((y >> 4) * nmacroblkpl) << 11;
- offset += ((y & 15) >> 1) << 8;
- offset += (y & 1) << 4;
- offset += (x / macroblkxs) << 11;
- offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
- offset += (x & (microblkxs - 1)) * rrb->cpp;
- } else {
- microblkxs = 32 / rrb->cpp;
- macroblkxs = 256 / rrb->cpp;
- nmacroblkpl = rrb->pitch / macroblkxs;
- offset += ((y >> 3) * nmacroblkpl) << 11;
- offset += (y & 7) << 8;
- offset += (x / macroblkxs) << 11;
- offset += ((x & (macroblkxs - 1)) / microblkxs) << 5;
- offset += (x & (microblkxs - 1)) * rrb->cpp;
- }
- } else {
- microblkxs = 32 / rrb->cpp;
- nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5;
- offset += (y * nmicroblkpl) << 5;
- offset += (x / microblkxs) << 5;
- offset += (x & (microblkxs - 1)) * rrb->cpp;
+ offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 3)) << 5;
+ offset += (y & 0x1) << 4;
+ offset += (x & 0x7) << 1;
}
}
return &ptr[offset];
@@ -239,7 +204,7 @@ s8z24_to_z24s8(uint32_t val)
int miny = cliprects[_nc].y1 - y_off; \
int maxx = cliprects[_nc].x2 - x_off; \
int maxy = cliprects[_nc].y2 - y_off;
-
+
/* ================================================================
* Color buffer
*/
@@ -251,7 +216,27 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_RGB565
#define TAG2(x,y) radeon##x##_RGB565##y
-#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off)
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#include "spantmp2.h"
+
+/* 16 bit, ARGB1555 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
+
+#define TAG(x) radeon##x##_ARGB1555
+#define TAG2(x,y) radeon##x##_ARGB1555##y
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#include "spantmp2.h"
+
+/* 16 bit, RGBA4 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
+
+#define TAG(x) radeon##x##_ARGB4444
+#define TAG2(x,y) radeon##x##_ARGB4444##y
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
#include "spantmp2.h"
/* 32 bit, xRGB8888 color spanline and pixel functions
@@ -261,9 +246,9 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_xRGB8888
#define TAG2(x,y) radeon##x##_xRGB8888##y
-#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) | 0xff000000))
+#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0xff000000))
#define PUT_VALUE(_x, _y, d) { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
#include "spantmp2.h"
@@ -275,7 +260,11 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_ARGB8888
#define TAG2(x,y) radeon##x##_ARGB8888##y
-#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off)
+#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)))
+#define PUT_VALUE(_x, _y, d) { \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
+ *_ptr = d; \
+} while (0)
#include "spantmp2.h"
/* ================================================================
@@ -297,10 +286,10 @@ s8z24_to_z24s8(uint32_t val)
#define VALUE_TYPE GLushort
#define WRITE_DEPTH( _x, _y, d ) \
- *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) = d
+ *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d
#define READ_DEPTH( d, _x, _y ) \
- d = *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off)
+ d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off)
#define TAG(x) radeon##x##_z16
#include "depthtmp.h"
@@ -315,7 +304,7 @@ s8z24_to_z24s8(uint32_t val)
#ifdef COMPILE_R300
#define WRITE_DEPTH( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = *_ptr; \
tmp &= 0x000000ff; \
tmp |= ((d << 8) & 0xffffff00); \
@@ -324,7 +313,7 @@ do { \
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = *_ptr; \
tmp &= 0xff000000; \
tmp |= ((d) & 0x00ffffff); \
@@ -335,11 +324,11 @@ do { \
#ifdef COMPILE_R300
#define READ_DEPTH( d, _x, _y ) \
do { \
- d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
+ d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
}while(0)
#else
#define READ_DEPTH( d, _x, _y ) \
- d = *(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0x00ffffff;
+ 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);\
@@ -359,13 +348,13 @@ do { \
#ifdef COMPILE_R300
#define WRITE_DEPTH( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = z24s8_to_s8z24(d); \
*_ptr = tmp; \
} while (0)
@@ -374,11 +363,11 @@ do { \
#ifdef COMPILE_R300
#define READ_DEPTH( d, _x, _y ) \
do { \
- d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off))); \
+ d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
}while(0)
#else
#define READ_DEPTH( d, _x, _y ) do { \
- d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off ))); \
+ d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off ))); \
} while (0)
#endif
/*
@@ -397,7 +386,7 @@ do { \
#ifdef COMPILE_R300
#define WRITE_STENCIL( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \
GLuint tmp = *_ptr; \
tmp &= 0xffffff00; \
tmp |= (d) & 0xff; \
@@ -406,7 +395,7 @@ do { \
#else
#define WRITE_STENCIL( _x, _y, d ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \
GLuint tmp = *_ptr; \
tmp &= 0x00ffffff; \
tmp |= (((d) & 0xff) << 24); \
@@ -417,14 +406,14 @@ do { \
#ifdef COMPILE_R300
#define READ_STENCIL( d, _x, _y ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = *_ptr; \
d = tmp & 0x000000ff; \
} while (0)
#else
#define READ_STENCIL( d, _x, _y ) \
do { \
- GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \
+ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = *_ptr; \
d = (tmp & 0xff000000) >> 24; \
} while (0)
@@ -438,11 +427,13 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
{
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
int r;
-
+
if (rrb == NULL || !rrb->bo)
return;
if (flag) {
+ if (rrb->bo->bom->funcs->bo_wait)
+ radeon_bo_wait(rrb->bo);
r = radeon_bo_map(rrb->bo, 1);
if (r) {
fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
@@ -472,25 +463,30 @@ radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
ctx->DrawBuffer->Attachment + i;
struct gl_texture_object *tex = att->Texture;
if (tex) {
- /* render to texture */
+ /* Render to texture. Note that a mipmapped texture need not
+ * be complete for render to texture, so we must restrict to
+ * mapping only the attached image.
+ */
+ radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
ASSERT(att->Renderbuffer);
+
if (map)
- ctx->Driver.MapTexture(ctx, tex);
+ radeon_teximage_map(image, GL_TRUE);
else
- ctx->Driver.UnmapTexture(ctx, tex);
+ radeon_teximage_unmap(image);
}
}
-
+
map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
/* depth buffer (Note wrapper!) */
if (ctx->DrawBuffer->_DepthBuffer)
map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
-
+
if (ctx->DrawBuffer->_StencilBuffer)
map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
-
}
+
static void radeonSpanRenderStart(GLcontext * ctx)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -507,15 +503,13 @@ static void radeonSpanRenderStart(GLcontext * ctx)
LOCK_HARDWARE(rmesa);
radeonWaitForIdleLocked(rmesa);
}
+
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled)
ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
}
radeon_map_unmap_buffers(ctx, 1);
-
-
-
}
static void radeonSpanRenderFinish(GLcontext * ctx)
@@ -553,6 +547,10 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
radeonInitPointers_xRGB8888(&rrb->base);
} else if (rrb->base._ActualFormat == GL_RGBA8) {
radeonInitPointers_ARGB8888(&rrb->base);
+ } else if (rrb->base._ActualFormat == GL_RGBA4) {
+ radeonInitPointers_ARGB4444(&rrb->base);
+ } else if (rrb->base._ActualFormat == GL_RGB5_A1) {
+ radeonInitPointers_ARGB1555(&rrb->base);
} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) {
radeonInitDepthPointers_z16(&rrb->base);
} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {
@@ -561,5 +559,7 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
radeonInitDepthPointers_z24_s8(&rrb->base);
} else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
radeonInitStencilPointers_z24_s8(&rrb->base);
+ } else {
+ fprintf(stderr, "radeonSetSpanFunctions: bad actual format: 0x%04X\n", rrb->base._ActualFormat);
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 06b8c29936..0d1728b747 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -458,6 +458,10 @@ static void radeonFrontFace( GLcontext *ctx, GLenum mode )
RADEON_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
+ /* Winding is inverted when rendering to FBO */
+ if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+ mode = (mode == GL_CW) ? GL_CCW : GL_CW;
+
switch ( mode ) {
case GL_CW:
rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
@@ -508,11 +512,18 @@ static void radeonColorMask( GLcontext *ctx,
GLboolean b, GLboolean a )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
- GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
- ctx->Color.ColorMask[RCOMP],
- ctx->Color.ColorMask[GCOMP],
- ctx->Color.ColorMask[BCOMP],
- ctx->Color.ColorMask[ACOMP] );
+ struct radeon_renderbuffer *rrb;
+ GLuint mask;
+
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ if (!rrb)
+ return;
+
+ mask = radeonPackColor( rrb->cpp,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] );
if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
RADEON_STATECHANGE( rmesa, msk );
@@ -1500,11 +1511,17 @@ static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
GLubyte c[4];
+ struct radeon_renderbuffer *rrb;
+
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ if (!rrb)
+ return;
+
CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
- rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
+ rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
c[0], c[1], c[2], c[3] );
}
@@ -2048,23 +2065,23 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx)
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
- int i;
+ int i, ret;
- radeon_validate_reset_bos(&rmesa->radeon);
+ radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- radeon_validate_bo(&rmesa->radeon, rrb->bo,
- 0, RADEON_GEM_DOMAIN_VRAM);
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -2073,20 +2090,19 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx)
if (!ctx->Texture.Unit[i]._ReallyEnabled)
continue;
- t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
+ t = rmesa->state.texture.unit[i].texobj;
if (t->image_override && t->bo)
- radeon_validate_bo(&rmesa->radeon, t->bo,
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
else if (t->mt->bo)
- radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- if (rmesa->radeon.dma.current)
- radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current,
- RADEON_GEM_DOMAIN_GTT, 0);
-
- return radeon_revalidate_bos(ctx);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ return GL_TRUE;
}
GLboolean radeonValidateState( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index f5d4189d66..aaa82b1d6a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -390,8 +390,17 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10);
if (rrb->cpp == 4)
atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888;
- else
+ else switch (rrb->base._ActualFormat) {
+ case GL_RGB5:
atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565;
+ break;
+ case GL_RGBA4:
+ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB4444;
+ break;
+ case GL_RGB5_A1:
+ atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB1555;
+ break;
+ }
cbpitch = (rrb->pitch / rrb->cpp);
if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
@@ -453,8 +462,8 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
OUT_BATCH(0);
OUT_BATCH(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
if (rrb) {
- OUT_BATCH(((rrb->width - 1) << RADEON_RE_WIDTH_SHIFT) |
- ((rrb->height - 1) << RADEON_RE_HEIGHT_SHIFT));
+ OUT_BATCH(((rrb->base.Width - 1) << RADEON_RE_WIDTH_SHIFT) |
+ ((rrb->base.Height - 1) << RADEON_RE_HEIGHT_SHIFT));
} else {
OUT_BATCH(0);
}
@@ -465,6 +474,34 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
+ uint32_t dwords = 3;
+ int i = atom->idx, j;
+ radeonTexObj *t = r100->state.texture.unit[i].texobj;
+ radeon_mipmap_level *lvl;
+
+ if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT))
+ return;
+
+ if (!t)
+ return;
+
+ if (!t->mt)
+ return;
+
+ BEGIN_BATCH_NO_AUTOSTATE(dwords + (5 * 3));
+ OUT_BATCH_TABLE(atom->cmd, 3);
+ lvl = &t->mt->levels[0];
+ for (j = 0; j < 5; j++) {
+ OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset,
+ RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ }
+ END_BATCH();
+}
+
+static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r100ContextPtr r100 = R100_CONTEXT(ctx);
+ BATCH_LOCALS(&r100->radeon);
uint32_t dwords = 2;
int i = atom->idx, j;
radeonTexObj *t = r100->state.texture.unit[i].texobj;
@@ -490,7 +527,7 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
OUT_BATCH_TABLE(atom->cmd, 2);
lvl = &t->mt->levels[0];
for (j = 0; j < 5; j++) {
- OUT_BATCH(CP_PACKET0(base_reg + (4 * (j-1)), 0));
+ OUT_BATCH(CP_PACKET0(base_reg + (4 * j), 0));
OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset,
RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
@@ -661,7 +698,10 @@ void radeonInitState( r100ContextPtr rmesa )
ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 );
ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 );
for (i = 0; i < 3; i++)
- rmesa->hw.cube[i].emit = cube_emit;
+ if (rmesa->radeon.radeonScreen->kernel_mm)
+ rmesa->hw.cube[i].emit = cube_emit_cs;
+ else
+ rmesa->hw.cube[i].emit = cube_emit;
}
else
{
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index 279bcd4df6..c29105d7b8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -706,7 +706,7 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_
rImage->mt = NULL;
}
_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
- rb->width, rb->height, 1, 0, rb->cpp);
+ rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
texImage->RowStride = rb->pitch / rb->cpp;
texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
internalFormat,
@@ -738,8 +738,8 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_
t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
break;
}
- t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT)
- | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT);
+ t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
+ | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
t->pp_txpitch = pitch_val;
t->pp_txpitch -= 32;
@@ -1143,12 +1143,14 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
r100ContextPtr rmesa = R100_CONTEXT(ctx);
if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) {
+ rmesa->state.texture.unit[unit].texobj = NULL;
return GL_FALSE;
}
if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
/* disable the unit */
disable_tex_obj_state(rmesa, unit);
+ rmesa->state.texture.unit[unit].texobj = NULL;
return GL_TRUE;
}
@@ -1156,8 +1158,8 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
_mesa_warning(ctx,
"failed to validate texture for unit %d.\n",
unit);
- rmesa->state.texture.unit[unit].texobj = NULL;
- return GL_FALSE;
+ rmesa->state.texture.unit[unit].texobj = NULL;
+ return GL_FALSE;
}
rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index ee66fc2ea0..ad501c454c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -477,6 +477,26 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
case GL_DEPTH_STENCIL_EXT:
case GL_DEPTH24_STENCIL8_EXT:
return &_mesa_texformat_s8_z24;
+
+ /* EXT_texture_sRGB */
+ case GL_SRGB:
+ case GL_SRGB8:
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ case GL_COMPRESSED_SRGB:
+ case GL_COMPRESSED_SRGB_ALPHA:
+ return &_mesa_texformat_srgba8;
+
+ case GL_SLUMINANCE:
+ case GL_SLUMINANCE8:
+ case GL_COMPRESSED_SLUMINANCE:
+ return &_mesa_texformat_sl8;
+
+ case GL_SLUMINANCE_ALPHA:
+ case GL_SLUMINANCE8_ALPHA8:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA:
+ return &_mesa_texformat_sla8;
+
default:
_mesa_problem(ctx,
"unexpected internalFormat 0x%x in %s",
@@ -492,7 +512,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
*/
static void radeon_teximage(
GLcontext *ctx, int dims,
- GLint face, GLint level,
+ GLenum target, GLint level,
GLint internalFormat,
GLint width, GLint height, GLint depth,
GLsizei imageSize,
@@ -509,6 +529,7 @@ static void radeon_teximage(
GLint postConvWidth = width;
GLint postConvHeight = height;
GLuint texelBytes;
+ GLuint face = radeon_face_for_target(target);
radeon_firevertices(rmesa);
@@ -594,6 +615,8 @@ static void radeon_teximage(
memcpy(texImage->Data, pixels, imageSize);
} else {
GLuint dstRowStride;
+ GLuint *dstImageOffsets;
+
if (image->mt) {
radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
dstRowStride = lvl->rowstride;
@@ -601,20 +624,37 @@ static void radeon_teximage(
dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
}
+ if (dims == 3) {
+ int i;
+
+ dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ;
+ if (!dstImageOffsets)
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+
+ for (i = 0; i < depth; ++i) {
+ dstImageOffsets[i] = dstRowStride/texImage->TexFormat->TexelBytes * height * i;
+ }
+ } else {
+ dstImageOffsets = texImage->ImageOffsets;
+ }
+
if (!texImage->TexFormat->StoreImage(ctx, dims,
texImage->_BaseFormat,
texImage->TexFormat,
texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
dstRowStride,
- texImage->ImageOffsets,
+ dstImageOffsets,
width, height, depth,
format, type, pixels, packing))
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+
+ if (dims == 3)
+ _mesa_free(dstImageOffsets);
}
/* SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- radeon_generate_mipmap(ctx, texObj->Target, texObj);
+ radeon_generate_mipmap(ctx, target, texObj);
}
}
@@ -634,7 +674,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
+ radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
0, format, type, pixels, packing, texObj, texImage, 0);
}
@@ -647,9 +687,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
- GLuint face = radeon_face_for_target(target);
-
- radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+ radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
0, format, type, pixels, packing, texObj, texImage, 0);
}
@@ -660,9 +698,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLuint face = radeon_face_for_target(target);
-
- radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+ radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
}
@@ -675,14 +711,14 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
+ radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
0, format, type, pixels, packing, texObj, texImage, 0);
}
/**
* Update a subregion of the given texture image.
*/
-static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
+static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLsizei imageSize,
@@ -742,7 +778,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- radeon_generate_mipmap(ctx, texObj->Target, texObj);
+ radeon_generate_mipmap(ctx, target, texObj);
}
}
@@ -762,7 +798,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
+ radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
format, type, pixels, packing, texObj, texImage, 0);
}
@@ -775,7 +811,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+ radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
0, format, type, pixels, packing, texObj, texImage,
0);
}
@@ -788,7 +824,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+ radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
}
@@ -802,7 +838,7 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
+ radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
format, type, pixels, packing, texObj, texImage, 0);
}