summaryrefslogtreecommitdiff
path: root/src/mesa/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--src/mesa/drivers/dri/Makefile.template2
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h30
-rw-r--r--src/mesa/drivers/dri/i915/Makefile1
-rw-r--r--src/mesa/drivers/dri/i915/i830_reg.h13
-rw-r--r--src/mesa/drivers/dri/i915/i830_state.c21
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c10
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c40
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_reg.h15
-rw-r--r--src/mesa/drivers/dri/i915/i915_tex_layout.c64
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c9
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c44
l---------src/mesa/drivers/dri/i915/intel_generatemipmap.c1
-rw-r--r--src/mesa/drivers/dri/i965/Makefile2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h14
-rw-r--r--src/mesa/drivers/dri/i965/brw_curbe.c77
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c16
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h25
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c159
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c50
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c70
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_surface_state.c226
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c12
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c17
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c311
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_iz.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass2.c21
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_sampler_state.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c318
l---------src/mesa/drivers/dri/i965/intel_generatemipmap.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c66
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffers.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_clear.c15
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c79
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h22
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c16
-rw-r--r--src/mesa/drivers/dri/intel/intel_generatemipmap.c283
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c35
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h10
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel.c84
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_bitmap.c23
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_draw.c49
-rw-r--r--src/mesa/drivers/dri/intel/intel_reg.h13
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c111
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c19
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.c72
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h111
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c34
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c103
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_layout.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c38
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_validate.c4
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c5
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c3
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c9
-rw-r--r--src/mesa/drivers/dri/r300/r500_fragprog.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c2
-rw-r--r--src/mesa/drivers/x11/xm_dd.c3
70 files changed, 1877 insertions, 1001 deletions
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 276da41f4e..56abdbdfcb 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -237,6 +237,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->DeleteArrayObject = _mesa_delete_array_object;
driver->BindArrayObject = NULL;
+ /* GL_ARB_copy_buffer */
+ driver->CopyBufferSubData = _mesa_copy_buffer_subdata;
+
/* T&L stuff */
driver->NeedValidate = GL_FALSE;
driver->ValidateTnlModule = NULL;
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 5c01d233c1..bd38e3be47 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -92,7 +92,7 @@ clean:
install: $(LIBNAME)
$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
-include depend
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index 8dcaaee307..f5e35e4161 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -1763,6 +1763,13 @@ static const char DeleteFencesNV_names[] =
"";
#endif
+#if defined(need_GL_SGIX_polynomial_ffd)
+static const char DeformationMap3dSGIX_names[] =
+ "iddiiddiiddiip\0" /* Parameter signature */
+ "glDeformationMap3dSGIX\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0)
static const char IsShader_names[] =
"i\0" /* Parameter signature */
@@ -4396,6 +4403,13 @@ static const char WindowPos3ivMESA_names[] =
"";
#endif
+#if defined(need_GL_ARB_copy_buffer)
+static const char CopyBufferSubData_names[] =
+ "iiiii\0" /* Parameter signature */
+ "glCopyBufferSubData\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
static const char IsBufferARB_names[] =
"i\0" /* Parameter signature */
@@ -4560,13 +4574,6 @@ static const char Minmax_names[] =
"";
#endif
-#if defined(need_GL_SGIX_polynomial_ffd)
-static const char DeformationMap3dSGIX_names[] =
- "iddiiddiiddiip\0" /* Parameter signature */
- "glDeformationMap3dSGIX\0"
- "";
-#endif
-
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
static const char FogCoorddvEXT_names[] =
"p\0" /* Parameter signature */
@@ -4939,6 +4946,13 @@ static const struct dri_extension_function GL_APPLE_vertex_array_object_function
};
#endif
+#if defined(need_GL_ARB_copy_buffer)
+static const struct dri_extension_function GL_ARB_copy_buffer_functions[] = {
+ { CopyBufferSubData_names, CopyBufferSubData_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_draw_buffers)
static const struct dri_extension_function GL_ARB_draw_buffers_functions[] = {
{ DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 },
@@ -6055,9 +6069,9 @@ static const struct dri_extension_function GL_SGIX_pixel_texture_functions[] = {
#if defined(need_GL_SGIX_polynomial_ffd)
static const struct dri_extension_function GL_SGIX_polynomial_ffd_functions[] = {
{ LoadIdentityDeformationMapSGIX_names, LoadIdentityDeformationMapSGIX_remap_index, -1 },
+ { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 },
{ DeformSGIX_names, DeformSGIX_remap_index, -1 },
{ DeformationMap3fSGIX_names, DeformationMap3fSGIX_remap_index, -1 },
- { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index 9f4bd1699f..beaf9a4b12 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -19,6 +19,7 @@ DRIVER_SOURCES = \
intel_batchbuffer.c \
intel_clear.c \
intel_extensions.c \
+ intel_generatemipmap.c \
intel_mipmap_tree.c \
intel_tex_layout.c \
intel_tex_image.c \
diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h
index d210c2d08e..db16871001 100644
--- a/src/mesa/drivers/dri/i915/i830_reg.h
+++ b/src/mesa/drivers/dri/i915/i830_reg.h
@@ -48,19 +48,6 @@
#define AA_LINE_ENABLE ((1<<1) | 1)
#define AA_LINE_DISABLE (1<<1)
-#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
-/* Dword 1 */
-#define BUF_3D_ID_COLOR_BACK (0x3<<24)
-#define BUF_3D_ID_DEPTH (0x7<<24)
-#define BUF_3D_USE_FENCE (1<<23)
-#define BUF_3D_TILED_SURFACE (1<<22)
-#define BUF_3D_TILE_WALK_X 0
-#define BUF_3D_TILE_WALK_Y (1<<21)
-#define BUF_3D_PITCH(x) (((x)/4)<<2)
-/* Dword 2 */
-#define BUF_3D_ADDR(x) ((x) & ~0x3)
-
-
#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16))
#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index d9cad0c4bf..8ef6c9144f 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -39,6 +39,7 @@
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_fbo.h"
+#include "intel_buffers.h"
#include "i830_context.h"
#include "i830_reg.h"
@@ -446,6 +447,24 @@ i830DepthMask(GLcontext * ctx, GLboolean flag)
i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
}
+/** Called from ctx->Driver.Viewport() */
+static void
+i830Viewport(GLcontext * ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ intelCalcViewport(ctx);
+
+ intel_viewport(ctx, x, y, width, height);
+}
+
+
+/** Called from ctx->Driver.DepthRange() */
+static void
+i830DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
+{
+ intelCalcViewport(ctx);
+}
+
/* =============================================================
* Polygon stipple
*
@@ -1064,6 +1083,8 @@ i830InitStateFuncs(struct dd_function_table *functions)
functions->StencilFuncSeparate = i830StencilFuncSeparate;
functions->StencilMaskSeparate = i830StencilMaskSeparate;
functions->StencilOpSeparate = i830StencilOpSeparate;
+ functions->DepthRange = i830DepthRange;
+ functions->Viewport = i830Viewport;
}
void
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index 753c25b57e..6f998fa6f7 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -174,14 +174,16 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
(LOAD_TEXTURE_MAP0 << unit) | 4);
-/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */
-/* t->intel.TextureOffset); */
-
-
state[I830_TEXREG_TM0S1] =
(((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) |
((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format);
+ if (intelObj->mt->region->tiling != I915_TILING_NONE) {
+ state[I830_TEXREG_TM0S1] |= TM0S1_TILED_SURFACE;
+ if (intelObj->mt->region->tiling == I915_TILING_Y)
+ state[I830_TEXREG_TM0S1] |= TM0S1_TILE_WALK;
+ }
+
state[I830_TEXREG_TM0S2] =
((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK);
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 3bf02de61f..cbee9f9efe 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -552,7 +552,7 @@ i830_emit_state(struct intel_context *intel)
if (state->tex_buffer[i]) {
OUT_RELOC(state->tex_buffer[i],
I915_GEM_DOMAIN_SAMPLER, 0,
- state->tex_offset[i] | TM0S0_USE_FENCE);
+ state->tex_offset[i]);
}
else if (state == &i830->meta) {
assert(i == 0);
@@ -634,21 +634,11 @@ i830_state_draw_region(struct intel_context *intel,
/*
* Set stride/cpp values
*/
- if (color_region) {
- state->Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I830_DESTREG_CBUFADDR1] =
- (BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
- BUF_3D_USE_FENCE);
- }
+ i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_CBUFADDR0],
+ color_region, BUF_3D_ID_COLOR_BACK);
- if (depth_region) {
- state->Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I830_DESTREG_DBUFADDR1] =
- (BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
- BUF_3D_USE_FENCE);
- }
+ i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_DBUFADDR0],
+ depth_region, BUF_3D_ID_DEPTH);
/*
* Compute/set I830_DESTREG_DV1 value
@@ -718,26 +708,6 @@ i830_set_draw_region(struct intel_context *intel,
i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region);
}
-#if 0
-static void
-i830_update_color_z_regions(intelContextPtr intel,
- const intelRegion * colorRegion,
- const intelRegion * depthRegion)
-{
- i830ContextPtr i830 = I830_CONTEXT(intel);
-
- i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
- (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) |
- BUF_3D_USE_FENCE);
- i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset;
-
- i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
- (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE);
- i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset;
-}
-#endif
-
-
/* This isn't really handled at the moment.
*/
static void
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 1f9f363df9..367d2a3b64 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -73,7 +73,7 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
p->params_uptodate = 0;
}
- if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM))
+ if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))
i915_update_fog(ctx);
}
diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h
index 8891e11c6f..84db58ea95 100644
--- a/src/mesa/drivers/dri/i915/i915_reg.h
+++ b/src/mesa/drivers/dri/i915/i915_reg.h
@@ -93,20 +93,6 @@
/* 3DSTATE_BIN_CONTROL p141 */
-/* p143 */
-#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
-/* Dword 1 */
-#define BUF_3D_ID_COLOR_BACK (0x3<<24)
-#define BUF_3D_ID_DEPTH (0x7<<24)
-#define BUF_3D_USE_FENCE (1<<23)
-#define BUF_3D_TILED_SURFACE (1<<22)
-#define BUF_3D_TILE_WALK_X 0
-#define BUF_3D_TILE_WALK_Y (1<<21)
-#define BUF_3D_PITCH(x) (((x)/4)<<2)
-/* Dword 2 */
-#define BUF_3D_ADDR(x) ((x) & ~0x3)
-
-
/* 3DSTATE_CHROMA_KEY */
/* 3DSTATE_CLEAR_PARAMETERS, p150 */
@@ -155,6 +141,7 @@
/* p161 */
#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16))
/* Dword 1 */
+#define CLASSIC_EARLY_DEPTH (1<<31)
#define TEX_DEFAULT_COLOR_OGL (0<<30)
#define TEX_DEFAULT_COLOR_D3D (1<<30)
#define ZR_EARLY_DEPTH (1<<29)
diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c
index d44a2f47b3..d9588e5b56 100644
--- a/src/mesa/drivers/dri/i915/i915_tex_layout.c
+++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c
@@ -55,6 +55,17 @@ static GLint step_offsets[6][2] = {
[FACE_NEG_Z] = {-1, 1},
};
+
+static GLint bottom_offsets[6] = {
+ [FACE_POS_X] = 16 + 0 * 8,
+ [FACE_POS_Y] = 16 + 1 * 8,
+ [FACE_POS_Z] = 16 + 2 * 8,
+ [FACE_NEG_X] = 16 + 3 * 8,
+ [FACE_NEG_Y] = 16 + 4 * 8,
+ [FACE_NEG_Z] = 16 + 5 * 8,
+};
+
+
/**
* Cube texture map layout for i830M-GM915.
*
@@ -101,7 +112,8 @@ static GLint step_offsets[6][2] = {
*/
static void
i915_miptree_layout_cube(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
const GLuint dim = mt->width0;
GLuint face;
@@ -111,7 +123,7 @@ i915_miptree_layout_cube(struct intel_context *intel,
assert(lvlWidth == lvlHeight); /* cubemap images are square */
/* double pitch for cube layouts */
- mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, dim * 2);
mt->total_height = dim * 4;
for (level = mt->first_level; level <= mt->last_level; level++) {
@@ -145,7 +157,8 @@ i915_miptree_layout_cube(struct intel_context *intel,
static void
i915_miptree_layout_3d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
@@ -154,7 +167,7 @@ i915_miptree_layout_3d(struct intel_context *intel,
GLint level;
/* Calculate the size of a single slice. */
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
/* XXX: hardware expects/requires 9 levels at minimum. */
for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) {
@@ -189,14 +202,15 @@ i915_miptree_layout_3d(struct intel_context *intel,
static void
i915_miptree_layout_2d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
GLuint img_height;
GLint level;
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
mt->total_height = 0;
for (level = mt->first_level; level <= mt->last_level; level++) {
@@ -217,19 +231,20 @@ i915_miptree_layout_2d(struct intel_context *intel,
}
GLboolean
-i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
+i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
- i915_miptree_layout_cube(intel, mt);
+ i915_miptree_layout_cube(intel, mt, tiling);
break;
case GL_TEXTURE_3D:
- i915_miptree_layout_3d(intel, mt);
+ i915_miptree_layout_3d(intel, mt, tiling);
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
- i915_miptree_layout_2d(intel, mt);
+ i915_miptree_layout_2d(intel, mt, tiling);
break;
default:
_mesa_problem(NULL, "Unexpected tex target in i915_miptree_layout()");
@@ -297,7 +312,7 @@ i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
* +---+ +---+ +---+ +---+ +---+ +---+
*
* The bottom row continues with the remaining 2x2 then the 1x1 mip contents
- * in order, with each of them aligned to a 4x4 block boundary. Thus, for
+ * in order, with each of them aligned to a 8x8 block boundary. Thus, for
* 32x32 cube maps and smaller, the bottom row layout is going to dictate the
* pitch of the tree. For a tree with 4x4 images, the pitch is at least
* 14 * 8 = 112 texels, for 2x2 it is at least 12 * 8 texels, and for 1x1
@@ -306,7 +321,8 @@ i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
static void
i945_miptree_layout_cube(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
const GLuint dim = mt->width0;
GLuint face;
@@ -320,9 +336,9 @@ i945_miptree_layout_cube(struct intel_context *intel,
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32)
- mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, dim * 2);
else
- mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, 14 * 8);
if (dim >= 4)
mt->total_height = dim * 4 + 4;
@@ -375,10 +391,11 @@ i945_miptree_layout_cube(struct intel_context *intel,
x = (face - 4) * 8;
break;
}
+ break;
case 2:
y = mt->total_height - 4;
- x = 16 + face * 8;
+ x = bottom_offsets[face];
break;
case 1:
@@ -396,7 +413,8 @@ i945_miptree_layout_cube(struct intel_context *intel,
static void
i945_miptree_layout_3d(struct intel_context *intel,
- struct intel_mipmap_tree * mt)
+ struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
GLuint width = mt->width0;
GLuint height = mt->height0;
@@ -405,7 +423,7 @@ i945_miptree_layout_3d(struct intel_context *intel,
GLuint pack_y_pitch;
GLuint level;
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
mt->total_height = 0;
pack_y_pitch = MAX2(mt->height0, 2);
@@ -450,19 +468,23 @@ i945_miptree_layout_3d(struct intel_context *intel,
}
GLboolean
-i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)
+i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt,
+ uint32_t tiling)
{
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
- i945_miptree_layout_cube(intel, mt);
+ if (mt->compressed)
+ i945_miptree_layout_cube(intel, mt, tiling);
+ else
+ i915_miptree_layout_cube(intel, mt, tiling);
break;
case GL_TEXTURE_3D:
- i945_miptree_layout_3d(intel, mt);
+ i945_miptree_layout_3d(intel, mt, tiling);
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_RECTANGLE_ARB:
- i945_miptree_layout_2d(intel, mt);
+ i945_miptree_layout_2d(intel, mt, tiling);
break;
default:
_mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()");
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index a37dd7f4fb..32d4b30cf9 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -185,8 +185,13 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
state[I915_TEXREG_MS3] =
(((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
- ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format |
- MS3_USE_FENCE_REGS);
+ ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format);
+
+ if (intelObj->mt->region->tiling != I915_TILING_NONE) {
+ state[I915_TEXREG_MS3] |= MS3_TILED_SURFACE;
+ if (intelObj->mt->region->tiling == I915_TILING_Y)
+ state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
+ }
state[I915_TEXREG_MS4] =
((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 115004616f..2fca247af1 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -42,6 +42,7 @@
#include "intel_regions.h"
#include "intel_tris.h"
#include "intel_fbo.h"
+#include "intel_chipset.h"
#include "i915_reg.h"
#include "i915_context.h"
@@ -529,6 +530,23 @@ i915_destroy_context(struct intel_context *intel)
_tnl_free_vertices(&intel->ctx);
}
+void
+i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region,
+ uint32_t buffer_id)
+{
+ state[0] = _3DSTATE_BUF_INFO_CMD;
+ state[1] = buffer_id;
+
+ if (region != NULL) {
+ state[1] |= BUF_3D_PITCH(region->pitch * region->cpp);
+
+ if (region->tiling != I915_TILING_NONE) {
+ state[1] |= BUF_3D_TILED_SURFACE;
+ if (region->tiling == I915_TILING_Y)
+ state[1] |= BUF_3D_TILE_WALK_Y;
+ }
+ }
+}
/**
* Set the drawing regions for the color and depth/stencil buffers.
@@ -562,21 +580,11 @@ i915_state_draw_region(struct intel_context *intel,
/*
* Set stride/cpp values
*/
- if (color_region) {
- state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I915_DESTREG_CBUFADDR1] =
- (BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
- BUF_3D_USE_FENCE);
- }
+ i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_CBUFADDR0],
+ color_region, BUF_3D_ID_COLOR_BACK);
- if (depth_region) {
- state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I915_DESTREG_DBUFADDR1] =
- (BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
- BUF_3D_USE_FENCE);
- }
+ i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_DBUFADDR0],
+ depth_region, BUF_3D_ID_DEPTH);
/*
* Compute/set I915_DESTREG_DV1 value
@@ -604,6 +612,14 @@ i915_state_draw_region(struct intel_context *intel,
}
}
+ /* This isn't quite safe, thus being hidden behind an option. When changing
+ * the value of this bit, the pipeline needs to be MI_FLUSHed. And it
+ * can only be set when a depth buffer is already defined.
+ */
+ if (IS_945(intel->intelScreen->deviceID) && intel->use_early_z &&
+ depth_region->tiling != I915_TILING_NONE)
+ value |= CLASSIC_EARLY_DEPTH;
+
if (depth_region && depth_region->cpp == 4) {
value |= DEPTH_FRMT_24_FIXED_8_OTHER;
}
diff --git a/src/mesa/drivers/dri/i915/intel_generatemipmap.c b/src/mesa/drivers/dri/i915/intel_generatemipmap.c
new file mode 120000
index 0000000000..4c6b37ada0
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_generatemipmap.c
@@ -0,0 +1 @@
+../intel/intel_generatemipmap.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 2934414d99..9712c38725 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -14,6 +14,7 @@ DRIVER_SOURCES = \
intel_decode.c \
intel_extensions.c \
intel_fbo.c \
+ intel_generatemipmap.c \
intel_mipmap_tree.c \
intel_regions.c \
intel_screen.c \
@@ -69,6 +70,7 @@ DRIVER_SOURCES = \
brw_vs_constval.c \
brw_vs_emit.c \
brw_vs_state.c \
+ brw_vs_surface_state.c \
brw_vtbl.c \
brw_wm.c \
brw_wm_debug.c \
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index aef2ff5f86..873fc8ffff 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -131,6 +131,7 @@ struct brw_context;
#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
#define BRW_NEW_INDICES 0x4000
#define BRW_NEW_VERTICES 0x8000
@@ -245,6 +246,9 @@ 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
@@ -450,8 +454,6 @@ struct brw_context
struct {
struct brw_state_flags dirty;
- struct brw_tracked_state **atoms;
- GLuint nr_atoms;
GLuint nr_color_regions;
struct intel_region *color_regions[MAX_DRAW_BUFFERS];
@@ -471,7 +473,8 @@ struct brw_context
int validated_bo_count;
} state;
- struct brw_cache cache;
+ struct brw_cache cache; /** non-surface items */
+ struct brw_cache surface_cache; /* surface items */
struct brw_cached_batch_item *cached_batch_items;
struct {
@@ -555,11 +558,6 @@ struct brw_context
GLuint vs_size;
GLuint total_size;
- /* Dynamic tracker which changes to reflect the state referenced
- * by active fp and vp program parameters:
- */
- struct brw_tracked_state tracked_state;
-
dri_bo *curbe_bo;
/** Offset within curbe_bo of space for current curbe entry */
GLuint curbe_offset;
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 9197fede2d..a1a6c53d0e 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -36,6 +36,7 @@
#include "main/macros.h"
#include "main/enums.h"
#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#include "intel_batchbuffer.h"
#include "intel_regions.h"
@@ -188,13 +189,6 @@ static void prepare_constant_buffer(struct brw_context *brw)
GLfloat *buf;
GLuint i;
- /* Update our own dependency flags. This works because this
- * function will also be called whenever fp or vp changes.
- */
- brw->curbe.tracked_state.dirty.mesa = (_NEW_TRANSFORM|_NEW_PROJECTION);
- brw->curbe.tracked_state.dirty.mesa |= vp->program.Base.Parameters->StateFlags;
- brw->curbe.tracked_state.dirty.mesa |= fp->program.Base.Parameters->StateFlags;
-
if (sz == 0) {
if (brw->curbe.last_buf) {
free(brw->curbe.last_buf);
@@ -335,78 +329,11 @@ static void prepare_constant_buffer(struct brw_context *brw)
*/
}
-
-/**
- * Copy Mesa program parameters into given constant buffer.
- */
-static void
-update_constant_buffer(struct brw_context *brw,
- const struct gl_program_parameter_list *params,
- dri_bo *const_buffer)
-{
- struct intel_context *intel = &brw->intel;
- const int size = params->NumParameters * 4 * sizeof(GLfloat);
-
- /* copy Mesa program constants into the buffer */
- if (const_buffer && size > 0) {
-
- assert(const_buffer);
- assert(const_buffer->size >= size);
-
- if (intel->intelScreen->kernel_exec_fencing) {
- drm_intel_gem_bo_map_gtt(const_buffer);
- memcpy(const_buffer->virtual, params->ParameterValues, size);
- drm_intel_gem_bo_unmap_gtt(const_buffer);
- }
- else {
- dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
- }
-
- if (0) {
- int i;
- for (i = 0; i < params->NumParameters; i++) {
- float *p = params->ParameterValues[i];
- printf("%d: %f %f %f %f\n", i, p[0], p[1], p[2], p[3]);
- }
- }
- }
-}
-
-
-/** Copy current vertex program's parameters into the constant buffer */
-static void
-update_vertex_constant_buffer(struct brw_context *brw)
-{
- struct brw_vertex_program *vp =
- (struct brw_vertex_program *) brw->vertex_program;
- if (0) {
- printf("update VS constants in buffer %p\n", vp->const_buffer);
- printf("program %u\n", vp->program.Base.Id);
- }
- if (vp->use_const_buffer)
- update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer);
-}
-
-
-/** Copy current fragment program's parameters into the constant buffer */
-static void
-update_fragment_constant_buffer(struct brw_context *brw)
-{
- struct brw_fragment_program *fp =
- (struct brw_fragment_program *) brw->fragment_program;
- if (fp->use_const_buffer)
- update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer);
-}
-
-
static void emit_constant_buffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
GLuint sz = brw->curbe.total_size;
- update_vertex_constant_buffer(brw);
- update_fragment_constant_buffer(brw);
-
BEGIN_BATCH(2, IGNORE_CLIPRECTS);
if (sz == 0) {
OUT_BATCH((CMD_CONST_BUFFER << 16) | (2 - 2));
@@ -428,7 +355,7 @@ static void emit_constant_buffer(struct brw_context *brw)
*/
const struct brw_tracked_state brw_constant_buffer = {
.dirty = {
- .mesa = (_NEW_TRANSFORM|_NEW_PROJECTION), /* plus fp and vp flags */
+ .mesa = _NEW_PROGRAM_CONSTANTS,
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_VERTEX_PROGRAM |
BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index b91b20bec6..1b8bcc14ec 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -343,7 +343,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- GLuint tmp = brw->vs.prog_data->inputs_read;
+ GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
GLuint i;
const unsigned char *ptr = NULL;
GLuint interleave = 0;
@@ -362,11 +362,11 @@ static void brw_prepare_vertices(struct brw_context *brw)
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
/* Accumulate the list of enabled arrays. */
- while (tmp) {
- GLuint i = _mesa_ffsll(tmp)-1;
+ while (vs_inputs) {
+ GLuint i = _mesa_ffsll(vs_inputs) - 1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
- tmp &= ~(1<<i);
+ vs_inputs &= ~(1 << i);
enabled[nr_enabled++] = input;
}
@@ -477,17 +477,17 @@ static void brw_emit_vertices(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- GLuint tmp = brw->vs.prog_data->inputs_read;
+ GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
GLuint i;
GLuint nr_enabled = 0;
/* Accumulate the list of enabled arrays. */
- while (tmp) {
- i = _mesa_ffsll(tmp)-1;
+ while (vs_inputs) {
+ i = _mesa_ffsll(vs_inputs) - 1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
- tmp &= ~(1<<i);
+ vs_inputs &= ~(1 << i);
enabled[nr_enabled++] = input;
}
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 62c98bd8bb..bc7756ceab 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -97,7 +97,7 @@ struct brw_glsl_call;
#define BRW_EU_MAX_INSN_STACK 5
-#define BRW_EU_MAX_INSN 4000
+#define BRW_EU_MAX_INSN 10000
struct brw_compile {
struct brw_instruction store[BRW_EU_MAX_INSN];
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 9bc5c35139..4784254bc7 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -118,7 +118,10 @@ static void upload_binding_table_pointers(struct brw_context *brw)
BEGIN_BATCH(6, IGNORE_CLIPRECTS);
OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2));
- OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */
+ if (brw->vs.bind_bo != NULL)
+ OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */
+ else
+ OUT_BATCH(0);
OUT_BATCH(0); /* gs */
OUT_BATCH(0); /* clip */
OUT_BATCH(0); /* sf */
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 68fa9820b6..c99918724b 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -66,7 +66,9 @@ static void upload_sf_vp(struct brw_context *brw)
sfv.viewport.m31 = v[MAT_TY] * y_scale + y_bias;
sfv.viewport.m32 = v[MAT_TZ] * depth_scale;
- /* _NEW_SCISSOR */
+ /* _NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT
+ * for DrawBuffer->_[XY]{min,max}
+ */
/* The scissor only needs to handle the intersection of drawable and
* scissor rect. Clipping to the boundaries of static shared buffers
@@ -97,7 +99,8 @@ static void upload_sf_vp(struct brw_context *brw)
const struct brw_tracked_state brw_sf_vp = {
.dirty = {
.mesa = (_NEW_VIEWPORT |
- _NEW_SCISSOR),
+ _NEW_SCISSOR |
+ _NEW_BUFFERS),
.brw = 0,
.cache = 0
},
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 81b0a45998..bf9f6cae55 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -72,11 +72,13 @@ const struct brw_tracked_state brw_sf_vp;
const struct brw_tracked_state brw_state_base_address;
const struct brw_tracked_state brw_urb_fence;
const struct brw_tracked_state brw_vertex_state;
+const struct brw_tracked_state brw_vs_surfaces;
const struct brw_tracked_state brw_vs_prog;
const struct brw_tracked_state brw_vs_unit;
const struct brw_tracked_state brw_wm_input_sizes;
const struct brw_tracked_state brw_wm_prog;
const struct brw_tracked_state brw_wm_samplers;
+const struct brw_tracked_state brw_wm_constant_surface;
const struct brw_tracked_state brw_wm_surfaces;
const struct brw_tracked_state brw_wm_unit;
@@ -91,6 +93,20 @@ const struct brw_tracked_state brw_drawing_rect;
const struct brw_tracked_state brw_indices;
const struct brw_tracked_state brw_vertices;
+/**
+ * Use same key for WM and VS surfaces.
+ */
+struct brw_surface_key {
+ GLenum target, depthmode;
+ dri_bo *bo;
+ GLint format, internal_format;
+ GLint first_level, last_level;
+ GLint width, height, depth;
+ GLint pitch, cpp;
+ uint32_t tiling;
+ GLuint offset;
+};
+
/***********************************************************************
* brw_state.c
*/
@@ -135,8 +151,8 @@ dri_bo *brw_search_cache( struct brw_cache *cache,
void *aux_return);
void brw_state_cache_check_size( struct brw_context *brw );
-void brw_init_cache( struct brw_context *brw );
-void brw_destroy_cache( struct brw_context *brw );
+void brw_init_caches( struct brw_context *brw );
+void brw_destroy_caches( struct brw_context *brw );
/***********************************************************************
* brw_state_batch.c
@@ -150,4 +166,9 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
void brw_destroy_batch_cache( struct brw_context *brw );
void brw_clear_batch_cache_flush( struct brw_context *brw );
+/* brw_wm_surface_state.c */
+dri_bo *
+brw_create_constant_surface( struct brw_context *brw,
+ struct brw_surface_key *key );
+
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index d5b5166406..e40d7a0416 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -56,9 +56,9 @@
* incorrect program is run for the other instance.
*/
+#include "main/imports.h"
#include "brw_state.h"
#include "intel_batchbuffer.h"
-#include "main/imports.h"
/* XXX: Fixme - have to include these to get the sizes of the prog_key
* structs:
@@ -69,8 +69,10 @@
#include "brw_sf.h"
#include "brw_gs.h"
-static GLuint hash_key( const void *key, GLuint key_size,
- dri_bo **reloc_bufs, GLuint nr_reloc_bufs)
+
+static GLuint
+hash_key(const void *key, GLuint key_size,
+ dri_bo **reloc_bufs, GLuint nr_reloc_bufs)
{
GLuint *ikey = (GLuint *)key;
GLuint hash = 0, i;
@@ -95,6 +97,7 @@ static GLuint hash_key( const void *key, GLuint key_size,
return hash;
}
+
/**
* Marks a new buffer as being chosen for the given cache id.
*/
@@ -111,6 +114,7 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
cache->brw->state.dirty.cache |= 1 << cache_id;
}
+
static struct brw_cache_item *
search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
GLuint hash, const void *key, GLuint key_size,
@@ -143,7 +147,8 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
}
-static void rehash( struct brw_cache *cache )
+static void
+rehash(struct brw_cache *cache)
{
struct brw_cache_item **items;
struct brw_cache_item *c, *next;
@@ -164,15 +169,17 @@ static void rehash( struct brw_cache *cache )
cache->size = size;
}
+
/**
* Returns the buffer object matching cache_id and key, or NULL.
*/
-dri_bo *brw_search_cache( struct brw_cache *cache,
- enum brw_cache_id cache_id,
- const void *key,
- GLuint key_size,
- dri_bo **reloc_bufs, GLuint nr_reloc_bufs,
- void *aux_return )
+dri_bo *
+brw_search_cache(struct brw_cache *cache,
+ enum brw_cache_id cache_id,
+ const void *key,
+ GLuint key_size,
+ dri_bo **reloc_bufs, GLuint nr_reloc_bufs,
+ void *aux_return)
{
struct brw_cache_item *item;
GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs);
@@ -192,6 +199,7 @@ dri_bo *brw_search_cache( struct brw_cache *cache,
return item->bo;
}
+
dri_bo *
brw_upload_cache( struct brw_cache *cache,
enum brw_cache_id cache_id,
@@ -265,7 +273,9 @@ brw_upload_cache( struct brw_cache *cache,
return bo;
}
-/* This doesn't really work with aux data. Use search/upload instead
+
+/**
+ * This doesn't really work with aux data. Use search/upload instead
*/
dri_bo *
brw_cache_data_sz(struct brw_cache *cache,
@@ -296,6 +306,7 @@ brw_cache_data_sz(struct brw_cache *cache,
return bo;
}
+
/**
* Wrapper around brw_cache_data_sz using the cache_id's canonical key size.
*
@@ -319,21 +330,22 @@ enum pool_type {
DW_GENERAL_STATE
};
+
static void
-brw_init_cache_id( struct brw_context *brw,
- const char *name,
- enum brw_cache_id id,
- GLuint key_size,
- GLuint aux_size)
+brw_init_cache_id(struct brw_cache *cache,
+ const char *name,
+ enum brw_cache_id id,
+ GLuint key_size,
+ GLuint aux_size)
{
- struct brw_cache *cache = &brw->cache;
-
cache->name[id] = strdup(name);
cache->key_size[id] = key_size;
cache->aux_size[id] = aux_size;
}
-void brw_init_cache( struct brw_context *brw )
+
+static void
+brw_init_non_surface_cache(struct brw_context *brw)
{
struct brw_cache *cache = &brw->cache;
@@ -342,114 +354,136 @@ void brw_init_cache( struct brw_context *brw )
cache->size = 7;
cache->n_items = 0;
cache->items = (struct brw_cache_item **)
- _mesa_calloc(cache->size *
- sizeof(struct brw_cache_item));
+ _mesa_calloc(cache->size * sizeof(struct brw_cache_item));
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"CC_VP",
BRW_CC_VP,
sizeof(struct brw_cc_viewport),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"CC_UNIT",
BRW_CC_UNIT,
sizeof(struct brw_cc_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"WM_PROG",
BRW_WM_PROG,
sizeof(struct brw_wm_prog_key),
sizeof(struct brw_wm_prog_data));
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SAMPLER_DEFAULT_COLOR",
BRW_SAMPLER_DEFAULT_COLOR,
sizeof(struct brw_sampler_default_color),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SAMPLER",
BRW_SAMPLER,
0, /* variable key/data size */
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"WM_UNIT",
BRW_WM_UNIT,
sizeof(struct brw_wm_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SF_PROG",
BRW_SF_PROG,
sizeof(struct brw_sf_prog_key),
sizeof(struct brw_sf_prog_data));
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SF_VP",
BRW_SF_VP,
sizeof(struct brw_sf_viewport),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SF_UNIT",
BRW_SF_UNIT,
sizeof(struct brw_sf_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"VS_UNIT",
BRW_VS_UNIT,
sizeof(struct brw_vs_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"VS_PROG",
BRW_VS_PROG,
sizeof(struct brw_vs_prog_key),
sizeof(struct brw_vs_prog_data));
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"CLIP_UNIT",
BRW_CLIP_UNIT,
sizeof(struct brw_clip_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"CLIP_PROG",
BRW_CLIP_PROG,
sizeof(struct brw_clip_prog_key),
sizeof(struct brw_clip_prog_data));
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"GS_UNIT",
BRW_GS_UNIT,
sizeof(struct brw_gs_unit_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"GS_PROG",
BRW_GS_PROG,
sizeof(struct brw_gs_prog_key),
sizeof(struct brw_gs_prog_data));
+}
+
+
+static void
+brw_init_surface_cache(struct brw_context *brw)
+{
+ struct brw_cache *cache = &brw->surface_cache;
+
+ cache->brw = brw;
- brw_init_cache_id(brw,
+ cache->size = 7;
+ cache->n_items = 0;
+ cache->items = (struct brw_cache_item **)
+ _mesa_calloc(cache->size * sizeof(struct brw_cache_item));
+
+ brw_init_cache_id(cache,
"SS_SURFACE",
BRW_SS_SURFACE,
sizeof(struct brw_surface_state),
0);
- brw_init_cache_id(brw,
+ brw_init_cache_id(cache,
"SS_SURF_BIND",
BRW_SS_SURF_BIND,
0,
0);
}
+
+void
+brw_init_caches(struct brw_context *brw)
+{
+ brw_init_non_surface_cache(brw);
+ brw_init_surface_cache(brw);
+}
+
+
static void
-brw_clear_cache( struct brw_context *brw )
+brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
{
struct brw_cache_item *c, *next;
GLuint i;
@@ -457,8 +491,8 @@ brw_clear_cache( struct brw_context *brw )
if (INTEL_DEBUG & DEBUG_STATE)
_mesa_printf("%s\n", __FUNCTION__);
- for (i = 0; i < brw->cache.size; i++) {
- for (c = brw->cache.items[i]; c; c = next) {
+ for (i = 0; i < cache->size; i++) {
+ for (c = cache->items[i]; c; c = next) {
int j;
next = c->next;
@@ -468,10 +502,10 @@ brw_clear_cache( struct brw_context *brw )
free((void *)c->key);
free(c);
}
- brw->cache.items[i] = NULL;
+ cache->items[i] = NULL;
}
- brw->cache.n_items = 0;
+ cache->n_items = 0;
if (brw->curbe.last_buf) {
_mesa_free(brw->curbe.last_buf);
@@ -483,25 +517,46 @@ brw_clear_cache( struct brw_context *brw )
brw->state.dirty.cache |= ~0;
}
-void brw_state_cache_check_size( struct brw_context *brw )
+
+void
+brw_state_cache_check_size(struct brw_context *brw)
{
+ if (INTEL_DEBUG & DEBUG_STATE)
+ _mesa_printf("%s (n_items=%d)\n", __FUNCTION__, brw->cache.n_items);
+
/* un-tuned guess. We've got around 20 state objects for a total of around
* 32k, so 1000 of them is around 1.5MB.
*/
if (brw->cache.n_items > 1000)
- brw_clear_cache(brw);
+ brw_clear_cache(brw, &brw->cache);
+
+ if (brw->surface_cache.n_items > 1000)
+ brw_clear_cache(brw, &brw->surface_cache);
}
-void brw_destroy_cache( struct brw_context *brw )
+
+static void
+brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
{
GLuint i;
- brw_clear_cache(brw);
+ if (INTEL_DEBUG & DEBUG_STATE)
+ _mesa_printf("%s\n", __FUNCTION__);
+
+ brw_clear_cache(brw, cache);
for (i = 0; i < BRW_MAX_CACHE; i++) {
- dri_bo_unreference(brw->cache.last_bo[i]);
- free(brw->cache.name[i]);
+ dri_bo_unreference(cache->last_bo[i]);
+ free(cache->name[i]);
}
- free(brw->cache.items);
- brw->cache.items = NULL;
- brw->cache.size = 0;
+ free(cache->items);
+ cache->items = NULL;
+ cache->size = 0;
+}
+
+
+void
+brw_destroy_caches(struct brw_context *brw)
+{
+ brw_destroy_cache(brw, &brw->cache);
+ brw_destroy_cache(brw, &brw->surface_cache);
}
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 5de1450e61..c6dfea4743 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -59,11 +59,12 @@ const struct brw_tracked_state *atoms[] =
&brw_curbe_offsets,
&brw_recalculate_urb_fence,
-
&brw_cc_vp,
&brw_cc_unit,
- &brw_wm_surfaces, /* must do before samplers */
+ &brw_vs_surfaces, /* must do before unit */
+ &brw_wm_constant_surface, /* must do before wm surfaces/bind bo */
+ &brw_wm_surfaces, /* must do before samplers and unit */
&brw_wm_samplers,
&brw_wm_unit,
@@ -88,54 +89,26 @@ const struct brw_tracked_state *atoms[] =
&brw_line_stipple,
&brw_aa_line_parameters,
- /* Ordering of the commands below is documented as fixed.
- */
-#if 0
- &brw_pipelined_state_pointers,
- &brw_urb_fence,
- &brw_constant_buffer_state,
-#else
+
&brw_psp_urb_cbs,
-#endif
&brw_drawing_rect,
&brw_indices,
&brw_vertices,
- NULL, /* brw_constant_buffer */
+ &brw_constant_buffer
};
void brw_init_state( struct brw_context *brw )
{
- GLuint i;
-
- brw_init_cache(brw);
-
- brw->state.atoms = _mesa_malloc(sizeof(atoms));
- brw->state.nr_atoms = sizeof(atoms)/sizeof(*atoms);
- _mesa_memcpy(brw->state.atoms, atoms, sizeof(atoms));
-
- /* Patch in a pointer to the dynamic state atom:
- */
- for (i = 0; i < brw->state.nr_atoms; i++)
- if (brw->state.atoms[i] == NULL)
- brw->state.atoms[i] = &brw->curbe.tracked_state;
-
- _mesa_memcpy(&brw->curbe.tracked_state,
- &brw_constant_buffer,
- sizeof(brw_constant_buffer));
+ brw_init_caches(brw);
}
void brw_destroy_state( struct brw_context *brw )
{
- if (brw->state.atoms) {
- _mesa_free(brw->state.atoms);
- brw->state.atoms = NULL;
- }
-
- brw_destroy_cache(brw);
+ brw_destroy_caches(brw);
brw_destroy_batch_cache(brw);
}
@@ -218,6 +191,7 @@ static struct dirty_bit_map mesa_bits[] = {
DEFINE_BIT(_NEW_MULTISAMPLE),
DEFINE_BIT(_NEW_TRACK_MATRIX),
DEFINE_BIT(_NEW_PROGRAM),
+ DEFINE_BIT(_NEW_PROGRAM_CONSTANTS),
{0, 0, 0}
};
@@ -336,7 +310,7 @@ void brw_validate_state( struct brw_context *brw )
/* do prepare stage for all atoms */
for (i = 0; i < Elements(atoms); i++) {
- const struct brw_tracked_state *atom = brw->state.atoms[i];
+ const struct brw_tracked_state *atom = atoms[i];
if (brw->intel.Fallback)
break;
@@ -367,8 +341,8 @@ void brw_upload_state(struct brw_context *brw)
_mesa_memset(&examined, 0, sizeof(examined));
prev = *state;
- for (i = 0; i < brw->state.nr_atoms; i++) {
- const struct brw_tracked_state *atom = brw->state.atoms[i];
+ for (i = 0; i < Elements(atoms); i++) {
+ const struct brw_tracked_state *atom = atoms[i];
struct brw_state_flags generated;
assert(atom->dirty.mesa ||
@@ -397,7 +371,7 @@ void brw_upload_state(struct brw_context *brw)
}
else {
for (i = 0; i < Elements(atoms); i++) {
- const struct brw_tracked_state *atom = brw->state.atoms[i];
+ const struct brw_tracked_state *atom = atoms[i];
if (brw->intel.Fallback)
break;
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 51a617fcb4..5c5455813a 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -28,7 +28,6 @@
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-
/* Code to layout images in a mipmap tree for i965.
*/
@@ -40,14 +39,15 @@
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
-GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_tree *mt )
+GLboolean brw_miptree_layout(struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling)
{
- /* XXX: these vary depending on image format:
- */
-/* GLint align_w = 4; */
+ /* XXX: these vary depending on image format: */
+ /* GLint align_w = 4; */
switch (mt->target) {
- case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_3D: {
GLuint width = mt->width0;
GLuint height = mt->height0;
@@ -59,25 +59,25 @@ GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_t
GLuint align_w = 4;
mt->total_height = 0;
-
+
if (mt->compressed) {
align_w = intel_compressed_alignment(mt->internal_format);
mt->pitch = ALIGN(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else {
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);
- pack_y_pitch = ALIGN(mt->height0, align_h);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->width0);
+ pack_y_pitch = ALIGN(mt->height0, align_h);
}
pack_x_pitch = mt->pitch;
pack_x_nr = 1;
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+ for (level = mt->first_level ; level <= mt->last_level ; level++) {
GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6;
GLint x = 0;
GLint y = 0;
GLint q, j;
-
+
intel_miptree_set_level_info(mt, level, nr_images,
0, mt->total_height,
width, height, depth);
@@ -89,7 +89,7 @@ GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_t
}
x = 0;
- y += pack_y_pitch;
+ y += pack_y_pitch;
}
@@ -98,40 +98,40 @@ GLboolean brw_miptree_layout( struct intel_context *intel, struct intel_mipmap_t
height = minify(height);
depth = minify(depth);
- if (mt->compressed) {
- pack_y_pitch = (height + 3) / 4;
-
- if (pack_x_pitch > ALIGN(width, align_w)) {
- pack_x_pitch = ALIGN(width, align_w);
- pack_x_nr <<= 1;
- }
- } else {
- if (pack_x_pitch > 4) {
- pack_x_pitch >>= 1;
- pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->pitch);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- pack_y_pitch = ALIGN(pack_y_pitch, align_h);
- }
- }
+ if (mt->compressed) {
+ pack_y_pitch = (height + 3) / 4;
+
+ if (pack_x_pitch > ALIGN(width, align_w)) {
+ pack_x_pitch = ALIGN(width, align_w);
+ pack_x_nr <<= 1;
+ }
+ } else {
+ if (pack_x_pitch > 4) {
+ pack_x_pitch >>= 1;
+ pack_x_nr <<= 1;
+ assert(pack_x_pitch * pack_x_nr <= mt->pitch);
+ }
+
+ if (pack_y_pitch > 2) {
+ pack_y_pitch >>= 1;
+ pack_y_pitch = ALIGN(pack_y_pitch, align_h);
+ }
+ }
}
break;
}
default:
- i945_miptree_layout_2d(intel, mt);
+ i945_miptree_layout_2d(intel, mt, tiling);
break;
}
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
+ DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+ mt->pitch,
mt->total_height,
mt->cpp,
mt->pitch * mt->total_height * mt->cpp );
-
+
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index b69616d6e5..d7f75e3685 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -69,13 +69,18 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
{
GLuint i, reg = 0, mrf;
-#if 0
- if (c->vp->program.Base.Parameters->NumParameters >= 6)
- c->vp->use_const_buffer = 1;
+ /* Determine whether to use a real constant buffer or use a block
+ * of GRF registers for constants. The later is faster but only
+ * works if everything fits in the GRF.
+ * XXX this heuristic/check may need some fine tuning...
+ */
+ if (c->vp->program.Base.Parameters->NumParameters +
+ c->vp->program.Base.NumTemporaries + 20 > BRW_MAX_GRF)
+ c->vp->use_const_buffer = GL_TRUE;
else
-#endif
c->vp->use_const_buffer = GL_FALSE;
- /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/
+
+ /*printf("use_const_buffer = %d\n", c->vp->use_const_buffer);*/
/* r0 -- reserved as usual
*/
@@ -709,10 +714,11 @@ get_constant(struct brw_vs_compile *c,
struct brw_compile *p = &c->func;
struct brw_reg const_reg;
struct brw_reg const2_reg;
+ const GLboolean relAddr = src->RelAddr;
assert(argIndex < 3);
- if (c->current_const[argIndex].index != src->Index || src->RelAddr) {
+ if (c->current_const[argIndex].index != src->Index || relAddr) {
struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
c->current_const[argIndex].index = src->Index;
@@ -725,13 +731,13 @@ get_constant(struct brw_vs_compile *c,
brw_dp_READ_4_vs(p,
c->current_const[argIndex].reg,/* writeback dest */
0, /* oword */
- src->RelAddr, /* relative indexing? */
+ relAddr, /* relative indexing? */
addrReg, /* address register */
16 * src->Index, /* byte offset */
SURF_INDEX_VERT_CONST_BUFFER /* binding table index */
);
- if (src->RelAddr) {
+ if (relAddr) {
/* second read */
const2_reg = get_tmp(c);
@@ -742,7 +748,7 @@ get_constant(struct brw_vs_compile *c,
brw_dp_READ_4_vs(p,
const2_reg, /* writeback dest */
1, /* oword */
- src->RelAddr, /* relative indexing? */
+ relAddr, /* relative indexing? */
addrReg, /* address register */
16 * src->Index, /* byte offset */
SURF_INDEX_VERT_CONST_BUFFER
@@ -752,7 +758,7 @@ get_constant(struct brw_vs_compile *c,
const_reg = c->current_const[argIndex].reg;
- if (src->RelAddr) {
+ if (relAddr) {
/* merge the two Owords into the constant register */
/* const_reg[7..4] = const2_reg[7..4] */
brw_MOV(p,
@@ -1219,7 +1225,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
for (insn = 0; insn < nr_insns; insn++) {
- struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
+ const struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
struct brw_reg args[3], dst;
GLuint i;
@@ -1232,7 +1238,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
*/
if (inst->Opcode != OPCODE_SWZ)
for (i = 0; i < 3; i++) {
- struct prog_src_register *src = &inst->SrcReg[i];
+ const struct prog_src_register *src = &inst->SrcReg[i];
index = src->Index;
file = src->File;
if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
new file mode 100644
index 0000000000..89f47522a1
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -0,0 +1,226 @@
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "main/mtypes.h"
+#include "main/texformat.h"
+#include "main/texstore.h"
+#include "shader/prog_parameter.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+
+/* Creates a new VS constant buffer reflecting the current VS program's
+ * constants, if needed by the VS program.
+ *
+ * Otherwise, constants go through the CURBEs using the brw_constant_buffer
+ * state atom.
+ */
+static drm_intel_bo *
+brw_vs_update_constant_buffer(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ struct brw_vertex_program *vp =
+ (struct brw_vertex_program *) brw->vertex_program;
+ const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
+ const int size = params->NumParameters * 4 * sizeof(GLfloat);
+ drm_intel_bo *const_buffer;
+
+ /* BRW_NEW_VERTEX_PROGRAM */
+ if (!vp->use_const_buffer)
+ return NULL;
+
+ const_buffer = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
+ size, 64);
+
+ /* _NEW_PROGRAM_CONSTANTS */
+ dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
+
+ return const_buffer;
+}
+
+/**
+ * Update the surface state for a VS constant buffer.
+ *
+ * Sets brw->vs.surf_bo[surf] and brw->vp->const_buffer.
+ */
+static void
+brw_update_vs_constant_surface( GLcontext *ctx,
+ GLuint surf)
+{
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_surface_key key;
+ struct brw_vertex_program *vp =
+ (struct brw_vertex_program *) brw->vertex_program;
+ const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
+
+ assert(surf == 0);
+
+ /* If we're in this state update atom, we need to update VS constants, so
+ * free the old buffer and create a new one for the new contents.
+ */
+ dri_bo_unreference(vp->const_buffer);
+ vp->const_buffer = brw_vs_update_constant_buffer(brw);
+
+ /* If there's no constant buffer, then no surface BO is needed to point at
+ * it.
+ */
+ if (vp->const_buffer == 0) {
+ drm_intel_bo_unreference(brw->vs.surf_bo[surf]);
+ brw->vs.surf_bo[surf] = NULL;
+ return;
+ }
+
+ memset(&key, 0, sizeof(key));
+
+ key.format = MESA_FORMAT_RGBA_FLOAT32;
+ key.internal_format = GL_RGBA;
+ key.bo = vp->const_buffer;
+ key.depthmode = GL_NONE;
+ key.pitch = params->NumParameters;
+ key.width = params->NumParameters;
+ key.height = 1;
+ key.depth = 1;
+ key.cpp = 16;
+
+ /*
+ printf("%s:\n", __FUNCTION__);
+ printf(" width %d height %d depth %d cpp %d pitch %d\n",
+ key.width, key.height, key.depth, key.cpp, key.pitch);
+ */
+
+ drm_intel_bo_unreference(brw->vs.surf_bo[surf]);
+ brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &key.bo, key.bo ? 1 : 0,
+ NULL);
+ if (brw->vs.surf_bo[surf] == NULL) {
+ brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key);
+ }
+}
+
+
+/**
+ * Constructs the binding table for the VS surface state.
+ */
+static dri_bo *
+brw_vs_get_binding_table(struct brw_context *brw)
+{
+ dri_bo *bind_bo;
+
+ bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
+ NULL, 0,
+ brw->vs.surf_bo, BRW_VS_MAX_SURF,
+ NULL);
+
+ if (bind_bo == NULL) {
+ GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint);
+ uint32_t *data = malloc(data_size);
+ int i;
+
+ for (i = 0; i < BRW_VS_MAX_SURF; i++)
+ if (brw->vs.surf_bo[i])
+ data[i] = brw->vs.surf_bo[i]->offset;
+ else
+ data[i] = 0;
+
+ bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
+ NULL, 0,
+ brw->vs.surf_bo, BRW_VS_MAX_SURF,
+ data, data_size,
+ NULL, NULL);
+
+ /* Emit binding table relocations to surface state */
+ for (i = 0; i < BRW_VS_MAX_SURF; i++) {
+ if (brw->vs.surf_bo[i] != NULL) {
+ /* The presumed offsets were set in the data values for
+ * brw_upload_cache.
+ */
+ drm_intel_bo_emit_reloc(bind_bo, i * 4,
+ brw->vs.surf_bo[i], 0,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+ }
+ }
+
+ free(data);
+ }
+
+ return bind_bo;
+}
+
+/**
+ * Vertex shader surfaces (constant buffer).
+ *
+ * This consumes the state updates for the constant buffer needing
+ * to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and
+ * CACHE_NEW_SURF_BIND for the binding table upload.
+ */
+static void prepare_vs_surfaces(struct brw_context *brw )
+{
+ GLcontext *ctx = &brw->intel.ctx;
+ int i;
+ int nr_surfaces = 0;
+
+ brw_update_vs_constant_surface(ctx, SURF_INDEX_VERT_CONST_BUFFER);
+
+ for (i = 0; i < BRW_VS_MAX_SURF; i++) {
+ if (brw->vs.surf_bo[i] != NULL) {
+ nr_surfaces = i + 1;
+ }
+ }
+
+ if (brw->vs.nr_surfaces != nr_surfaces) {
+ brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES;
+ brw->vs.nr_surfaces = nr_surfaces;
+ }
+
+ /* Note that we don't end up updating the bind_bo if we don't have a
+ * surface to be pointing at. This should be relatively harmless, as it
+ * just slightly increases our working set size.
+ */
+ if (brw->vs.nr_surfaces != 0) {
+ dri_bo_unreference(brw->vs.bind_bo);
+ brw->vs.bind_bo = brw_vs_get_binding_table(brw);
+ }
+}
+
+const struct brw_tracked_state brw_vs_surfaces = {
+ .dirty = {
+ .mesa = (_NEW_PROGRAM_CONSTANTS),
+ .brw = (BRW_NEW_VERTEX_PROGRAM),
+ .cache = 0
+ },
+ .prepare = prepare_vs_surfaces,
+};
+
+
+
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 90d74c2885..3e476fd3be 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -146,6 +146,13 @@ static void do_wm_prog( struct brw_context *brw,
if (c == NULL) {
brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
c = brw->wm.compile_data;
+ if (c == NULL) {
+ /* Ouch - big out of memory problem. Can't continue
+ * without triggering a segfault, no way to signal,
+ * so just return.
+ */
+ return;
+ }
} else {
memset(c, 0, sizeof(*brw->wm.compile_data));
}
@@ -312,6 +319,9 @@ static void brw_wm_populate_key( struct brw_context *brw,
key->drawable_height = brw->intel.driDrawable->h;
}
+ /* CACHE_NEW_VS_PROG */
+ key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS;
+
/* The unique fragment program ID */
key->program_string_id = fp->id;
}
@@ -350,7 +360,7 @@ const struct brw_tracked_state brw_wm_prog = {
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_WM_INPUT_DIMENSIONS |
BRW_NEW_REDUCED_PRIMITIVE),
- .cache = 0
+ .cache = CACHE_NEW_VS_PROG,
},
.prepare = brw_prepare_wm_prog
};
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index f0d31fc1dd..fb15c03e83 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -75,6 +75,7 @@ struct brw_wm_prog_key {
GLuint program_string_id:32;
GLuint origin_x, origin_y;
GLuint drawable_height;
+ GLuint vp_outputs_written;
};
@@ -240,15 +241,20 @@ struct brw_wm_compile {
GLuint max_wm_grf;
GLuint last_scratch;
+ GLuint cur_inst; /**< index of current instruction */
+
+ GLboolean out_of_regs; /**< ran out of GRF registers? */
+
/** Mapping from Mesa registers to hardware registers */
struct {
GLboolean inited;
struct brw_reg reg;
} wm_regs[PROGRAM_PAYLOAD+1][256][4];
+ GLboolean used_grf[BRW_WM_MAX_GRF];
+ GLuint first_free_grf;
struct brw_reg stack;
struct brw_reg emit_mask_reg;
- GLuint reg_index; /**< Index of next free GRF register */
GLuint tmp_regs[BRW_WM_MAX_GRF];
GLuint tmp_index;
GLuint tmp_max;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 72fc21d2eb..14ab9042de 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -353,6 +353,19 @@ static void emit_mad( struct brw_compile *p,
}
}
+static void emit_trunc( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0)
+{
+ GLuint i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ brw_RNDZ(p, dst[i], arg0[i]);
+ }
+ }
+}
static void emit_lrp( struct brw_compile *p,
const struct brw_reg *dst,
@@ -1224,6 +1237,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_dph(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_TRUNC:
+ emit_trunc(p, dst, dst_flags, args[0]);
+ break;
+
case OPCODE_LRP:
emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 117460842a..0e6a2f8ef0 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -1,5 +1,7 @@
#include "main/macros.h"
#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "shader/prog_optimize.h"
#include "brw_context.h"
#include "brw_eu.h"
#include "brw_wm.h"
@@ -21,7 +23,6 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
const struct prog_instruction *inst = &fp->Base.Instructions[i];
switch (inst->Opcode) {
case OPCODE_IF:
- case OPCODE_TRUNC:
case OPCODE_ENDIF:
case OPCODE_CAL:
case OPCODE_BRK:
@@ -42,6 +43,83 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
}
+
+static void
+reclaim_temps(struct brw_wm_compile *c);
+
+
+/** Mark GRF register as used. */
+static void
+prealloc_grf(struct brw_wm_compile *c, int r)
+{
+ c->used_grf[r] = GL_TRUE;
+}
+
+
+/** Mark given GRF register as not in use. */
+static void
+release_grf(struct brw_wm_compile *c, int r)
+{
+ /*assert(c->used_grf[r]);*/
+ c->used_grf[r] = GL_FALSE;
+ c->first_free_grf = MIN2(c->first_free_grf, r);
+}
+
+
+/** Return index of a free GRF, mark it as used. */
+static int
+alloc_grf(struct brw_wm_compile *c)
+{
+ GLuint r;
+ for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
+ if (!c->used_grf[r]) {
+ c->used_grf[r] = GL_TRUE;
+ c->first_free_grf = r + 1; /* a guess */
+ return r;
+ }
+ }
+
+ /* no free temps, try to reclaim some */
+ reclaim_temps(c);
+ c->first_free_grf = 0;
+
+ /* try alloc again */
+ for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
+ if (!c->used_grf[r]) {
+ c->used_grf[r] = GL_TRUE;
+ c->first_free_grf = r + 1; /* a guess */
+ return r;
+ }
+ }
+
+ for (r = 0; r < BRW_WM_MAX_GRF; r++) {
+ assert(c->used_grf[r]);
+ }
+
+ /* really, no free GRF regs found */
+ if (!c->out_of_regs) {
+ /* print warning once per compilation */
+ _mesa_warning(NULL, "i965: ran out of registers for fragment program");
+ c->out_of_regs = GL_TRUE;
+ }
+
+ return -1;
+}
+
+
+/** Return number of GRF registers used */
+static int
+num_grf_used(const struct brw_wm_compile *c)
+{
+ int r;
+ for (r = BRW_WM_MAX_GRF - 1; r >= 0; r--)
+ if (c->used_grf[r])
+ return r + 1;
+ return 0;
+}
+
+
+
/**
* Record the mapping of a Mesa register to a hardware register.
*/
@@ -68,11 +146,23 @@ static int get_scalar_dst_index(const struct prog_instruction *inst)
static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
{
struct brw_reg reg;
- if(c->tmp_index == c->tmp_max)
- c->tmp_regs[ c->tmp_max++ ] = c->reg_index++;
-
+
+ /* if we need to allocate another temp, grow the tmp_regs[] array */
+ if (c->tmp_index == c->tmp_max) {
+ int r = alloc_grf(c);
+ if (r < 0) {
+ /*printf("Out of temps in %s\n", __FUNCTION__);*/
+ r = 50; /* XXX random register! */
+ }
+ c->tmp_regs[ c->tmp_max++ ] = r;
+ }
+
+ /* form the GRF register */
reg = brw_vec8_grf(c->tmp_regs[ c->tmp_index++ ], 0);
+ /*printf("alloc_temp %d\n", reg.nr);*/
+ assert(reg.nr < BRW_WM_MAX_GRF);
return reg;
+
}
/**
@@ -130,35 +220,29 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component,
return brw_null_reg();
}
+ assert(index < 256);
+ assert(component < 4);
+
/* see if we've already allocated a HW register for this Mesa register */
if (c->wm_regs[file][index][component].inited) {
- /* yes, re-use */
- reg = c->wm_regs[file][index][component].reg;
+ /* yes, re-use */
+ reg = c->wm_regs[file][index][component].reg;
}
else {
/* no, allocate new register */
- reg = brw_vec8_grf(c->reg_index, 0);
- }
+ int grf = alloc_grf(c);
+ /*printf("alloc grf %d for reg %d:%d.%d\n", grf, file, index, component);*/
+ if (grf < 0) {
+ /* totally out of temps */
+ grf = 51; /* XXX random register! */
+ }
- /* if this is a new register allocation, record it in the table */
- if (!c->wm_regs[file][index][component].inited) {
- set_reg(c, file, index, component, reg);
- c->reg_index++;
- }
+ reg = brw_vec8_grf(grf, 0);
+ /*printf("Alloc new grf %d for %d.%d\n", reg.nr, index, component);*/
- if (c->reg_index >= BRW_WM_MAX_GRF - 12) {
- /* ran out of temporary registers! */
-#if 1
- /* This is a big hack for now.
- * Return bad register index, just don't hang the GPU.
- */
- _mesa_fprintf(stderr, "out of regs %d\n", c->reg_index);
- c->reg_index = BRW_WM_MAX_GRF - 13;
-#else
- return brw_null_reg();
-#endif
+ set_reg(c, file, index, component, reg);
}
-
+
if (neg & (1 << component)) {
reg = negate(reg);
}
@@ -168,6 +252,46 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component,
}
+
+/**
+ * This is called if we run out of GRF registers. Examine the live intervals
+ * of temp regs in the program and free those which won't be used again.
+ */
+static void
+reclaim_temps(struct brw_wm_compile *c)
+{
+ GLint intBegin[MAX_PROGRAM_TEMPS];
+ GLint intEnd[MAX_PROGRAM_TEMPS];
+ int index;
+
+ /*printf("Reclaim temps:\n");*/
+
+ _mesa_find_temp_intervals(c->prog_instructions, c->nr_fp_insns,
+ intBegin, intEnd);
+
+ for (index = 0; index < MAX_PROGRAM_TEMPS; index++) {
+ if (intEnd[index] != -1 && intEnd[index] < c->cur_inst) {
+ /* program temp[i] can be freed */
+ int component;
+ /*printf(" temp[%d] is dead\n", index);*/
+ for (component = 0; component < 4; component++) {
+ if (c->wm_regs[PROGRAM_TEMPORARY][index][component].inited) {
+ int r = c->wm_regs[PROGRAM_TEMPORARY][index][component].reg.nr;
+ release_grf(c, r);
+ /*
+ printf(" Reclaim temp %d, reg %d at inst %d\n",
+ index, r, c->cur_inst);
+ */
+ c->wm_regs[PROGRAM_TEMPORARY][index][component].inited = GL_FALSE;
+ }
+ }
+ }
+ }
+}
+
+
+
+
/**
* Preallocate registers. This sets up the Mesa to hardware register
* mapping for certain registers, such as constants (uniforms/state vars)
@@ -177,8 +301,12 @@ static void prealloc_reg(struct brw_wm_compile *c)
{
int i, j;
struct brw_reg reg;
- int nr_interp_regs = 0;
+ int urb_read_length = 0;
GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
+ GLuint reg_index = 0;
+
+ memset(c->used_grf, GL_FALSE, sizeof(c->used_grf));
+ c->first_free_grf = 0;
for (i = 0; i < 4; i++) {
if (i < c->key.nr_depth_regs)
@@ -187,14 +315,20 @@ static void prealloc_reg(struct brw_wm_compile *c)
reg = brw_vec8_grf(0, 0);
set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
}
- c->reg_index += 2 * c->key.nr_depth_regs;
+ reg_index += 2 * c->key.nr_depth_regs;
/* constants */
{
- const int nr_params = c->fp->program.Base.Parameters->NumParameters;
+ const GLuint nr_params = c->fp->program.Base.Parameters->NumParameters;
+ const GLuint nr_temps = c->fp->program.Base.NumTemporaries;
/* use a real constant buffer, or just use a section of the GRF? */
- c->fp->use_const_buffer = GL_FALSE; /* (nr_params > 8);*/
+ /* XXX this heuristic may need adjustment... */
+ if ((nr_params + nr_temps) * 4 + reg_index > 80)
+ c->fp->use_const_buffer = GL_TRUE;
+ else
+ c->fp->use_const_buffer = GL_FALSE;
+ /*printf("WM use_const_buffer = %d\n", c->fp->use_const_buffer);*/
if (c->fp->use_const_buffer) {
/* We'll use a real constant buffer and fetch constants from
@@ -216,7 +350,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
for (i = 0; i < nr_params; i++) {
/* loop over XYZW channels */
for (j = 0; j < 4; j++, index++) {
- reg = brw_vec1_grf(c->reg_index + index / 8, index % 8);
+ reg = brw_vec1_grf(reg_index + index / 8, index % 8);
/* Save pointer to parameter/constant value.
* Constants will be copied in prepare_constant_buffer()
*/
@@ -226,28 +360,47 @@ static void prealloc_reg(struct brw_wm_compile *c)
}
/* number of constant regs used (each reg is float[8]) */
c->nr_creg = 2 * ((4 * nr_params + 15) / 16);
- c->reg_index += c->nr_creg;
+ reg_index += c->nr_creg;
}
}
/* fragment shader inputs */
- for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
- if (inputs & (1<<i)) {
- nr_interp_regs++;
- reg = brw_vec8_grf(c->reg_index, 0);
- for (j = 0; j < 4; j++)
- set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
- c->reg_index += 2;
- }
+ for (i = 0; i < VERT_RESULT_MAX; i++) {
+ int fp_input;
+
+ if (i >= VERT_RESULT_VAR0)
+ fp_input = i - VERT_RESULT_VAR0 + FRAG_ATTRIB_VAR0;
+ else if (i <= VERT_RESULT_TEX7)
+ fp_input = i;
+ else
+ fp_input = -1;
+
+ if (fp_input >= 0 && inputs & (1 << fp_input)) {
+ urb_read_length = reg_index;
+ reg = brw_vec8_grf(reg_index, 0);
+ for (j = 0; j < 4; j++)
+ set_reg(c, PROGRAM_PAYLOAD, fp_input, j, reg);
+ }
+ if (c->key.vp_outputs_written & (1 << i)) {
+ reg_index += 2;
+ }
}
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
- c->prog_data.urb_read_length = nr_interp_regs * 2;
+ c->prog_data.urb_read_length = urb_read_length;
c->prog_data.curb_read_length = c->nr_creg;
- c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
- c->reg_index++;
- c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
- c->reg_index += 2;
+ c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
+ reg_index++;
+ c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
+ reg_index += 2;
+
+ /* mark GRF regs [0..reg_index-1] as in-use */
+ for (i = 0; i < reg_index; i++)
+ prealloc_grf(c, i);
+
+ /* Don't use GRF 126, 127. Using them seems to lead to GPU lock-ups */
+ prealloc_grf(c, 126);
+ prealloc_grf(c, 127);
/* An instruction may reference up to three constants.
* They'll be found in these registers.
@@ -256,12 +409,12 @@ static void prealloc_reg(struct brw_wm_compile *c)
if (c->fp->use_const_buffer) {
for (i = 0; i < 3; i++) {
c->current_const[i].index = -1;
- c->current_const[i].reg = alloc_tmp(c);
+ c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0);
}
}
#if 0
printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer);
- printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index);
+ printf("AFTER PRE_ALLOC, reg_index = %d\n", reg_index);
#endif
}
@@ -283,23 +436,21 @@ static void fetch_constants(struct brw_wm_compile *c,
if (src->File == PROGRAM_STATE_VAR ||
src->File == PROGRAM_CONSTANT ||
src->File == PROGRAM_UNIFORM) {
- if (c->current_const[i].index != src->Index) {
- c->current_const[i].index = src->Index;
+ c->current_const[i].index = src->Index;
#if 0
- printf(" fetch const[%d] for arg %d into reg %d\n",
- src->Index, i, c->current_const[i].reg.nr);
+ printf(" fetch const[%d] for arg %d into reg %d\n",
+ src->Index, i, c->current_const[i].reg.nr);
#endif
- /* 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 */
- );
- }
+ /* 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 */
+ );
}
}
}
@@ -368,6 +519,14 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c,
const GLuint nr = 1;
const GLuint component = GET_SWZ(src->Swizzle, channel);
+ /* Extended swizzle terms */
+ if (component == SWIZZLE_ZERO) {
+ return brw_imm_f(0.0F);
+ }
+ else if (component == SWIZZLE_ONE) {
+ return brw_imm_f(1.0F);
+ }
+
if (c->fp->use_const_buffer &&
(src->File == PROGRAM_STATE_VAR ||
src->File == PROGRAM_CONSTANT ||
@@ -665,27 +824,26 @@ static void emit_fb_write(struct brw_wm_compile *c,
}
if (c->key.dest_depth_reg) {
- GLuint comp = c->key.dest_depth_reg / 2;
- GLuint off = c->key.dest_depth_reg % 2;
+ const GLuint comp = c->key.dest_depth_reg / 2;
+ const GLuint off = c->key.dest_depth_reg % 2;
- assert(comp == 1);
- assert(off == 0);
-#if 0
- /* XXX do we need this code? comp always 1, off always 0, it seems */
if (off != 0) {
+ /* XXX this code needs review/testing */
+ struct brw_reg arg1_0 = get_src_reg(c, inst, 1, comp);
+ struct brw_reg arg1_1 = get_src_reg(c, inst, 1, comp+1);
+
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
- brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1));
+ brw_MOV(p, brw_message_reg(nr), offset(arg1_0, 1));
/* 2nd half? */
- brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]);
+ brw_MOV(p, brw_message_reg(nr+1), arg1_1);
brw_pop_insn_state(p);
}
else
-#endif
{
- struct brw_reg src = get_src_reg(c, inst, 1, 1);
- brw_MOV(p, brw_message_reg(nr), src);
+ struct brw_reg src = get_src_reg(c, inst, 1, 1);
+ brw_MOV(p, brw_message_reg(nr), src);
}
nr += 2;
}
@@ -2595,7 +2753,8 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
struct brw_compile *p = &c->func;
struct brw_indirect stack_index = brw_indirect(0, 0);
- c->reg_index = 0;
+ c->out_of_regs = GL_FALSE;
+
prealloc_reg(c);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
@@ -2603,6 +2762,8 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
for (i = 0; i < c->nr_fp_insns; i++) {
const struct prog_instruction *inst = &c->prog_instructions[i];
+ c->cur_inst = i;
+
#if 0
_mesa_printf("Inst %d: ", i);
_mesa_print_instruction(inst);
@@ -2833,17 +2994,13 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
_mesa_printf("unsupported IR in fragment shader %d\n",
inst->Opcode);
}
+
if (inst->CondUpdate)
brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
else
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
post_wm_emit(c);
-
- if (c->reg_index >= BRW_WM_MAX_GRF) {
- _mesa_problem(NULL, "Ran out of registers in brw_wm_emit_glsl()");
- /* XXX we need to do some proper error recovery here */
- }
}
@@ -2867,6 +3024,6 @@ void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c)
brw_wm_print_program(c, "brw_wm_glsl_emit done");
}
- c->prog_data.total_grf = c->reg_index;
+ c->prog_data.total_grf = num_grf_used(c);
c->prog_data.total_scratch = 0;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.c b/src/mesa/drivers/dri/i965/brw_wm_iz.c
index bd60ac9b31..8fd067abe7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_iz.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_iz.c
@@ -116,6 +116,10 @@ const struct {
{ C, 0, 1, 1, 1 }
};
+/**
+ * \param line_aa AA_NEVER, AA_ALWAYS or AA_SOMETIMES
+ * \param lookup bitmask of IZ_* flags
+ */
void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
struct brw_wm_prog_key *key )
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index ab9aa2f10d..3436a24717 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -159,6 +159,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_FRC:
case OPCODE_MOV:
case OPCODE_SWZ:
+ case OPCODE_TRUNC:
read0 = writemask;
break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index 780edbc42e..6faea018fb 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -69,8 +69,6 @@ static void prealloc_reg(struct brw_wm_compile *c,
*/
static void init_registers( struct brw_wm_compile *c )
{
- struct brw_context *brw = c->func.brw;
- GLuint inputs = (brw->vs.prog_data->outputs_written & DO_SETUP_BITS);
GLuint nr_interp_regs = 0;
GLuint i = 0;
GLuint j;
@@ -85,16 +83,19 @@ static void init_registers( struct brw_wm_compile *c )
prealloc_reg(c, &c->creg[j], i++);
for (j = 0; j < FRAG_ATTRIB_MAX; j++) {
- if (inputs & (1<<j)) {
- /* index for vs output and ps input are not the same
- in shader varying */
- GLuint index;
- if (j > FRAG_ATTRIB_VAR0)
- index = j - (VERT_RESULT_VAR0 - FRAG_ATTRIB_VAR0);
+ if (c->key.vp_outputs_written & (1<<j)) {
+ int fp_index;
+
+ if (j >= VERT_RESULT_VAR0)
+ fp_index = j - (VERT_RESULT_VAR0 - FRAG_ATTRIB_VAR0);
+ else if (j <= VERT_RESULT_TEX7)
+ fp_index = j;
else
- index = j;
+ fp_index = -1;
+
nr_interp_regs++;
- prealloc_reg(c, &c->payload.input_interp[index], i++);
+ if (fp_index >= 0)
+ prealloc_reg(c, &c->payload.input_interp[fp_index], i++);
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index c604ef0162..3fc18ff1f3 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -178,6 +178,16 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
}
+ else if (key->tex_target == GL_TEXTURE_1D) {
+ /* There's a bug in 1D texture sampling - it actually pays
+ * attention to the wrap_t value, though it should not.
+ * Override the wrap_t value here to GL_REPEAT to keep
+ * any nonexistent border pixels from floating in.
+ */
+ sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
+ sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
+ sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+ }
else {
sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
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 805df8a4af..c49a5f6b4e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -176,22 +176,6 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format,
}
}
-
-/**
- * Use same key for WM and VS surfaces.
- */
-struct brw_surface_key {
- GLenum target, depthmode;
- dri_bo *bo;
- GLint format, internal_format;
- GLint first_level, last_level;
- GLint width, height, depth;
- GLint pitch, cpp;
- uint32_t tiling;
- GLuint offset;
-};
-
-
static void
brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
{
@@ -268,7 +252,7 @@ brw_create_texture_surface( struct brw_context *brw,
surf.ss0.cube_neg_z = 1;
}
- bo = brw_upload_cache(&brw->cache, BRW_SS_SURFACE,
+ bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
key, sizeof(*key),
&key->bo, key->bo ? 1 : 0,
&surf, sizeof(surf),
@@ -321,10 +305,11 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
key.tiling = intelObj->mt->region->tiling;
dri_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, key.bo ? 1 : 0,
- NULL);
+ brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &key.bo, key.bo ? 1 : 0,
+ NULL);
if (brw->wm.surf_bo[surf] == NULL) {
brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key);
}
@@ -336,7 +321,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
* Create the constant buffer surface. Vertex/fragment shader constants will be
* read from this buffer with Data Port Read instructions/messages.
*/
-static dri_bo *
+dri_bo *
brw_create_constant_surface( struct brw_context *brw,
struct brw_surface_key *key )
{
@@ -362,7 +347,7 @@ brw_create_constant_surface( struct brw_context *brw,
surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
- bo = brw_upload_cache(&brw->cache, BRW_SS_SURFACE,
+ bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
key, sizeof(*key),
&key->bo, key->bo ? 1 : 0,
&surf, sizeof(surf),
@@ -380,39 +365,70 @@ brw_create_constant_surface( struct brw_context *brw,
return bo;
}
+/* Creates a new WM constant buffer reflecting the current fragment program's
+ * constants, if needed by the fragment program.
+ *
+ * Otherwise, constants go through the CURBEs using the brw_constant_buffer
+ * state atom.
+ */
+static drm_intel_bo *
+brw_wm_update_constant_buffer(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
+ const int size = params->NumParameters * 4 * sizeof(GLfloat);
+ drm_intel_bo *const_buffer;
+
+ /* BRW_NEW_FRAGMENT_PROGRAM */
+ if (!fp->use_const_buffer)
+ return NULL;
+
+ const_buffer = drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer",
+ size, 64);
+
+ /* _NEW_PROGRAM_CONSTANTS */
+ dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
+
+ return const_buffer;
+}
/**
* Update the surface state for a WM constant buffer.
* The constant buffer will be (re)allocated here if needed.
*/
-static dri_bo *
+static void
brw_update_wm_constant_surface( GLcontext *ctx,
- GLuint surf,
- dri_bo *const_buffer,
- const struct gl_program_parameter_list *params)
+ GLuint surf)
{
struct brw_context *brw = brw_context(ctx);
struct brw_surface_key key;
- struct intel_context *intel = &brw->intel;
- const int size = params->NumParameters * 4 * sizeof(GLfloat);
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ const struct gl_program_parameter_list *params =
+ fp->program.Base.Parameters;
- /* free old const buffer if too small */
- if (const_buffer && const_buffer->size < size) {
- dri_bo_unreference(const_buffer);
- const_buffer = NULL;
- }
+ /* If we're in this state update atom, we need to update WM constants, so
+ * free the old buffer and create a new one for the new contents.
+ */
+ dri_bo_unreference(fp->const_buffer);
+ fp->const_buffer = brw_wm_update_constant_buffer(brw);
- /* alloc new buffer if needed */
- if (!const_buffer) {
- const_buffer =
- drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer", size, 64);
+ /* If there's no constant buffer, then no surface BO is needed to point at
+ * it.
+ */
+ if (fp->const_buffer == 0) {
+ drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = NULL;
+ return;
}
memset(&key, 0, sizeof(key));
key.format = MESA_FORMAT_RGBA_FLOAT32;
key.internal_format = GL_RGBA;
- key.bo = const_buffer;
+ key.bo = fp->const_buffer;
key.depthmode = GL_NONE;
key.pitch = params->NumParameters;
key.width = params->NumParameters;
@@ -427,77 +443,59 @@ brw_update_wm_constant_surface( GLcontext *ctx,
*/
dri_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
+ brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
&key, sizeof(key),
&key.bo, key.bo ? 1 : 0,
NULL);
if (brw->wm.surf_bo[surf] == NULL) {
brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
}
-
- return const_buffer;
+ brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
}
-
/**
- * Update the surface state for a VS constant buffer.
- * The constant buffer will be (re)allocated here if needed.
+ * Updates surface / buffer for fragment shader constant buffer, if
+ * one is required.
+ *
+ * This consumes the state updates for the constant buffer, and produces
+ * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
+ * inclusion in the binding table.
*/
-static dri_bo *
-brw_update_vs_constant_surface( GLcontext *ctx,
- GLuint surf,
- dri_bo *const_buffer,
- const struct gl_program_parameter_list *params)
+static void prepare_wm_constant_surface(struct brw_context *brw )
{
- struct brw_context *brw = brw_context(ctx);
- struct brw_surface_key key;
- struct intel_context *intel = &brw->intel;
- const int size = params->NumParameters * 4 * sizeof(GLfloat);
-
- assert(surf == 0);
-
- /* free old const buffer if too small */
- if (const_buffer && const_buffer->size < size) {
- dri_bo_unreference(const_buffer);
- const_buffer = NULL;
- }
-
- /* alloc new buffer if needed */
- if (!const_buffer) {
- const_buffer =
- drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", size, 64);
- }
-
- memset(&key, 0, sizeof(key));
-
- key.format = MESA_FORMAT_RGBA_FLOAT32;
- key.internal_format = GL_RGBA;
- key.bo = const_buffer;
- key.depthmode = GL_NONE;
- key.pitch = params->NumParameters;
- key.width = params->NumParameters;
- key.height = 1;
- key.depth = 1;
- key.cpp = 16;
+ GLcontext *ctx = &brw->intel.ctx;
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
- /*
- printf("%s:\n", __FUNCTION__);
- printf(" width %d height %d depth %d cpp %d pitch %d\n",
- key.width, key.height, key.depth, key.cpp, key.pitch);
- */
+ drm_intel_bo_unreference(fp->const_buffer);
+ fp->const_buffer = brw_wm_update_constant_buffer(brw);
- dri_bo_unreference(brw->vs.surf_bo[surf]);
- brw->vs.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, key.bo ? 1 : 0,
- NULL);
- if (brw->vs.surf_bo[surf] == NULL) {
- brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key);
+ /* If there's no constant buffer, then no surface BO is needed to point at
+ * it.
+ */
+ if (fp->const_buffer == 0) {
+ if (brw->wm.surf_bo[surf] != NULL) {
+ drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = NULL;
+ brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+ }
+ return;
}
- return const_buffer;
+ brw_update_wm_constant_surface(ctx, surf);
}
+const struct brw_tracked_state brw_wm_constant_surface = {
+ .dirty = {
+ .mesa = (_NEW_PROGRAM_CONSTANTS),
+ .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+ .cache = 0
+ },
+ .prepare = prepare_wm_constant_surface,
+};
+
/**
* Sets up a surface state structure to point at the given region.
@@ -507,7 +505,7 @@ brw_update_vs_constant_surface( GLcontext *ctx,
static void
brw_update_renderbuffer_surface(struct brw_context *brw,
struct gl_renderbuffer *rb,
- unsigned int unit, GLboolean cached)
+ unsigned int unit)
{
GLcontext *ctx = &brw->intel.ctx;
dri_bo *region_bo = NULL;
@@ -567,12 +565,11 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
ctx->Color.BlendEnabled);
dri_bo_unreference(brw->wm.surf_bo[unit]);
- brw->wm.surf_bo[unit] = NULL;
- if (cached)
- brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,
- &key, sizeof(key),
- &region_bo, 1,
- NULL);
+ brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &region_bo, 1,
+ NULL);
if (brw->wm.surf_bo[unit] == NULL) {
struct brw_surface_state surf;
@@ -598,7 +595,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
surf.ss0.writedisable_alpha = !key.color_mask[3];
/* Key size will never match key size for textures, so we're safe. */
- brw->wm.surf_bo[unit] = brw_upload_cache(&brw->cache, BRW_SS_SURFACE,
+ brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
&key, sizeof(key),
&region_bo, 1,
&surf, sizeof(surf),
@@ -630,7 +628,7 @@ brw_wm_get_binding_table(struct brw_context *brw)
assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
- bind_bo = brw_search_cache(&brw->cache, BRW_SS_SURF_BIND,
+ bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
brw->wm.surf_bo, brw->wm.nr_surfaces,
NULL);
@@ -646,7 +644,7 @@ brw_wm_get_binding_table(struct brw_context *brw)
else
data[i] = 0;
- bind_bo = brw_upload_cache( &brw->cache, BRW_SS_SURF_BIND,
+ bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
brw->wm.surf_bo, brw->wm.nr_surfaces,
data, data_size,
@@ -682,27 +680,17 @@ static void prepare_wm_surfaces(struct brw_context *brw )
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
brw_update_renderbuffer_surface(brw,
ctx->DrawBuffer->_ColorDrawBuffers[i],
- i,
- GL_FALSE);
+ i);
}
} else {
- brw_update_renderbuffer_surface(brw, NULL, 0, GL_TRUE);
+ brw_update_renderbuffer_surface(brw, NULL, 0);
}
old_nr_surfaces = brw->wm.nr_surfaces;
brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;
- /* Update surface / buffer for fragment shader constant buffer */
- {
- const GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
- struct brw_fragment_program *fp =
- (struct brw_fragment_program *) brw->fragment_program;
- fp->const_buffer =
- brw_update_wm_constant_surface(ctx, surf, fp->const_buffer,
- fp->program.Base.Parameters);
-
- brw->wm.nr_surfaces = surf + 1;
- }
+ if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL)
+ brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
/* Update surfaces for textures */
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
@@ -735,100 +723,16 @@ static void prepare_wm_surfaces(struct brw_context *brw )
brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
}
-
-/**
- * Constructs the binding table for the VS surface state.
- */
-static dri_bo *
-brw_vs_get_binding_table(struct brw_context *brw)
-{
- dri_bo *bind_bo;
-
- assert(brw->vs.nr_surfaces <= BRW_VS_MAX_SURF);
-
- bind_bo = brw_search_cache(&brw->cache, BRW_SS_SURF_BIND,
- NULL, 0,
- brw->vs.surf_bo, brw->vs.nr_surfaces,
- NULL);
-
- if (bind_bo == NULL) {
- GLuint data_size = brw->vs.nr_surfaces * sizeof(GLuint);
- uint32_t *data = malloc(data_size);
- int i;
-
- for (i = 0; i < brw->vs.nr_surfaces; i++)
- if (brw->vs.surf_bo[i])
- data[i] = brw->vs.surf_bo[i]->offset;
- else
- data[i] = 0;
-
- bind_bo = brw_upload_cache( &brw->cache, BRW_SS_SURF_BIND,
- NULL, 0,
- brw->vs.surf_bo, brw->vs.nr_surfaces,
- data, data_size,
- NULL, NULL);
-
- /* Emit binding table relocations to surface state */
- for (i = 0; i < BRW_VS_MAX_SURF; i++) {
- if (brw->vs.surf_bo[i] != NULL) {
- dri_bo_emit_reloc(bind_bo,
- I915_GEM_DOMAIN_INSTRUCTION, 0,
- 0,
- i * sizeof(GLuint),
- brw->vs.surf_bo[i]);
- }
- }
-
- free(data);
- }
-
- return bind_bo;
-}
-
-
-/**
- * Vertex shader surfaces. Just constant buffer for now. Could add vertex
- * shader textures in the future.
- */
-static void prepare_vs_surfaces(struct brw_context *brw )
-{
- GLcontext *ctx = &brw->intel.ctx;
-
- /* Update surface / buffer for vertex shader constant buffer */
- {
- const GLuint surf = SURF_INDEX_VERT_CONST_BUFFER;
- struct brw_vertex_program *vp =
- (struct brw_vertex_program *) brw->vertex_program;
- vp->const_buffer =
- brw_update_vs_constant_surface(ctx, surf, vp->const_buffer,
- vp->program.Base.Parameters);
-
- brw->vs.nr_surfaces = 1;
- }
-
- dri_bo_unreference(brw->vs.bind_bo);
- brw->vs.bind_bo = brw_vs_get_binding_table(brw);
-
- if (1)
- brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES;
-}
-
-
-static void
-prepare_surfaces(struct brw_context *brw)
-{
- prepare_wm_surfaces(brw);
- prepare_vs_surfaces(brw);
-}
-
-
const struct brw_tracked_state brw_wm_surfaces = {
.dirty = {
- .mesa = _NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS | _NEW_PROGRAM,
- .brw = BRW_NEW_CONTEXT,
+ .mesa = (_NEW_COLOR |
+ _NEW_TEXTURE |
+ _NEW_BUFFERS),
+ .brw = (BRW_NEW_CONTEXT |
+ BRW_NEW_WM_SURFACES),
.cache = 0
},
- .prepare = prepare_surfaces,
+ .prepare = prepare_wm_surfaces,
};
diff --git a/src/mesa/drivers/dri/i965/intel_generatemipmap.c b/src/mesa/drivers/dri/i965/intel_generatemipmap.c
new file mode 120000
index 0000000000..4c6b37ada0
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_generatemipmap.c
@@ -0,0 +1 @@
+../intel/intel_generatemipmap.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index c849e4869e..23ba3b9ef6 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -35,6 +35,9 @@
#include "intel_batchbuffer.h"
#include "intel_regions.h"
+static GLboolean
+intel_bufferobj_unmap(GLcontext * ctx,
+ GLenum target, struct gl_buffer_object *obj);
/** Allocates a new dri_bo to store the data for the buffer object. */
static void
@@ -100,8 +103,15 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
assert(intel_obj);
- assert(!obj->Pointer); /* Mesa should have unmapped it */
+ /* Buffer objects are automatically unmapped when deleting according
+ * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy
+ * (though it does if you call glDeleteBuffers)
+ */
+ if (obj->Pointer)
+ intel_bufferobj_unmap(ctx, 0, obj);
+
+ _mesa_free(intel_obj->sys_buffer);
if (intel_obj->region) {
intel_bufferobj_release_region(intel, intel_obj);
}
@@ -142,7 +152,23 @@ intel_bufferobj_data(GLcontext * ctx,
dri_bo_unreference(intel_obj->buffer);
intel_obj->buffer = NULL;
}
+ _mesa_free(intel_obj->sys_buffer);
+ intel_obj->sys_buffer = NULL;
+
if (size != 0) {
+#ifdef I915
+ /* On pre-965, stick VBOs in system memory, as we're always doing swtnl
+ * with their contents anyway.
+ */
+ if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) {
+ intel_obj->sys_buffer = _mesa_malloc(size);
+ if (intel_obj->sys_buffer != NULL) {
+ if (data != NULL)
+ memcpy(intel_obj->sys_buffer, data, size);
+ return;
+ }
+ }
+#endif
intel_bufferobj_alloc_buffer(intel, intel_obj);
if (data != NULL)
@@ -172,7 +198,10 @@ intel_bufferobj_subdata(GLcontext * ctx,
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
- dri_bo_subdata(intel_obj->buffer, offset, size, data);
+ if (intel_obj->sys_buffer)
+ memcpy((char *)intel_obj->sys_buffer + offset, data, size);
+ else
+ dri_bo_subdata(intel_obj->buffer, offset, size, data);
}
@@ -205,9 +234,15 @@ intel_bufferobj_map(GLcontext * ctx,
struct intel_context *intel = intel_context(ctx);
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
GLboolean read_only = (access == GL_READ_ONLY_ARB);
+ GLboolean write_only = (access == GL_WRITE_ONLY_ARB);
assert(intel_obj);
+ if (intel_obj->sys_buffer) {
+ obj->Pointer = intel_obj->sys_buffer;
+ return obj->Pointer;
+ }
+
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
@@ -216,7 +251,14 @@ intel_bufferobj_map(GLcontext * ctx,
return NULL;
}
- dri_bo_map(intel_obj->buffer, !read_only);
+ if (write_only && intel->intelScreen->kernel_exec_fencing) {
+ drm_intel_gem_bo_map_gtt(intel_obj->buffer);
+ intel_obj->mapped_gtt = GL_TRUE;
+ } else {
+ drm_intel_bo_map(intel_obj->buffer, !read_only);
+ intel_obj->mapped_gtt = GL_FALSE;
+ }
+
obj->Pointer = intel_obj->buffer->virtual;
return obj->Pointer;
}
@@ -234,7 +276,11 @@ intel_bufferobj_unmap(GLcontext * ctx,
assert(intel_obj);
if (intel_obj->buffer != NULL) {
assert(obj->Pointer);
- dri_bo_unmap(intel_obj->buffer);
+ if (intel_obj->mapped_gtt) {
+ drm_intel_gem_bo_unmap_gtt(intel_obj->buffer);
+ } else {
+ drm_intel_bo_unmap(intel_obj->buffer);
+ }
obj->Pointer = NULL;
}
return GL_TRUE;
@@ -253,6 +299,18 @@ intel_bufferobj_buffer(struct intel_context *intel,
}
}
+ if (intel_obj->buffer == NULL) {
+ intel_bufferobj_alloc_buffer(intel, intel_obj);
+ intel_bufferobj_subdata(&intel->ctx,
+ GL_ARRAY_BUFFER_ARB,
+ 0,
+ intel_obj->Base.Size,
+ intel_obj->sys_buffer,
+ &intel_obj->Base);
+ _mesa_free(intel_obj->sys_buffer);
+ intel_obj->sys_buffer = NULL;
+ }
+
return intel_obj->buffer;
}
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
index bf6dbd58f2..0431015631 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
@@ -42,10 +42,13 @@ struct intel_buffer_object
{
struct gl_buffer_object Base;
dri_bo *buffer; /* the low-level buffer manager's buffer handle */
+ /** System memory buffer data, if not using a BO to store the data. */
+ void *sys_buffer;
struct intel_region *region; /* Is there a zero-copy texture
associated with this (pixel)
buffer object? */
+ GLboolean mapped_gtt;
};
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index b86cafea24..df5c3fc176 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -157,7 +157,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
/* Do this here, not core Mesa, since this function is called from
* many places within the driver.
*/
- if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
+ if (ctx->NewState & _NEW_BUFFERS) {
/* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
_mesa_update_framebuffer(ctx);
/* this updates the DrawBuffer's Width/Height if it's a FBO */
@@ -276,7 +276,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
(ctx->Depth.Test && fb->Visual.depthBits > 0));
ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
- (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));
+ (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
}
else {
/* Mesa's Stencil._Enabled field is updated when
diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c
index eb0d890f47..309ac1923b 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -53,6 +53,7 @@
#include "intel_clear.h"
#include "intel_fbo.h"
#include "intel_pixel.h"
+#include "intel_regions.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -255,8 +256,10 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask)
/* 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, GL_ALWAYS, ctx->Stencil.Clear,
+ _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);
@@ -310,7 +313,6 @@ 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;
@@ -338,7 +340,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
= intel_get_rb_region(fb, BUFFER_STENCIL);
if (stencilRegion) {
/* have hw stencil */
- if (IS_965(intel->intelScreen->deviceID) ||
+ if (stencilRegion->tiling == I915_TILING_Y ||
(ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* We have to use the 3D engine if we're clearing a partial mask
* of the stencil buffer, or if we're on a 965 which has a tiled
@@ -355,9 +357,10 @@ intelClear(GLcontext *ctx, GLbitfield mask)
/* HW depth */
if (mask & BUFFER_BIT_DEPTH) {
+ const struct intel_region *irb = intel_get_rb_region(fb, BUFFER_DEPTH);
+
/* clear depth with whatever method is used for stencil (see above) */
- if (IS_965(intel->intelScreen->deviceID) ||
- tri_mask & BUFFER_BIT_STENCIL)
+ if (irb->tiling == I915_TILING_Y || tri_mask & BUFFER_BIT_STENCIL)
tri_mask |= BUFFER_BIT_DEPTH;
else
blit_mask |= BUFFER_BIT_DEPTH;
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 5dc3df395d..f88b37d0f3 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -394,7 +394,7 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
if (!driContext->driScreenPriv->dri2.enabled)
return;
- if (!intel->internal_viewport_call) {
+ if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) {
intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
if (driContext->driDrawablePriv != driContext->driReadablePriv)
intel_update_renderbuffers(driContext, driContext->driReadablePriv);
@@ -550,6 +550,9 @@ intelInitDriverFunctions(struct dd_function_table *functions)
functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
intelInitTextureFuncs(functions);
+ intelInitTextureImageFuncs(functions);
+ intelInitTextureSubImageFuncs(functions);
+ intelInitTextureCopyImageFuncs(functions);
intelInitStateFuncs(functions);
intelInitClearFuncs(functions);
intelInitBufferFuncs(functions);
@@ -650,6 +653,13 @@ intelInitContext(struct intel_context *intel,
_mesa_init_point(ctx);
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
+ if (IS_965(intelScreen->deviceID)) {
+ if (MAX_WIDTH > 8192)
+ ctx->Const.MaxRenderbufferSize = 8192;
+ } else {
+ if (MAX_WIDTH > 2048)
+ ctx->Const.MaxRenderbufferSize = 2048;
+ }
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext(ctx);
@@ -717,6 +727,9 @@ intelInitContext(struct intel_context *intel,
else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
+ intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
+ "texture_tiling");
+ intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
intel->prim.primitive = ~0;
@@ -778,13 +791,64 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb_bo = NULL;
if (release_texture_heaps) {
- /* This share group is about to go away, free our private
- * texture object data.
+ /* Nothing is currently done here to free texture heaps;
+ * but we're not using the texture heap utilities, so I
+ * rather think we shouldn't. I've taken a look, and can't
+ * find any private texture data hanging around anywhere, but
+ * I'm not yet certain there isn't any at all...
*/
- if (INTEL_DEBUG & DEBUG_TEXTURE)
+ /* if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "do something to free texture heaps\n");
+ */
}
+ /* XXX In intelMakeCurrent() below, the context's static regions are
+ * referenced inside the frame buffer; it's listed as a hack,
+ * with a comment of "XXX FBO temporary fix-ups!", but
+ * as long as it's there, we should release the regions here.
+ * The do/while loop around the block is used to allow the
+ * "continue" statements inside the block to exit the block,
+ * to avoid many layers of "if" constructs.
+ */
+ do {
+ __DRIdrawablePrivate * driDrawPriv = intel->driDrawable;
+ struct intel_framebuffer *intel_fb;
+ struct intel_renderbuffer *irbDepth, *irbStencil;
+ if (!driDrawPriv) {
+ /* We're already detached from the drawable; exit this block. */
+ continue;
+ }
+ intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate;
+ if (!intel_fb) {
+ /* The frame buffer is already gone; exit this block. */
+ continue;
+ }
+ irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+ irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+
+ /* If the regions of the frame buffer still match the regions
+ * of the context, release them. If they've changed somehow,
+ * leave them alone.
+ */
+ if (intel_fb->color_rb[0] && intel_fb->color_rb[0]->region == intel->front_region) {
+ intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
+ }
+ if (intel_fb->color_rb[1] && intel_fb->color_rb[1]->region == intel->back_region) {
+ intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
+ }
+
+ if (irbDepth && irbDepth->region == intel->depth_region) {
+ intel_renderbuffer_set_region(irbDepth, NULL);
+ }
+ /* Usually, the stencil buffer is the same as the depth buffer;
+ * but they're handled separately in MakeCurrent, so we'll
+ * handle them separately here.
+ */
+ if (irbStencil && irbStencil->region == intel->depth_region) {
+ intel_renderbuffer_set_region(irbStencil, NULL);
+ }
+ } while (0);
+
intel_region_release(&intel->front_region);
intel_region_release(&intel->back_region);
intel_region_release(&intel->depth_region);
@@ -793,6 +857,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
/* free the Mesa context */
_mesa_free_context_data(&intel->ctx);
+
+
}
}
@@ -821,7 +887,10 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
if (driDrawPriv != driReadPriv)
intel_update_renderbuffers(driContextPriv, driReadPriv);
} else {
- /* XXX FBO temporary fix-ups! */
+ /* XXX FBO temporary fix-ups! These are released in
+ * intelDextroyContext(), above. Changes here should be
+ * reflected there.
+ */
/* if the renderbuffers don't have regions, init them from the context */
struct intel_renderbuffer *irbDepth
= intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index f45e24ca3a..7d3c80bb21 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -161,12 +161,22 @@ struct intel_context
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;
@@ -295,6 +305,9 @@ struct intel_context
*/
GLboolean is_front_buffer_rendering;
+ GLboolean use_texture_tiling;
+ GLboolean use_early_z;
+
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */
int perf_boxes;
@@ -549,6 +562,9 @@ void intel_viewport(GLcontext * ctx, GLint x, GLint y,
void intel_update_renderbuffers(__DRIcontext *context,
__DRIdrawable *drawable);
+void i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region,
+ uint32_t buffer_id);
+
/*======================================================================
* Inline conversion functions.
* These are better-typed than the macros used previously:
@@ -559,4 +575,10 @@ intel_context(GLcontext * ctx)
return (struct intel_context *) ctx;
}
+static INLINE GLboolean
+is_power_of_two(uint32_t value)
+{
+ return (value & (value - 1)) == 0;
+}
+
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 9ec1b4ec2f..1e8b1878ab 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -48,6 +48,7 @@
#define need_GL_EXT_point_parameters
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
+#define need_GL_APPLE_vertex_array_object
#define need_GL_ATI_separate_stencil
#define need_GL_ATI_envmap_bumpmap
#define need_GL_NV_point_sprite
@@ -95,6 +96,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_EXT_texture_lod_bias", NULL },
{ "GL_3DFX_texture_compression_FXT1", NULL },
{ "GL_APPLE_client_storage", NULL },
+ { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions},
{ "GL_MESA_pack_invert", NULL },
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 52647ddf8b..0ea413aee1 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -217,7 +217,8 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width,
height, pitch);
- irb->region = intel_region_alloc(intel, cpp, width, height, pitch,
+ irb->region = intel_region_alloc(intel, I915_TILING_NONE,
+ cpp, width, height, pitch,
GL_TRUE);
if (!irb->region)
return GL_FALSE; /* out of memory? */
@@ -574,9 +575,10 @@ intel_render_texture(GLcontext * ctx,
ASSERT(newImage);
- if (newImage->Border != 0) {
- /* Fallback on drawing to a texture with a border, which won't have a
- * miptree.
+ intel_image = intel_texture_image(newImage);
+ if (!intel_image->mt) {
+ /* Fallback on drawing to a texture that doesn't have a miptree
+ * (has a border, width/height 0, etc.)
*/
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
_mesa_render_texture(ctx, fb, att);
@@ -607,7 +609,6 @@ intel_render_texture(GLcontext * ctx,
irb->Base.RefCount);
/* point the renderbufer's region to the texture image region */
- intel_image = intel_texture_image(newImage);
if (irb->region != intel_image->mt->region) {
if (irb->region)
intel_region_release(&irb->region);
@@ -679,6 +680,11 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
if (rb == NULL)
continue;
+ if (irb == NULL) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ continue;
+ }
+
switch (irb->texformat->MesaFormat) {
case MESA_FORMAT_ARGB8888:
case MESA_FORMAT_RGB565:
diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
new file mode 100644
index 0000000000..1060fbd9e5
--- /dev/null
+++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/bufferobj.h"
+#include "main/teximage.h"
+#include "main/texenv.h"
+#include "main/texobj.h"
+#include "main/texstate.h"
+#include "main/texparam.h"
+#include "main/varray.h"
+#include "main/attrib.h"
+#include "main/enable.h"
+#include "main/buffers.h"
+#include "main/fbobject.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/depth.h"
+#include "main/hash.h"
+#include "main/mipmap.h"
+#include "main/blend.h"
+#include "glapi/dispatch.h"
+#include "swrast/swrast.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_pixel.h"
+#include "intel_tex.h"
+#include "intel_mipmap_tree.h"
+
+static const char *intel_fp_tex2d =
+ "!!ARBfp1.0\n"
+ "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n"
+ "END\n";
+
+static GLboolean
+intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,
+ int level, int width, int height)
+{
+ struct intel_context *intel = intel_context(ctx);
+ GLfloat vertices[4][2];
+ GLint status;
+
+ /* Set to source from the previous level */
+ _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level - 1);
+ _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1);
+
+ /* Set to draw into the current level */
+ _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D,
+ tex_name,
+ level);
+ /* Choose to render to the color attachment. */
+ _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+ status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+ return GL_FALSE;
+
+ intel_meta_set_passthrough_transform(intel);
+
+ /* XXX: Doing it right would involve setting up the transformation to do
+ * 0-1 mapping or something, and not changing the vertex data.
+ */
+ vertices[0][0] = 0;
+ vertices[0][1] = 0;
+ vertices[1][0] = width;
+ vertices[1][1] = 0;
+ vertices[2][0] = width;
+ vertices[2][1] = height;
+ vertices[3][0] = 0;
+ vertices[3][1] = height;
+
+ _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);
+ _mesa_Enable(GL_VERTEX_ARRAY);
+ intel_meta_set_default_texrect(intel);
+
+ CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+
+ intel_meta_restore_texcoords(intel);
+ intel_meta_restore_transform(intel);
+
+ return GL_TRUE;
+}
+
+static GLboolean
+intel_generate_mipmap_2d(GLcontext *ctx,
+ GLenum target,
+ struct gl_texture_object *texObj)
+{
+ struct intel_context *intel = intel_context(ctx);
+ GLint old_active_texture;
+ int level, max_levels, start_level, end_level;
+ GLuint fb_name;
+ GLboolean success = GL_FALSE;
+ struct gl_framebuffer *saved_fbo = NULL;
+
+ _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
+ GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT);
+ _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ old_active_texture = ctx->Texture.CurrentUnit;
+ _mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer);
+
+ _mesa_Disable(GL_POLYGON_STIPPLE);
+ _mesa_Disable(GL_DEPTH_TEST);
+ _mesa_Disable(GL_STENCIL_TEST);
+ _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ _mesa_DepthMask(GL_FALSE);
+
+ /* Bind the given texture to GL_TEXTURE_2D with linear filtering for our
+ * minification.
+ */
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB);
+ _mesa_Enable(GL_TEXTURE_2D);
+ _mesa_BindTexture(GL_TEXTURE_2D, texObj->Name);
+ _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ /* Bind the new renderbuffer to the color attachment point. */
+ _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);
+
+ max_levels = _mesa_max_texture_levels(ctx, texObj->Target);
+ start_level = texObj->BaseLevel;
+ end_level = texObj->MaxLevel;
+
+ /* Loop generating level+1 from level. */
+ for (level = start_level; level < end_level && level < max_levels - 1; level++) {
+ const struct gl_texture_image *srcImage;
+ int width, height;
+
+ srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (srcImage->Border != 0)
+ goto fail;
+
+ width = srcImage->Width / 2;
+ if (width < 1)
+ width = 1;
+ height = srcImage->Height / 2;
+ if (height < 1)
+ height = 1;
+
+ if (width == srcImage->Width &&
+ height == srcImage->Height) {
+ /* Neither _mesa_max_texture_levels nor texObj->MaxLevel are the
+ * maximum texture level for the object, so break out when we've gone
+ * over the edge.
+ */
+ break;
+ }
+
+ /* Make sure that there's space allocated for the target level.
+ * We could skip this if there's already space allocated and save some
+ * time.
+ */
+ _mesa_TexImage2D(GL_TEXTURE_2D, level + 1, srcImage->InternalFormat,
+ width, height, 0,
+ GL_RGBA, GL_UNSIGNED_INT, NULL);
+
+ if (!intel_generate_mipmap_level(ctx, texObj->Name, level + 1,
+ width, height))
+ goto fail;
+ }
+
+ success = GL_TRUE;
+
+fail:
+ intel_meta_restore_fragment_program(intel);
+ intel_meta_restore_vertex_program(intel);
+
+ _mesa_DeleteFramebuffersEXT(1, &fb_name);
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
+ if (saved_fbo)
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, saved_fbo->Name);
+ _mesa_reference_framebuffer(&saved_fbo, NULL);
+ _mesa_PopClientAttrib();
+ _mesa_PopAttrib();
+
+ return success;
+}
+
+
+/**
+ * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap
+ * level).
+ *
+ * The texture object's miptree must be mapped.
+ *
+ * It would be really nice if this was just called by Mesa whenever mipmaps
+ * needed to be regenerated, rather than us having to remember to do so in
+ * each texture image modification path.
+ *
+ * This function should also include an accelerated path.
+ */
+void
+intel_generate_mipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_object *intelObj = intel_texture_object(texObj);
+ GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+ int face, i;
+
+ /* HW path */
+ if (target == GL_TEXTURE_2D &&
+ ctx->Extensions.EXT_framebuffer_object &&
+ ctx->Extensions.ARB_fragment_program &&
+ ctx->Extensions.ARB_vertex_program) {
+ GLboolean success;
+
+ /* We'll be accessing this texture using GL entrypoints, which should
+ * be resilient against other access to this texture.
+ */
+ _mesa_unlock_texture(ctx, texObj);
+ success = intel_generate_mipmap_2d(ctx, target, texObj);
+ _mesa_lock_texture(ctx, texObj);
+
+ if (success)
+ return;
+ }
+
+ /* SW path */
+ intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel);
+ _mesa_generate_mipmap(ctx, target, texObj);
+ intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel);
+
+ /* Update the level information in our private data in the new images, since
+ * it didn't get set as part of a normal TexImage path.
+ */
+ for (face = 0; face < nr_faces; face++) {
+ for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
+ struct intel_texture_image *intelImage;
+
+ intelImage = intel_texture_image(texObj->Image[face][i]);
+ if (intelImage == NULL)
+ break;
+
+ intelImage->level = i;
+ intelImage->face = face;
+ /* Unreference the miptree to signal that the new Data is a bare
+ * pointer from mesa.
+ */
+ intel_miptree_release(intel, &intelImage->mt);
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 6e1e034e53..0d34f28311 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -57,14 +57,16 @@ intel_miptree_create_internal(struct intel_context *intel,
GLuint last_level,
GLuint width0,
GLuint height0,
- GLuint depth0, GLuint cpp, GLuint compress_byte)
+ GLuint depth0, GLuint cpp, GLuint compress_byte,
+ uint32_t tiling)
{
GLboolean ok;
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
- DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
+ DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
- _mesa_lookup_enum_by_nr(internal_format), first_level, last_level);
+ _mesa_lookup_enum_by_nr(internal_format),
+ first_level, last_level, mt);
mt->target = target_to_target(target);
mt->internal_format = internal_format;
@@ -80,15 +82,16 @@ intel_miptree_create_internal(struct intel_context *intel,
#ifdef I915
if (IS_945(intel->intelScreen->deviceID))
- ok = i945_miptree_layout(intel, mt);
+ ok = i945_miptree_layout(intel, mt, tiling);
else
- ok = i915_miptree_layout(intel, mt);
+ ok = i915_miptree_layout(intel, mt, tiling);
#else
- ok = brw_miptree_layout(intel, mt);
+ ok = brw_miptree_layout(intel, mt, tiling);
#endif
if (!ok) {
free(mt);
+ DBG("%s not okay - returning NULL\n", __FUNCTION__);
return NULL;
}
@@ -107,10 +110,18 @@ intel_miptree_create(struct intel_context *intel,
GLboolean expect_accelerated_upload)
{
struct intel_mipmap_tree *mt;
+ uint32_t tiling;
+
+ if (intel->use_texture_tiling && compress_byte == 0 &&
+ intel->intelScreen->kernel_exec_fencing)
+ tiling = I915_TILING_X;
+ else
+ tiling = I915_TILING_NONE;
mt = intel_miptree_create_internal(intel, target, internal_format,
first_level, last_level, width0,
- height0, depth0, cpp, compress_byte);
+ height0, depth0, cpp, compress_byte,
+ tiling);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
@@ -118,6 +129,7 @@ intel_miptree_create(struct intel_context *intel,
return NULL;
mt->region = intel_region_alloc(intel,
+ tiling,
mt->cpp,
mt->pitch,
mt->total_height,
@@ -147,7 +159,8 @@ intel_miptree_create_for_region(struct intel_context *intel,
mt = intel_miptree_create_internal(intel, target, internal_format,
first_level, last_level,
region->width, region->height, 1,
- region->cpp, compress_byte);
+ region->cpp, compress_byte,
+ I915_TILING_NONE);
if (!mt)
return mt;
#if 0
@@ -185,6 +198,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
int intel_miptree_pitch_align (struct intel_context *intel,
struct intel_mipmap_tree *mt,
+ uint32_t tiling,
int pitch)
{
#ifdef I915
@@ -205,6 +219,11 @@ int intel_miptree_pitch_align (struct intel_context *intel,
pitch_align = 4;
}
+ if (tiling == I915_TILING_X)
+ pitch_align = 512;
+ else if (tiling == I915_TILING_Y)
+ pitch_align = 128;
+
pitch = ALIGN(pitch * mt->cpp, pitch_align);
#ifdef I915
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 4060b9df78..3af9966827 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -148,6 +148,7 @@ intel_miptree_create_for_region(struct intel_context *intel,
int intel_miptree_pitch_align (struct intel_context *intel,
struct intel_mipmap_tree *mt,
+ uint32_t tiling,
int pitch);
void intel_miptree_reference(struct intel_mipmap_tree **dst,
@@ -218,10 +219,13 @@ void intel_miptree_image_copy(struct intel_context *intel,
/* i915_mipmap_tree.c:
*/
GLboolean i915_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
GLboolean i945_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
GLboolean brw_miptree_layout(struct intel_context *intel,
- struct intel_mipmap_tree *mt);
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c
index fc0ac0b79c..36a684b3b8 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel.c
@@ -27,9 +27,12 @@
#include "main/enums.h"
#include "main/state.h"
+#include "main/bufferobj.h"
#include "main/context.h"
#include "main/enable.h"
#include "main/matrix.h"
+#include "main/texstate.h"
+#include "main/varray.h"
#include "main/viewport.h"
#include "swrast/swrast.h"
#include "shader/arbprogram.h"
@@ -334,6 +337,85 @@ intel_meta_restore_fragment_program(struct intel_context *intel)
_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)
{
@@ -355,5 +437,7 @@ intel_free_pixel_state(struct intel_context *intel)
_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);
}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h
index cb41fa182c..6acf0813c8 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.h
+++ b/src/mesa/drivers/dri/intel/intel_pixel.h
@@ -40,6 +40,9 @@ void intel_meta_set_fragment_program(struct intel_context *intel,
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);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
index 1db7f5594e..80d3239189 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -360,7 +360,6 @@ intel_texture_bitmap(GLcontext * ctx,
"END\n";
GLuint texname;
GLfloat vertices[4][4];
- GLfloat texcoords[4][2];
GLint old_active_texture;
GLubyte *unpacked_bitmap;
GLubyte *a8_bitmap;
@@ -401,6 +400,14 @@ intel_texture_bitmap(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glBitmap() fallback: NPOT texture\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))) {
@@ -485,22 +492,12 @@ intel_texture_bitmap(GLcontext * ctx,
vertices[3][2] = dst_z;
vertices[3][3] = 1.0;
- texcoords[0][0] = 0.0;
- texcoords[0][1] = 0.0;
- texcoords[1][0] = 1.0;
- texcoords[1][1] = 0.0;
- texcoords[2][0] = 1.0;
- texcoords[2][1] = 1.0;
- texcoords[3][0] = 0.0;
- texcoords[3][1] = 1.0;
-
_mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
- _mesa_ClientActiveTextureARB(GL_TEXTURE0);
- _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords);
_mesa_Enable(GL_VERTEX_ARRAY);
- _mesa_Enable(GL_TEXTURE_COORD_ARRAY);
+ intel_meta_set_default_texrect(intel);
CALL_DrawArrays(ctx->Exec, (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);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
index e8d5ac8569..7cda6adb32 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -70,7 +70,6 @@ intel_texture_drawpixels(GLcontext * ctx,
struct intel_context *intel = intel_context(ctx);
GLuint texname;
GLfloat vertices[4][4];
- GLfloat texcoords[4][2];
GLfloat z;
GLint old_active_texture;
GLenum internalFormat;
@@ -120,6 +119,14 @@ intel_texture_drawpixels(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glDrawPixels() fallback: NPOT texture\n");
+ return GL_FALSE;
+ }
+
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
GL_CURRENT_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
@@ -169,22 +176,13 @@ intel_texture_drawpixels(GLcontext * ctx,
vertices[3][2] = z;
vertices[3][3] = 1.0;
- texcoords[0][0] = 0.0;
- texcoords[0][1] = 0.0;
- texcoords[1][0] = 1.0;
- texcoords[1][1] = 0.0;
- texcoords[2][0] = 1.0;
- texcoords[2][1] = 1.0;
- texcoords[3][0] = 0.0;
- texcoords[3][1] = 1.0;
-
_mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
- _mesa_ClientActiveTextureARB(GL_TEXTURE0);
- _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords);
_mesa_Enable(GL_VERTEX_ARRAY);
- _mesa_Enable(GL_TEXTURE_COORD_ARRAY);
+ intel_meta_set_default_texrect(intel);
+
CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ intel_meta_restore_texcoords(intel);
intel_meta_restore_transform(intel);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
@@ -208,7 +206,6 @@ intel_stencil_drawpixels(GLcontext * ctx,
struct intel_context *intel = intel_context(ctx);
GLuint texname, rb_name, fb_name, old_fb_name;
GLfloat vertices[4][2];
- GLfloat texcoords[4][2];
struct intel_renderbuffer *irb;
struct intel_renderbuffer *depth_irb;
struct gl_renderbuffer *rb;
@@ -273,6 +270,14 @@ intel_stencil_drawpixels(GLcontext * ctx,
return GL_FALSE;
}
+ if (!ctx->Extensions.ARB_texture_non_power_of_two &&
+ (!is_power_of_two(width) || !is_power_of_two(height))) {
+ if (INTEL_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr,
+ "glDrawPixels(GL_STENCIL_INDEX) fallback: NPOT texture\n");
+ return GL_FALSE;
+ }
+
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
@@ -343,7 +348,6 @@ intel_stencil_drawpixels(GLcontext * ctx,
_mesa_free(stencil_pixels);
intel_meta_set_passthrough_transform(intel);
-
vertices[0][0] = x;
vertices[0][1] = y;
vertices[1][0] = x + width * ctx->Pixel.ZoomX;
@@ -353,22 +357,13 @@ intel_stencil_drawpixels(GLcontext * ctx,
vertices[3][0] = x;
vertices[3][1] = y + height * ctx->Pixel.ZoomY;
- texcoords[0][0] = 0.0;
- texcoords[0][1] = 0.0;
- texcoords[1][0] = 1.0;
- texcoords[1][1] = 0.0;
- texcoords[2][0] = 1.0;
- texcoords[2][1] = 1.0;
- texcoords[3][0] = 0.0;
- texcoords[3][1] = 1.0;
-
_mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);
- _mesa_ClientActiveTextureARB(GL_TEXTURE0);
- _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords);
_mesa_Enable(GL_VERTEX_ARRAY);
- _mesa_Enable(GL_TEXTURE_COORD_ARRAY);
+ intel_meta_set_default_texrect(intel);
+
CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+ intel_meta_restore_texcoords(intel);
intel_meta_restore_transform(intel);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h
index 57ac8f0cc1..d19f1bae34 100644
--- a/src/mesa/drivers/dri/intel/intel_reg.h
+++ b/src/mesa/drivers/dri/intel/intel_reg.h
@@ -189,6 +189,19 @@
#define S7_DEPTH_OFFSET_CONST_MASK ~0
+/* p143 */
+#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1)
+/* Dword 1 */
+#define BUF_3D_ID_COLOR_BACK (0x3<<24)
+#define BUF_3D_ID_DEPTH (0x7<<24)
+#define BUF_3D_USE_FENCE (1<<23)
+#define BUF_3D_TILED_SURFACE (1<<22)
+#define BUF_3D_TILE_WALK_X 0
+#define BUF_3D_TILE_WALK_Y (1<<21)
+#define BUF_3D_PITCH(x) (((x)/4)<<2)
+/* Dword 2 */
+#define BUF_3D_ADDR(x) ((x) & ~0x3)
+
/* Primitive dispatch on 830-945 */
#define _3DPRIMITIVE (CMD_3D | (0x1f << 24))
#define PRIM_INDIRECT (1<<23)
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 0aa5b8c02c..49bcb3c1dd 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -52,17 +52,74 @@
#define FILE_DEBUG_FLAG DEBUG_REGION
+/* This should be set to the maximum backtrace size desired.
+ * Set it to 0 to disable backtrace debugging.
+ */
+#define DEBUG_BACKTRACE_SIZE 0
+
+#if DEBUG_BACKTRACE_SIZE == 0
+/* Use the standard debug output */
+#define _DBG(...) DBG(__VA_ARGS__)
+#else
+/* Use backtracing debug output */
+#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);}
+
+/* Backtracing debug support */
+#include <execinfo.h>
+
+static void
+debug_backtrace(void)
+{
+ void *trace[DEBUG_BACKTRACE_SIZE];
+ char **strings = NULL;
+ int traceSize;
+ register int i;
+
+ traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE);
+ strings = backtrace_symbols(trace, traceSize);
+ if (strings == NULL) {
+ DBG("no backtrace:");
+ return;
+ }
+
+ /* Spit out all the strings with a colon separator. Ignore
+ * the first, since we don't really care about the call
+ * to debug_backtrace() itself. Skip until the final "/" in
+ * the trace to avoid really long lines.
+ */
+ for (i = 1; i < traceSize; i++) {
+ char *p = strings[i], *slash = strings[i];
+ while (*p) {
+ if (*p++ == '/') {
+ slash = p;
+ }
+ }
+
+ DBG("%s:", slash);
+ }
+
+ /* Free up the memory, and we're done */
+ free(strings);
+}
+
+#endif
+
+
+
/* XXX: Thread safety?
*/
GLubyte *
intel_region_map(struct intel_context *intel, struct intel_region *region)
{
- DBG("%s\n", __FUNCTION__);
+ _DBG("%s %p\n", __FUNCTION__, region);
if (!region->map_refcount++) {
if (region->pbo)
intel_region_cow(intel, region);
- dri_bo_map(region->buffer, GL_TRUE);
+ if (intel->intelScreen->kernel_exec_fencing)
+ drm_intel_gem_bo_map_gtt(region->buffer);
+ else
+ dri_bo_map(region->buffer, GL_TRUE);
region->map = region->buffer->virtual;
}
@@ -72,9 +129,12 @@ intel_region_map(struct intel_context *intel, struct intel_region *region)
void
intel_region_unmap(struct intel_context *intel, struct intel_region *region)
{
- DBG("%s\n", __FUNCTION__);
+ _DBG("%s %p\n", __FUNCTION__, region);
if (!--region->map_refcount) {
- dri_bo_unmap(region->buffer);
+ if (intel->intelScreen->kernel_exec_fencing)
+ drm_intel_gem_bo_unmap_gtt(region->buffer);
+ else
+ dri_bo_unmap(region->buffer);
region->map = NULL;
}
}
@@ -87,10 +147,10 @@ intel_region_alloc_internal(struct intel_context *intel,
{
struct intel_region *region;
- DBG("%s\n", __FUNCTION__);
-
- if (buffer == NULL)
+ if (buffer == NULL) {
+ _DBG("%s <-- NULL\n", __FUNCTION__);
return NULL;
+ }
region = calloc(sizeof(*region), 1);
region->cpp = cpp;
@@ -104,15 +164,18 @@ intel_region_alloc_internal(struct intel_context *intel,
region->tiling = I915_TILING_NONE;
region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE;
+ _DBG("%s <-- %p\n", __FUNCTION__, region);
return region;
}
struct intel_region *
intel_region_alloc(struct intel_context *intel,
+ uint32_t tiling,
GLuint cpp, GLuint width, GLuint height, GLuint pitch,
GLboolean expect_accelerated_upload)
{
dri_bo *buffer;
+ struct intel_region *region;
if (expect_accelerated_upload) {
buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
@@ -122,7 +185,16 @@ intel_region_alloc(struct intel_context *intel,
pitch * cpp * height, 64);
}
- return intel_region_alloc_internal(intel, cpp, width, height, pitch, buffer);
+ region = intel_region_alloc_internal(intel, cpp, width, height,
+ pitch, buffer);
+
+ if (tiling != I915_TILING_NONE) {
+ assert(((pitch * cpp) & 511) == 0);
+ drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp);
+ drm_intel_bo_get_tiling(buffer, &region->tiling, &region->bit_6_swizzle);
+ }
+
+ return region;
}
struct intel_region *
@@ -158,7 +230,7 @@ void
intel_region_reference(struct intel_region **dst, struct intel_region *src)
{
if (src)
- DBG("%s %p %d\n", __FUNCTION__, src, src->refcount);
+ _DBG("%s %p %d\n", __FUNCTION__, src, src->refcount);
assert(*dst == NULL);
if (src) {
@@ -172,10 +244,12 @@ intel_region_release(struct intel_region **region_handle)
{
struct intel_region *region = *region_handle;
- if (region == NULL)
+ if (region == NULL) {
+ _DBG("%s NULL\n", __FUNCTION__);
return;
+ }
- DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
+ _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
ASSERT(region->refcount > 0);
region->refcount--;
@@ -251,7 +325,7 @@ intel_region_data(struct intel_context *intel,
{
GLboolean locked = GL_FALSE;
- DBG("%s\n", __FUNCTION__);
+ _DBG("%s\n", __FUNCTION__);
if (intel == NULL)
return;
@@ -293,7 +367,7 @@ intel_region_copy(struct intel_context *intel,
GLuint src_offset,
GLuint srcx, GLuint srcy, GLuint width, GLuint height)
{
- DBG("%s\n", __FUNCTION__);
+ _DBG("%s\n", __FUNCTION__);
if (intel == NULL)
return;
@@ -326,7 +400,7 @@ intel_region_fill(struct intel_context *intel,
GLuint dstx, GLuint dsty,
GLuint width, GLuint height, GLuint color)
{
- DBG("%s\n", __FUNCTION__);
+ _DBG("%s\n", __FUNCTION__);
if (intel == NULL)
return;
@@ -356,6 +430,8 @@ intel_region_attach_pbo(struct intel_context *intel,
if (region->pbo == pbo)
return;
+ _DBG("%s %p %p\n", __FUNCTION__, region, pbo);
+
/* If there is already a pbo attached, break the cow tie now.
* Don't call intel_region_release_pbo() as that would
* unnecessarily allocate a new buffer we would have to immediately
@@ -385,6 +461,7 @@ void
intel_region_release_pbo(struct intel_context *intel,
struct intel_region *region)
{
+ _DBG("%s %p\n", __FUNCTION__, region);
assert(region->buffer == region->pbo->buffer);
region->pbo->region = NULL;
region->pbo = NULL;
@@ -412,7 +489,7 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region)
assert(region->cpp * region->pitch * region->height == pbo->Base.Size);
- DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size);
+ _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size);
/* Now blit from the texture buffer to the new buffer:
*/
@@ -459,6 +536,10 @@ intel_recreate_static(struct intel_context *intel,
if (region == NULL) {
region = calloc(sizeof(*region), 1);
region->refcount = 1;
+ _DBG("%s creating new region %p\n", __FUNCTION__, region);
+ }
+ else {
+ _DBG("%s %p\n", __FUNCTION__, region);
}
if (intel->ctx.Visual.rgbBits == 24)
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 45e2bf4e77..bd3c8e7325 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -73,7 +73,8 @@ struct intel_region
* copied by calling intel_reference_region().
*/
struct intel_region *intel_region_alloc(struct intel_context *intel,
- GLuint cpp, GLuint width,
+ uint32_t tiling,
+ GLuint cpp, GLuint width,
GLuint height, GLuint pitch,
GLboolean expect_accelerated_upload);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 65e62947ef..8da96ede64 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -49,6 +49,10 @@
#include "i915_drm.h"
#include "i830_dri.h"
+#define DRI_CONF_TEXTURE_TILING(def) \
+ DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \
+ DRI_CONF_DESC(en, "Enable texture tiling") \
+ DRI_CONF_OPT_END \
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
@@ -64,6 +68,17 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
DRI_CONF_DESC_END
DRI_CONF_OPT_END
+
+#ifdef I915
+ DRI_CONF_TEXTURE_TILING(false)
+#else
+ DRI_CONF_TEXTURE_TILING(true)
+#endif
+
+ DRI_CONF_OPT_BEGIN(early_z, bool, false)
+ DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
+ DRI_CONF_OPT_END
+
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
@@ -76,7 +91,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_SECTION_END
DRI_CONF_END;
-const GLuint __driNConfigOptions = 8;
+const GLuint __driNConfigOptions = 10;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
@@ -236,7 +251,7 @@ intel_get_param(__DRIscreenPrivate *psp, int param, int *value)
ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
if (ret) {
- fprintf(stderr, "drm_i915_getparam: %d\n", ret);
+ _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
return GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
index ae0994b183..df63f29a42 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -158,81 +158,11 @@ timed_memcpy(void *dest, const void *src, size_t n)
}
#endif /* DO_DEBUG */
-/**
- * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap
- * level).
- *
- * The texture object's miptree must be mapped.
- *
- * It would be really nice if this was just called by Mesa whenever mipmaps
- * needed to be regenerated, rather than us having to remember to do so in
- * each texture image modification path.
- *
- * This function should also include an accelerated path.
- */
-void
-intel_generate_mipmap(GLcontext *ctx, GLenum target,
- struct gl_texture_object *texObj)
-{
- struct intel_context *intel = intel_context(ctx);
- struct intel_texture_object *intelObj = intel_texture_object(texObj);
- GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
- int face, i;
-
- _mesa_generate_mipmap(ctx, target, texObj);
-
- /* Update the level information in our private data in the new images, since
- * it didn't get set as part of a normal TexImage path.
- */
- for (face = 0; face < nr_faces; face++) {
- for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
- struct intel_texture_image *intelImage;
-
- intelImage = intel_texture_image(texObj->Image[face][i]);
- if (intelImage == NULL)
- break;
-
- intelImage->level = i;
- intelImage->face = face;
- /* Unreference the miptree to signal that the new Data is a bare
- * pointer from mesa.
- */
- intel_miptree_release(intel, &intelImage->mt);
- }
- }
-}
-
-static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj)
-{
- struct intel_context *intel = intel_context(ctx);
- struct intel_texture_object *intelObj = intel_texture_object(texObj);
-
- intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel);
- intel_generate_mipmap(ctx, target, texObj);
- intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel);
-}
-
void
intelInitTextureFuncs(struct dd_function_table *functions)
{
functions->ChooseTextureFormat = intelChooseTextureFormat;
- functions->TexImage1D = intelTexImage1D;
- functions->TexImage2D = intelTexImage2D;
- functions->TexImage3D = intelTexImage3D;
- functions->TexSubImage1D = intelTexSubImage1D;
- functions->TexSubImage2D = intelTexSubImage2D;
- functions->TexSubImage3D = intelTexSubImage3D;
- functions->CopyTexImage1D = intelCopyTexImage1D;
- functions->CopyTexImage2D = intelCopyTexImage2D;
- functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
- functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
- functions->GetTexImage = intelGetTexImage;
- functions->GenerateMipmap = intelGenerateMipmap;
-
- /* compressed texture functions */
- functions->CompressedTexImage2D = intelCompressedTexImage2D;
- functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
- functions->GetCompressedTexImage = intelGetCompressedTexImage;
+ functions->GenerateMipmap = intel_generate_mipmap;
functions->NewTextureObject = intelNewTextureObject;
functions->NewTextureImage = intelNewTextureImage;
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index f5372d82fb..471aa2a240 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -35,116 +35,17 @@
void intelInitTextureFuncs(struct dd_function_table *functions);
+void intelInitTextureImageFuncs(struct dd_function_table *functions);
+
+void intelInitTextureSubImageFuncs(struct dd_function_table *functions);
+
+void intelInitTextureCopyImageFuncs(struct dd_function_table *functions);
+
const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx,
GLint internalFormat,
GLenum format,
GLenum type);
-
-void intelTexImage3D(GLcontext * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelTexSubImage3D(GLcontext * ctx,
- GLenum target,
- GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelTexImage2D(GLcontext * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelTexSubImage2D(GLcontext * ctx,
- GLenum target,
- GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelTexImage1D(GLcontext * ctx,
- GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelTexSubImage1D(GLcontext * ctx,
- GLenum target,
- GLint level,
- GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border);
-
-void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border);
-
-void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width);
-
-void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height);
-
-void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid * pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage );
-
-void intelCompressedTexSubImage2D(GLcontext * ctx,
- GLenum target,
- GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid * pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
-void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
- GLvoid *pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage);
-
void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth, GLuint pitch);
void intelSetTexBuffer(__DRIcontext *pDRICtx,
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 90bbb8c6bb..260235b1eb 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -118,8 +118,12 @@ do_copy_texsubimage(struct intel_context *intel,
dstx += x - orig_x;
dsty += y - orig_y;
- /* image_offset may be non-page-aligned, but that's illegal for tiling. */
- assert(intelImage->mt->region->tiling == I915_TILING_NONE);
+ /* Can't blit to tiled buffers with non-tile-aligned offset. */
+ if (intelImage->mt->region->tiling != I915_TILING_NONE &&
+ (image_offset & 4095) != 0) {
+ UNLOCK_HARDWARE(intel);
+ return GL_FALSE;
+ }
if (ctx->ReadBuffer->Name == 0) {
/* reading from a window, adjust x, y */
@@ -158,17 +162,14 @@ do_copy_texsubimage(struct intel_context *intel,
/* GL_SGIS_generate_mipmap */
if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ intel_generate_mipmap(ctx, target, texObj);
}
return GL_TRUE;
}
-
-
-
-void
+static void
intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLint border)
@@ -214,7 +215,8 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
width, border);
}
-void
+
+static void
intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
@@ -262,7 +264,7 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
}
-void
+static void
intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width)
{
@@ -287,8 +289,7 @@ intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
}
-
-void
+static void
intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height)
@@ -301,7 +302,6 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
_mesa_select_tex_image(ctx, texObj, target, level);
GLenum internalFormat = texImage->InternalFormat;
-
/* Need to check texture is compatible with source format.
*/
@@ -316,3 +316,13 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
xoffset, yoffset, x, y, width, height);
}
}
+
+
+void
+intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
+{
+ functions->CopyTexImage1D = intelCopyTexImage1D;
+ functions->CopyTexImage2D = intelCopyTexImage2D;
+ functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
+ functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 1f192dafbe..e9a3823078 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -208,7 +208,7 @@ try_pbo_upload(struct intel_context *intel,
if (!pbo ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
- _mesa_printf("%s: failure 1\n", __FUNCTION__);
+ DBG("%s: failure 1\n", __FUNCTION__);
return GL_FALSE;
}
@@ -248,7 +248,6 @@ try_pbo_upload(struct intel_context *intel,
}
-
static GLboolean
try_pbo_zcopy(struct intel_context *intel,
struct intel_texture_image *intelImage,
@@ -264,7 +263,7 @@ try_pbo_zcopy(struct intel_context *intel,
if (!pbo ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
- _mesa_printf("%s: failure 1\n", __FUNCTION__);
+ DBG("%s: failure 1\n", __FUNCTION__);
return GL_FALSE;
}
@@ -283,7 +282,7 @@ try_pbo_zcopy(struct intel_context *intel,
dst_stride = intelImage->mt->pitch;
if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) {
- _mesa_printf("%s: failure 2\n", __FUNCTION__);
+ DBG("%s: failure 2\n", __FUNCTION__);
return GL_FALSE;
}
@@ -293,10 +292,6 @@ try_pbo_zcopy(struct intel_context *intel,
}
-
-
-
-
static void
intelTexImage(GLcontext * ctx,
GLint dims,
@@ -307,7 +302,8 @@ intelTexImage(GLcontext * ctx,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *unpack,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
+ struct gl_texture_image *texImage, GLsizei imageSize,
+ GLboolean compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_object *intelObj = intel_texture_object(texObj);
@@ -316,7 +312,6 @@ intelTexImage(GLcontext * ctx,
GLint postConvHeight = height;
GLint texelBytes, sizeInBytes;
GLuint dstRowStride = 0, srcRowStride = texImage->RowStride;
- GLboolean needs_map;
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
@@ -464,8 +459,6 @@ intelTexImage(GLcontext * ctx,
DBG("pbo upload failed\n");
}
-
-
/* intelCopyTexImage calls this function with pixels == NULL, with
* the expectation that the mipmap tree will be set up but nothing
* more will be done. This is where those calls return:
@@ -482,15 +475,8 @@ intelTexImage(GLcontext * ctx,
LOCK_HARDWARE(intel);
- /* Two cases where we need a mapping of the miptree: when the user supplied
- * data is mapped as well (non-PBO, memcpy upload) or when we're going to do
- * (software) mipmap generation.
- */
- needs_map = (pixels != NULL) || (level == texObj->BaseLevel &&
- texObj->GenerateMipmap);
-
if (intelImage->mt) {
- if (needs_map)
+ if (pixels != NULL)
texImage->Data = intel_miptree_image_map(intel,
intelImage->mt,
intelImage->face,
@@ -547,25 +533,26 @@ intelTexImage(GLcontext * ctx,
format, type, pixels, unpack)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target, texObj);
- }
}
_mesa_unmap_teximage_pbo(ctx, unpack);
if (intelImage->mt) {
- if (needs_map)
+ if (pixels != NULL)
intel_miptree_image_unmap(intel, intelImage->mt);
texImage->Data = NULL;
}
UNLOCK_HARDWARE(intel);
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ intel_generate_mipmap(ctx, target, texObj);
+ }
}
-void
+
+static void
intelTexImage3D(GLcontext * ctx,
GLenum target, GLint level,
GLint internalFormat,
@@ -578,11 +565,11 @@ intelTexImage3D(GLcontext * ctx,
{
intelTexImage(ctx, 3, target, level,
internalFormat, width, height, depth, border,
- format, type, pixels, unpack, texObj, texImage, 0, 0);
+ format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
}
-void
+static void
intelTexImage2D(GLcontext * ctx,
GLenum target, GLint level,
GLint internalFormat,
@@ -594,10 +581,11 @@ intelTexImage2D(GLcontext * ctx,
{
intelTexImage(ctx, 2, target, level,
internalFormat, width, height, 1, border,
- format, type, pixels, unpack, texObj, texImage, 0, 0);
+ format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
}
-void
+
+static void
intelTexImage1D(GLcontext * ctx,
GLenum target, GLint level,
GLint internalFormat,
@@ -609,21 +597,24 @@ intelTexImage1D(GLcontext * ctx,
{
intelTexImage(ctx, 1, target, level,
internalFormat, width, 1, 1, border,
- format, type, pixels, unpack, texObj, texImage, 0, 0);
+ format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
}
-void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
+
+static void
+intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid *data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage )
{
intelTexImage(ctx, 2, target, level,
internalFormat, width, height, 1, border,
- 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
+ 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE);
}
+
/**
* Need to map texture image into memory before copying image data,
* then unmap it.
@@ -632,11 +623,17 @@ static void
intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
GLenum format, GLenum type, GLvoid * pixels,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage, int compressed)
+ struct gl_texture_image *texImage, GLboolean compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
+ /* If we're reading from a texture that has been rendered to, need to
+ * make sure rendering is complete.
+ * We could probably predicate this on texObj->_RenderToTexture
+ */
+ intelFlush(ctx);
+
/* Map */
if (intelImage->mt) {
/* Image is stored in hardware format in a buffer managed by the
@@ -680,28 +677,29 @@ intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
}
}
-void
+
+static void
intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
GLenum format, GLenum type, GLvoid * pixels,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intel_get_tex_image(ctx, target, level, format, type, pixels,
- texObj, texImage, 0);
-
-
+ texObj, texImage, GL_FALSE);
}
-void
+
+static void
intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
GLvoid *pixels,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
intel_get_tex_image(ctx, target, level, 0, 0, pixels,
- texObj, texImage, 1);
+ texObj, texImage, GL_TRUE);
}
+
void
intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth, GLuint pitch)
@@ -810,3 +808,16 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
*/
intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
}
+
+
+void
+intelInitTextureImageFuncs(struct dd_function_table *functions)
+{
+ functions->TexImage1D = intelTexImage1D;
+ functions->TexImage2D = intelTexImage2D;
+ functions->TexImage3D = intelTexImage3D;
+ functions->GetTexImage = intelGetTexImage;
+
+ functions->CompressedTexImage2D = intelCompressedTexImage2D;
+ functions->GetCompressedTexImage = intelGetCompressedTexImage;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index e6f9a41779..2c1b722b7f 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -52,7 +52,9 @@ GLuint intel_compressed_alignment(GLenum internalFormat)
return alignment;
}
-void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )
+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 level;
@@ -92,7 +94,7 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch);
+ mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->pitch);
mt->total_height = 0;
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
index dbc90e6f9b..7bc25b6bcb 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -38,5 +38,7 @@ static GLuint minify( GLuint d )
return MAX2(1, d>>1);
}
-extern void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt );
+extern void i945_miptree_layout_2d(struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ uint32_t tiling);
extern GLuint intel_compressed_alignment(GLenum);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index f86de56897..1f27131dac 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -101,11 +101,6 @@ intelTexSubimage(GLcontext * ctx,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
if (intelImage->mt) {
@@ -114,13 +109,15 @@ intelTexSubimage(GLcontext * ctx,
}
UNLOCK_HARDWARE(intel);
-}
-
-
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ intel_generate_mipmap(ctx, target, texObj);
+ }
+}
-void
+static void
intelTexSubImage3D(GLcontext * ctx,
GLenum target,
GLint level,
@@ -132,18 +129,15 @@ intelTexSubImage3D(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
-
intelTexSubimage(ctx, 3,
target, level,
xoffset, yoffset, zoffset,
width, height, depth,
format, type, pixels, packing, texObj, texImage);
-
}
-
-void
+static void
intelTexSubImage2D(GLcontext * ctx,
GLenum target,
GLint level,
@@ -155,17 +149,15 @@ intelTexSubImage2D(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
-
intelTexSubimage(ctx, 2,
target, level,
xoffset, yoffset, 0,
width, height, 1,
format, type, pixels, packing, texObj, texImage);
-
}
-void
+static void
intelTexSubImage1D(GLcontext * ctx,
GLenum target,
GLint level,
@@ -182,10 +174,9 @@ intelTexSubImage1D(GLcontext * ctx,
xoffset, 0, 0,
width, 1, 1,
format, type, pixels, packing, texObj, texImage);
-
}
-void
+static void
intelCompressedTexSubImage2D(GLcontext * ctx,
GLenum target,
GLint level,
@@ -199,3 +190,14 @@ intelCompressedTexSubImage2D(GLcontext * ctx,
fprintf(stderr, "stubbed CompressedTexSubImage2D: %dx%d@%dx%d\n",
width, height, xoffset, yoffset);
}
+
+
+
+void
+intelInitTextureSubImageFuncs(struct dd_function_table *functions)
+{
+ functions->TexSubImage1D = intelTexSubImage1D;
+ functions->TexSubImage2D = intelTexSubImage2D;
+ functions->TexSubImage3D = intelTexSubImage3D;
+ functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index 05a375e1f3..b5cb7597d1 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -241,7 +241,7 @@ intel_tex_map_level_images(struct intel_context *intel,
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][level]);
- if (intelImage->mt) {
+ if (intelImage && intelImage->mt) {
intelImage->base.Data =
intel_miptree_image_map(intel,
intelImage->mt,
@@ -268,7 +268,7 @@ intel_tex_unmap_level_images(struct intel_context *intel,
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][level]);
- if (intelImage->mt) {
+ if (intelImage && intelImage->mt) {
intel_miptree_image_unmap(intel, intelImage->mt);
intelImage->base.Data = NULL;
}
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 2fcc87c0f5..81ee1ed022 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -2480,11 +2480,11 @@ void r200ValidateState( GLcontext *ctx )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint new_state = rmesa->NewGLState;
- if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
+ if (new_state & _NEW_BUFFERS) {
r200UpdateDrawBuffer(ctx);
}
- if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) {
+ if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
r200UpdateTextureState( ctx );
new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */
r200UpdateLocalViewer( ctx );
@@ -2523,6 +2523,7 @@ void r200ValidateState( GLcontext *ctx )
}
if (new_state & (_NEW_PROGRAM|
+ _NEW_PROGRAM_CONSTANTS |
/* need to test for pretty much anything due to possible parameter bindings */
_NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
_NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 873cde4414..2f45429cf2 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -470,7 +470,8 @@ void r300TranslateFragmentShader(r300ContextPtr r300,
fp->translated = GL_TRUE;
if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
r300FragmentProgramDump(fp, &fp->code);
- r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
+ r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM |
+ _NEW_PROGRAM_CONSTANTS);
}
update_params(r300, fp);
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 79f0b3625c..07299f3b36 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -1109,7 +1109,7 @@ void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
struct gl_program_parameter_list *paramList;
GLuint i;
- if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM)))
+ if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
return;
fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;
@@ -2357,11 +2357,12 @@ void r300UpdateShaders(r300ContextPtr rmesa)
hw_tcl_on = future_hw_tcl_on = 0;
r300ResetHwState(rmesa);
- r300UpdateStateParameters(ctx, _NEW_PROGRAM);
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM |
+ _NEW_PROGRAM_CONSTANTS);
return;
}
}
- r300UpdateStateParameters(ctx, _NEW_PROGRAM);
+ r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
}
static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx,
@@ -2588,7 +2589,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
_tnl_InvalidateState(ctx, new_state);
_ae_invalidate_state(ctx, new_state);
- if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
+ if (new_state & _NEW_BUFFERS) {
r300UpdateDrawBuffer(ctx);
}
diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c
index 292573de89..300559d0b4 100644
--- a/src/mesa/drivers/dri/r300/r500_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r500_fragprog.c
@@ -501,7 +501,8 @@ void r500TranslateFragmentShader(r300ContextPtr r300,
_mesa_reference_program(r300->radeon.glCtx, &compiler.program, 0);
- r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
+ r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM |
+ _NEW_PROGRAM_CONSTANTS);
if (RADEON_DEBUG & DEBUG_PIXEL) {
if (fp->translated) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index b6561001e7..4432f85691 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -2255,7 +2255,7 @@ void radeonValidateState( GLcontext *ctx )
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint new_state = rmesa->NewGLState;
- if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
+ if (new_state & _NEW_BUFFERS) {
radeonUpdateDrawBuffer(ctx);
}
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 305df548fa..9a01465bdf 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -912,8 +912,9 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state )
/*
* GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect
* renderbuffer span/clear funcs.
+ * Check _NEW_COLOR to detect dither enable/disable.
*/
- if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) {
+ if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) {
XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
struct xmesa_renderbuffer *front_xrb, *back_xrb;