intel_ioctl.c \
intel_pixel.c \
intel_render.c \
+ intel_rotate.c \
intel_screen.c \
intel_span.c \
intel_state.c \
intel_tex.c \
+ intel_texmem.c \
intel_tris.c
C_SOURCES = \
i830ClearWithTris( intelContextPtr intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
+extern void
+i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+ GLuint srcBuf);
-
#endif
#define SET_STATE( i830, STATE ) \
do { \
- i830->current->emitted &= ~ACTIVE; \
+ assert(!i830->intel.prim.flush); \
+ i830->current->emitted = 0; \
i830->current = &i830->STATE; \
- i830->current->emitted &= ~ACTIVE; \
+ i830->current->emitted = 0; \
} while (0)
/* Operations where the 3D engine is decoupled temporarily from the
(1 << WRITEMASK_BLUE_SHIFT) |
(1 << WRITEMASK_ALPHA_SHIFT));
+ i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask;
+
if (state) {
- i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask;
i830->meta.Ctx[I830_CTXREG_ENABLES_2] |=
(i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask);
}
- else
- i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= mask;
i830->meta.emitted &= ~I830_UPLOAD_CTX;
}
/* Set up a single element blend stage for 'replace' texturing with no
* funny ops.
*/
-static void enable_texture_blend_replace( i830ContextPtr i830,
- GLenum format )
+static void enable_texture_blend_replace( i830ContextPtr i830 )
{
static const struct gl_tex_env_combine_state comb = {
GL_REPLACE, GL_REPLACE,
- { GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, },
- { GL_SRC_COLOR, 0, 0 }, { GL_SRC_ALPHA, 0, 0 },
+ { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE }, { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, },
+ { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR }, { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
0, 0, 1, 1
};
GLuint offset,
GLuint width,
GLuint height,
- GLuint pitch,
+ GLuint pitch, /* in bytes */
GLuint textureFormat )
{
GLint numLevels = 1;
GLuint *setup = i830->meta.Tex[0];
- pitch *= i830->intel.intelScreen->cpp;
-
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
/* Select between front and back draw buffers.
*/
-static void set_draw_offset( i830ContextPtr i830,
- GLuint offset )
+static void set_draw_region( i830ContextPtr i830,
+ const intelRegion *region )
{
- i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset;
+ i830->meta.Buffer[I830_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = region->offset;
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
}
/* Setup an arbitary draw format, useful for targeting
* texture or agp memory.
*/
+#if 0
static void set_draw_format( i830ContextPtr i830,
GLuint format,
GLuint depth_format)
DEPTH_IS_Z |
depth_format);
}
+#endif
static void set_vertex_format( i830ContextPtr i830 )
/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
}
+static void draw_poly(i830ContextPtr i830,
+ GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha,
+ GLuint numVerts,
+ GLfloat verts[][2],
+ GLfloat texcoords[][2])
+{
+ GLuint vertex_size = 8;
+ GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
+ PRIM3D_TRIFAN,
+ numVerts * vertex_size,
+ vertex_size );
+ intelVertex tmp;
+ int i, k;
+
+ /* initial constant vertex fields */
+ tmp.v.z = 1.0;
+ tmp.v.w = 1.0;
+ tmp.v.color.red = red;
+ tmp.v.color.green = green;
+ tmp.v.color.blue = blue;
+ tmp.v.color.alpha = alpha;
+ tmp.v.specular.red = 0;
+ tmp.v.specular.green = 0;
+ tmp.v.specular.blue = 0;
+ tmp.v.specular.alpha = 0;
+
+ for (k = 0; k < numVerts; k++) {
+ tmp.v.x = verts[k][0];
+ tmp.v.y = verts[k][1];
+ tmp.v.u0 = texcoords[k][0];
+ tmp.v.v0 = texcoords[k][1];
+
+ for (i = 0 ; i < vertex_size ; i++)
+ vb[i] = tmp.ui[i];
+
+ vb += vertex_size;
+ }
+}
+
void
i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
-
+ INTEL_FIREVERTICES(intel);
SET_STATE( i830, meta );
set_initial_state( i830 );
- set_no_texture( i830 );
+/* set_no_texture( i830 ); */
set_vertex_format( i830 );
LOCK_HARDWARE(intel);
if(mask & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
- set_draw_offset( i830, screen->front.offset );
+ set_draw_region( i830, &screen->front );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->clear_blue, intel->clear_alpha,
if(mask & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i830 );
set_color_mask( i830, GL_TRUE );
- set_draw_offset( i830, screen->back.offset );
+ set_draw_region( i830, &screen->back );
draw_quad(i830, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->ctx.Stencil.Clear);
set_color_mask( i830, GL_FALSE );
- set_draw_offset( i830, screen->front.offset );
+ set_draw_region( i830, &screen->front );
draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
UNLOCK_HARDWARE(intel);
+ INTEL_FIREVERTICES(intel);
SET_STATE( i830, state );
}
-
+#if 0
GLboolean
i830TryTextureReadPixels( GLcontext *ctx,
textureFormat );
- enable_texture_blend_replace( i830, glTextureFormat );
+ enable_texture_blend_replace( i830 );
/* Set the 3d engine to draw into the agp memory
*/
- set_draw_offset( i830, destOffset );
+ set_draw_region( i830, destOffset );
set_draw_format( i830, destFormat, depthFormat );
!ctx->Color.ColorMask[2] ||
!ctx->Color.ColorMask[3] ||
ctx->Color.ColorLogicOpEnabled ||
- ctx->Texture._EnabledUnits) {
+ ctx->Texture._EnabledUnits ||
+ ctx->Depth.OcclusionTest) {
fprintf(stderr, "%s: other tests failed\n", __FUNCTION__);
return GL_FALSE;
}
textureFormat );
- enable_texture_blend_replace( i830, glTextureFormat );
+ enable_texture_blend_replace( i830 );
/* Draw to the current draw buffer:
return GL_TRUE;
}
+#endif
+
+/**
+ * Copy the window contents named by dPriv to the rotated (or reflected)
+ * color buffer.
+ * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
+ */
+void
+i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+ GLuint srcBuf)
+{
+ i830ContextPtr i830 = I830_CONTEXT( intel );
+ intelScreenPrivate *screen = intel->intelScreen;
+ const GLuint cpp = screen->cpp;
+ drm_clip_rect_t fullRect;
+ GLuint textureFormat, srcOffset, srcPitch;
+ const drm_clip_rect_t *clipRects;
+ int numClipRects;
+ int i;
+
+ int xOrig, yOrig;
+ int origNumClipRects;
+ drm_clip_rect_t *origRects;
+
+ /*
+ * set up hardware state
+ */
+ intelFlush( &intel->ctx );
+
+ SET_STATE( i830, meta );
+ set_initial_state( i830 );
+ set_no_texture( i830 );
+ set_vertex_format( i830 );
+ set_no_depth_stencil_write( i830 );
+ set_color_mask( i830, GL_FALSE );
+
+ LOCK_HARDWARE(intel);
+
+ /* save current drawing origin and cliprects (restored at end) */
+ xOrig = intel->drawX;
+ yOrig = intel->drawY;
+ origNumClipRects = intel->numClipRects;
+ origRects = intel->pClipRects;
+
+ if (!intel->numClipRects)
+ goto done;
+
+ /*
+ * set drawing origin, cliprects for full-screen access to rotated screen
+ */
+ fullRect.x1 = 0;
+ fullRect.y1 = 0;
+ fullRect.x2 = screen->rotatedWidth;
+ fullRect.y2 = screen->rotatedHeight;
+ intel->drawX = 0;
+ intel->drawY = 0;
+ intel->numClipRects = 1;
+ intel->pClipRects = &fullRect;
+
+ set_draw_region( i830, &screen->rotated );
+
+ if (cpp == 4)
+ textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ else
+ textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
+
+ if (srcBuf == BUFFER_BIT_FRONT_LEFT) {
+ srcPitch = screen->front.pitch; /* in bytes */
+ srcOffset = screen->front.offset; /* bytes */
+ clipRects = dPriv->pClipRects;
+ numClipRects = dPriv->numClipRects;
+ }
+ else {
+ srcPitch = screen->back.pitch; /* in bytes */
+ srcOffset = screen->back.offset; /* bytes */
+ clipRects = dPriv->pBackClipRects;
+ numClipRects = dPriv->numBackClipRects;
+ }
+
+ /* set the whole screen up as a texture to avoid alignment issues */
+ set_tex_rect_source(i830,
+ srcOffset,
+ screen->width,
+ screen->height,
+ srcPitch,
+ textureFormat);
+
+ enable_texture_blend_replace(i830);
+
+ /*
+ * loop over the source window's cliprects
+ */
+ for (i = 0; i < numClipRects; i++) {
+ int srcX0 = clipRects[i].x1;
+ int srcY0 = clipRects[i].y1;
+ int srcX1 = clipRects[i].x2;
+ int srcY1 = clipRects[i].y2;
+ GLfloat verts[4][2], tex[4][2];
+ int j;
+
+ /* build vertices for four corners of clip rect */
+ verts[0][0] = srcX0; verts[0][1] = srcY0;
+ verts[1][0] = srcX1; verts[1][1] = srcY0;
+ verts[2][0] = srcX1; verts[2][1] = srcY1;
+ verts[3][0] = srcX0; verts[3][1] = srcY1;
+
+ /* .. and texcoords */
+ tex[0][0] = srcX0; tex[0][1] = srcY0;
+ tex[1][0] = srcX1; tex[1][1] = srcY0;
+ tex[2][0] = srcX1; tex[2][1] = srcY1;
+ tex[3][0] = srcX0; tex[3][1] = srcY1;
+
+ /* transform coords to rotated screen coords */
+
+ for (j = 0; j < 4; j++) {
+ matrix23TransformCoordf(&screen->rotMatrix,
+ &verts[j][0], &verts[j][1]);
+ }
+
+ /* draw polygon to map source image to dest region */
+ draw_poly(i830, 255, 255, 255, 255, 4, verts, tex);
+
+ } /* cliprect loop */
+
+ assert(!intel->prim.flush);
+ intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE );
+
+ done:
+ /* restore original drawing origin and cliprects */
+ intel->drawX = xOrig;
+ intel->drawY = yOrig;
+ intel->numClipRects = origNumClipRects;
+ intel->pClipRects = origRects;
+
+ UNLOCK_HARDWARE(intel);
+
+ SET_STATE( i830, state );
+}
+
i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
+ BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
+ BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset;
}
}
+static void i830BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj )
+{
+ i830TextureObjectPtr tex;
+
+ if (!texObj->DriverData)
+ i830AllocTexObj( texObj );
+
+ tex = (i830TextureObjectPtr)texObj->DriverData;
+}
void i830InitTextureFuncs( struct dd_function_table *functions )
{
+ functions->BindTexture = i830BindTexture;
functions->TexEnv = i830TexEnv;
functions->TexParameter = i830TexParameter;
}
ADVANCE_BATCH(); \
} while (0);
+static GLuint get_state_size( struct i830_hw_state *state )
+{
+ GLuint dirty = state->active & ~state->emitted;
+ GLuint sz = 0;
+ GLuint i;
+
+ if (dirty & I830_UPLOAD_CTX)
+ sz += sizeof(state->Ctx);
+
+ if (dirty & I830_UPLOAD_BUFFERS)
+ sz += sizeof(state->Buffer);
+
+ if (dirty & I830_UPLOAD_STIPPLE)
+ sz += sizeof(state->Stipple);
+
+ for (i = 0; i < I830_TEX_UNITS; i++) {
+ if ((dirty & I830_UPLOAD_TEX(i)))
+ sz += sizeof(state->Tex[i]);
+
+ if (dirty & I830_UPLOAD_TEXBLEND(i))
+ sz += state->TexBlendWordsUsed[i] * 4;
+ }
+
+ return sz;
+}
+
/* Push the state into the sarea and/or texture memory.
*/
i830ContextPtr i830 = I830_CONTEXT(intel);
struct i830_hw_state *state = i830->current;
int i;
- GLuint dirty;
+ GLuint dirty = state->active & ~state->emitted;
+ GLuint counter = intel->batch.counter;
BATCH_LOCALS;
- dirty = state->active & ~state->emitted;
+ if (intel->batch.space < get_state_size(state)) {
+ intelFlushBatch(intel, GL_TRUE);
+ dirty = state->active & ~state->emitted;
+ counter = intel->batch.counter;
+ }
if (dirty & I830_UPLOAD_CTX) {
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_CTX:\n");
}
state->emitted |= dirty;
+ intel->batch.last_emit_state = counter;
+ assert(counter == intel->batch.counter);
}
static void i830_destroy_context( intelContextPtr intel )
_tnl_free_vertices(&intel->ctx);
}
-static void i830_set_draw_offset( intelContextPtr intel, int offset )
+static void
+i830_set_color_region(intelContextPtr intel, const intelRegion *region)
+{
+ i830ContextPtr i830 = I830_CONTEXT(intel);
+ I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
+ i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i830->state.Buffer[I830_DESTREG_CBUFADDR2] = region->offset;
+}
+
+
+static void
+i830_set_z_region(intelContextPtr intel, const intelRegion *region)
{
i830ContextPtr i830 = I830_CONTEXT(intel);
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
- i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset;
+ i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
+ (BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i830->state.Buffer[I830_DESTREG_DBUFADDR2] = region->offset;
}
+
+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;
+}
+
+
/* This isn't really handled at the moment.
*/
static void i830_lost_hardware( intelContextPtr intel )
i830->intel.vtbl.alloc_tex_obj = i830AllocTexObj;
i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
i830->intel.vtbl.clear_with_tris = i830ClearWithTris;
+ i830->intel.vtbl.rotate_window = i830RotateWindow;
i830->intel.vtbl.destroy = i830_destroy_context;
i830->intel.vtbl.emit_invarient_state = i830_emit_invarient_state;
i830->intel.vtbl.emit_state = i830_emit_state;
i830->intel.vtbl.lost_hardware = i830_lost_hardware;
i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state;
- i830->intel.vtbl.set_draw_offset = i830_set_draw_offset;
+ i830->intel.vtbl.set_color_region = i830_set_color_region;
+ i830->intel.vtbl.set_z_region = i830_set_z_region;
+ i830->intel.vtbl.update_color_z_regions = i830_update_color_z_regions;
i830->intel.vtbl.update_texture_state = i830UpdateTextureState;
i830->intel.vtbl.emit_flush = i830_emit_flush;
i830->intel.vtbl.render_start = i830_render_start;
#define I915_FALLBACK_STIPPLE 0x8000
#define I915_FALLBACK_PROGRAM 0x10000
#define I915_FALLBACK_LOGICOP 0x20000
+#define I915_FALLBACK_POLYGON_SMOOTH 0x40000
+#define I915_FALLBACK_POINT_SMOOTH 0x80000
#define I915_UPLOAD_CTX 0x1
#define I915_UPLOAD_BUFFERS 0x2
*/
extern void i915InitStateFunctions( struct dd_function_table *functions );
extern void i915InitState( i915ContextPtr i915 );
-extern void i915_update_fog( GLcontext *ctx );
/*======================================================================
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
+extern void
+i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+ GLuint srcBuf);
+
/*======================================================================
* i915_fragprog.c
*/
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
+#include "intel_rotate.h"
#include "i915_context.h"
#include "i915_reg.h"
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
}
-#if 0
+
static void enable_texture_blend_replace( i915ContextPtr i915 )
{
static const GLuint prog[] = {
GLuint offset,
GLuint width,
GLuint height,
- GLuint pitch,
+ GLuint pitch, /* in bytes! */
GLuint textureFormat )
{
GLuint unit = 0;
GLint numLevels = 1;
GLuint *state = i915->meta.Tex[0];
- pitch *= i915->intel.intelScreen->cpp;
+#if 0
+ printf("TexRect source offset 0x%x pitch %d\n", offset, pitch);
+#endif
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
MS3_USE_FENCE_REGS);
state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
- MS4_CUBE_FACE_ENA_MASK |
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) |
i915->meta.emitted &= ~I915_UPLOAD_TEX(0);
}
-#endif
+
/* Select between front and back draw buffers.
*/
-static void set_draw_offset( i915ContextPtr i915,
- GLuint offset )
+static void set_draw_region( i915ContextPtr i915, const intelRegion *region )
{
- i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = offset;
+#if 0
+ printf("Rotate into region: offset 0x%x pitch %d\n",
+ region->offset, region->pitch);
+#endif
+ i915->meta.Buffer[I915_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = region->offset;
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
}
+
#if 0
/* Setup an arbitary draw format, useful for targeting texture or agp
* memory.
vb[i] = tmp.ui[i];
}
+
+static void draw_poly(i915ContextPtr i915,
+ GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha,
+ GLuint numVerts,
+ /*const*/ GLfloat verts[][2],
+ /*const*/ GLfloat texcoords[][2])
+{
+ GLuint vertex_size = 8;
+ GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
+ PRIM3D_TRIFAN,
+ numVerts * vertex_size,
+ vertex_size );
+ intelVertex tmp;
+ int i, k;
+
+ /* initial constant vertex fields */
+ tmp.v.z = 1.0;
+ tmp.v.w = 1.0;
+ tmp.v.color.red = red;
+ tmp.v.color.green = green;
+ tmp.v.color.blue = blue;
+ tmp.v.color.alpha = alpha;
+ tmp.v.specular.red = 0;
+ tmp.v.specular.green = 0;
+ tmp.v.specular.blue = 0;
+ tmp.v.specular.alpha = 0;
+
+ for (k = 0; k < numVerts; k++) {
+ tmp.v.x = verts[k][0];
+ tmp.v.y = verts[k][1];
+ tmp.v.u0 = texcoords[k][0];
+ tmp.v.v0 = texcoords[k][1];
+
+ for (i = 0 ; i < vertex_size ; i++)
+ vb[i] = tmp.ui[i];
+
+ vb += vertex_size;
+ }
+}
+
+
void
i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
LOCK_HARDWARE(intel);
- if(!all) {
+ if (!all) {
x0 = cx;
y0 = cy;
x1 = x0 + cw;
if (mask & BUFFER_BIT_FRONT_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
- set_draw_offset( i915, screen->front.offset );
+ set_draw_region( i915, &screen->front );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
if (mask & BUFFER_BIT_BACK_LEFT) {
set_no_depth_stencil_write( i915 );
set_color_mask( i915, GL_TRUE );
- set_draw_offset( i915, screen->back.offset );
+ set_draw_region( i915, &screen->back );
draw_quad(i915, x0, x1, y0, y1,
intel->clear_red, intel->clear_green,
intel->ctx.Stencil.Clear);
set_color_mask( i915, GL_FALSE );
- set_draw_offset( i915, screen->front.offset ); /* could be either? */
+ set_draw_region( i915, &screen->front ); /* could be either? */
draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
}
}
+/**
+ * Copy the window contents named by dPriv to the rotated (or reflected)
+ * color buffer.
+ * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
+ */
+void
+i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+ GLuint srcBuf)
+{
+ i915ContextPtr i915 = I915_CONTEXT( intel );
+ intelScreenPrivate *screen = intel->intelScreen;
+ const GLuint cpp = screen->cpp;
+ drm_clip_rect_t fullRect;
+ GLuint textureFormat, srcOffset, srcPitch;
+ const drm_clip_rect_t *clipRects;
+ int numClipRects;
+ int i;
+
+ int xOrig, yOrig;
+ int origNumClipRects;
+ drm_clip_rect_t *origRects;
+
+ /*
+ * set up hardware state
+ */
+ intelFlush( &intel->ctx );
+
+ SET_STATE( i915, meta );
+ set_initial_state( i915 );
+ set_no_texture( i915 );
+ set_vertex_format( i915 );
+ set_no_depth_stencil_write( i915 );
+ set_color_mask( i915, GL_TRUE );
+
+ LOCK_HARDWARE(intel);
+
+ /* save current drawing origin and cliprects (restored at end) */
+ xOrig = intel->drawX;
+ yOrig = intel->drawY;
+ origNumClipRects = intel->numClipRects;
+ origRects = intel->pClipRects;
+
+ if (!intel->numClipRects)
+ goto done;
+
+ /*
+ * set drawing origin, cliprects for full-screen access to rotated screen
+ */
+ fullRect.x1 = 0;
+ fullRect.y1 = 0;
+ fullRect.x2 = screen->rotatedWidth;
+ fullRect.y2 = screen->rotatedHeight;
+ intel->drawX = 0;
+ intel->drawY = 0;
+ intel->numClipRects = 1;
+ intel->pClipRects = &fullRect;
+
+ set_draw_region( i915, &screen->rotated );
+
+ if (cpp == 4)
+ textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ else
+ textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
+
+ if (srcBuf == BUFFER_BIT_FRONT_LEFT) {
+ srcPitch = screen->front.pitch; /* in bytes */
+ srcOffset = screen->front.offset; /* bytes */
+ clipRects = dPriv->pClipRects;
+ numClipRects = dPriv->numClipRects;
+ }
+ else {
+ srcPitch = screen->back.pitch; /* in bytes */
+ srcOffset = screen->back.offset; /* bytes */
+ clipRects = dPriv->pBackClipRects;
+ numClipRects = dPriv->numBackClipRects;
+ }
+
+ /* set the whole screen up as a texture to avoid alignment issues */
+ set_tex_rect_source(i915,
+ srcOffset,
+ screen->width,
+ screen->height,
+ srcPitch,
+ textureFormat);
+
+ enable_texture_blend_replace(i915);
+
+ /*
+ * loop over the source window's cliprects
+ */
+ for (i = 0; i < numClipRects; i++) {
+ int srcX0 = clipRects[i].x1;
+ int srcY0 = clipRects[i].y1;
+ int srcX1 = clipRects[i].x2;
+ int srcY1 = clipRects[i].y2;
+ GLfloat verts[4][2], tex[4][2];
+ int j;
+
+ /* build vertices for four corners of clip rect */
+ verts[0][0] = srcX0; verts[0][1] = srcY0;
+ verts[1][0] = srcX1; verts[1][1] = srcY0;
+ verts[2][0] = srcX1; verts[2][1] = srcY1;
+ verts[3][0] = srcX0; verts[3][1] = srcY1;
+
+ /* .. and texcoords */
+ tex[0][0] = srcX0; tex[0][1] = srcY0;
+ tex[1][0] = srcX1; tex[1][1] = srcY0;
+ tex[2][0] = srcX1; tex[2][1] = srcY1;
+ tex[3][0] = srcX0; tex[3][1] = srcY1;
+
+ /* transform coords to rotated screen coords */
+ for (j = 0; j < 4; j++) {
+ matrix23TransformCoordf(&screen->rotMatrix,
+ &verts[j][0], &verts[j][1]);
+ }
+
+ /* draw polygon to map source image to dest region */
+ draw_poly(i915, 255, 255, 255, 255, 4, verts, tex);
+
+ } /* cliprect loop */
+
+ intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE );
+
+ done:
+ /* restore original drawing origin and cliprects */
+ intel->drawX = xOrig;
+ intel->drawY = yOrig;
+ intel->numClipRects = origNumClipRects;
+ intel->pClipRects = origRects;
+
+ UNLOCK_HARDWARE(intel);
+
+ SET_STATE( i915, state );
+}
+
#define MS4_MAX_LOD_SHIFT 9
#define MS4_MAX_LOD_MASK (0x3f<<9)
#define MS4_MIP_LAYOUT_LEGACY (0<<8)
+#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8)
+#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8)
#define MS4_VOLUME_DEPTH_SHIFT 0
#define MS4_VOLUME_DEPTH_MASK (0xff<<0)
}
break;
+ case GL_POLYGON_SMOOTH:
+ FALLBACK( &i915->intel, I915_FALLBACK_POLYGON_SMOOTH, state );
+ break;
+
+ case GL_POINT_SMOOTH:
+ FALLBACK( &i915->intel, I915_FALLBACK_POINT_SMOOTH, state );
+ break;
+
default:
;
}
{
I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
+ /* color buffer offset/stride */
i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
(BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
+ BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
+ /*i915->state.Buffer[I915_DESTREG_CBUFADDR2] is the offset */
+ /* depth/Z buffer offset/stride */
i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
(BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
+ BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */
BUF_3D_USE_FENCE);
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset;
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
+ /* color/depth pixel format */
switch (screen->fbFormat) {
case DV_PF_555:
case DV_PF_565:
DEPTH_FRMT_24_FIXED_8_OTHER);
break;
}
+
+ /* scissor */
i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
DISABLE_SCISSOR_RECT);
i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
static void i915BindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj )
{
- i915TextureObjectPtr tex = (i915TextureObjectPtr)texObj->DriverData;
+ i915TextureObjectPtr tex;
+
+ if (!texObj->DriverData)
+ i915AllocTexObj( texObj );
+
+ tex = (i915TextureObjectPtr)texObj->DriverData;
if (tex->lastTarget != texObj->Target) {
tex->intel.dirty = I915_UPLOAD_TEX_ALL;
}
- if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G)
+ if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G ||
+ i915->intel.intelScreen->deviceID == PCI_CHIP_I945_GM)
i945LayoutTextureImages( i915, tObj );
else
i915LayoutTextureImages( i915, tObj );
ADVANCE_BATCH(); \
} while (0);
+static GLuint get_dirty( struct i915_hw_state *state )
+{
+ GLuint dirty;
+
+ /* Workaround the multitex hang - if one texture unit state is
+ * modified, emit all texture units.
+ */
+ dirty = state->active & ~state->emitted;
+ if (dirty & I915_UPLOAD_TEX_ALL)
+ state->emitted &= ~I915_UPLOAD_TEX_ALL;
+ dirty = state->active & ~state->emitted;
+
+ return dirty;
+}
+
+
+static GLuint get_state_size( struct i915_hw_state *state )
+{
+ GLuint dirty = get_dirty(state);
+ GLuint i;
+ GLuint sz = 0;
+
+ if (dirty & I915_UPLOAD_CTX)
+ sz += sizeof(state->Ctx);
+
+ if (dirty & I915_UPLOAD_BUFFERS)
+ sz += sizeof(state->Buffer);
+
+ if (dirty & I915_UPLOAD_STIPPLE)
+ sz += sizeof(state->Stipple);
+
+ if (dirty & I915_UPLOAD_FOG)
+ sz += sizeof(state->Fog);
+
+ if (dirty & I915_UPLOAD_TEX_ALL) {
+ int nr = 0;
+ for (i = 0; i < I915_TEX_UNITS; i++)
+ if (dirty & I915_UPLOAD_TEX(i))
+ nr++;
+
+ sz += (2+nr*3) * sizeof(GLuint) * 2;
+ }
+
+ if (dirty & I915_UPLOAD_CONSTANTS)
+ sz += state->ConstantSize * sizeof(GLuint);
+
+ if (dirty & I915_UPLOAD_PROGRAM)
+ sz += state->ProgramSize * sizeof(GLuint);
+
+ return sz;
+}
+
/* Push the state into the sarea and/or texture memory.
*/
i915ContextPtr i915 = I915_CONTEXT(intel);
struct i915_hw_state *state = i915->current;
int i;
- GLuint dirty;
+ GLuint dirty = get_dirty(state);
+ GLuint counter = intel->batch.counter;
BATCH_LOCALS;
- /* More to workaround the multitex hang - if one texture unit state
- * is modified, emit all texture units.
- */
- dirty = state->active & ~state->emitted;
- if (dirty & I915_UPLOAD_TEX_ALL)
- state->emitted &= ~I915_UPLOAD_TEX_ALL;
- dirty = state->active & ~state->emitted;
-
+ if (intel->batch.space < get_state_size(state)) {
+ intelFlushBatch(intel, GL_TRUE);
+ dirty = get_dirty(state);
+ counter = intel->batch.counter;
+ }
if (VERBOSE)
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
}
state->emitted |= dirty;
+ intel->batch.last_emit_state = counter;
+ assert(counter == intel->batch.counter);
}
static void i915_destroy_context( intelContextPtr intel )
_tnl_free_vertices(&intel->ctx);
}
-static void i915_set_draw_offset( intelContextPtr intel, int offset )
+
+/**
+ * Set the color buffer drawing region.
+ */
+static void
+i915_set_color_region( intelContextPtr intel, const intelRegion *region)
+{
+ i915ContextPtr i915 = I915_CONTEXT(intel);
+ I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
+ i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i915->state.Buffer[I915_DESTREG_CBUFADDR2] = region->offset;
+}
+
+
+/**
+ * specify the z-buffer/stencil region
+ */
+static void
+i915_set_z_region( intelContextPtr intel, const intelRegion *region)
{
i915ContextPtr i915 = I915_CONTEXT(intel);
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
- i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset;
+ i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
+ (BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE);
+ i915->state.Buffer[I915_DESTREG_DBUFADDR2] = region->offset;
+}
+
+
+/**
+ * Set both the color and Z/stencil drawing regions.
+ * Similar to two previous functions, but don't use I915_STATECHANGE()
+ */
+static void
+i915_update_color_z_regions(intelContextPtr intel,
+ const intelRegion *colorRegion,
+ const intelRegion *depthRegion)
+{
+ i915ContextPtr i915 = I915_CONTEXT(intel);
+
+ i915->state.Buffer[I915_DESTREG_CBUFADDR1] =
+ (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | BUF_3D_USE_FENCE);
+ i915->state.Buffer[I915_DESTREG_CBUFADDR2] = colorRegion->offset;
+
+ i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
+ (BUF_3D_ID_DEPTH |
+ BUF_3D_PITCH(depthRegion->pitch) | /* pitch in bytes */
+ BUF_3D_USE_FENCE);
+ i915->state.Buffer[I915_DESTREG_DBUFADDR2] = depthRegion->offset;
}
+
static void i915_lost_hardware( intelContextPtr intel )
{
I915_CONTEXT(intel)->state.emitted = 0;
i915->intel.vtbl.alloc_tex_obj = i915AllocTexObj;
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
i915->intel.vtbl.clear_with_tris = i915ClearWithTris;
+ i915->intel.vtbl.rotate_window = i915RotateWindow;
i915->intel.vtbl.destroy = i915_destroy_context;
i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state;
i915->intel.vtbl.emit_state = i915_emit_state;
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state;
i915->intel.vtbl.render_start = i915_render_start;
- i915->intel.vtbl.set_draw_offset = i915_set_draw_offset;
+ i915->intel.vtbl.set_color_region = i915_set_color_region;
+ i915->intel.vtbl.set_z_region = i915_set_z_region;
+ i915->intel.vtbl.update_color_z_regions = i915_update_color_z_regions;
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
i915->intel.vtbl.emit_flush = i915_emit_flush;
}
GLshort w, GLshort h,
GLubyte r, GLubyte g, GLubyte b )
{
- intelEmitFillBlitLocked( intel,
- intel->intelScreen->cpp,
- intel->intelScreen->back.pitch,
- intel->intelScreen->front.offset,
- x, y, w, h,
- INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
- r,g,b,0xff));
+ x += intel->drawX;
+ y += intel->drawY;
+
+ if (x >= 0 && y >= 0 &&
+ x+w < intel->intelScreen->width &&
+ y+h < intel->intelScreen->height)
+ intelEmitFillBlitLocked( intel,
+ intel->intelScreen->cpp,
+ intel->intelScreen->back.pitch,
+ intel->intelScreen->back.offset,
+ x, y, w, h,
+ INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
+ r,g,b,0xff));
}
static void intel_draw_performance_boxes( intelContextPtr intel )
/* Make sure there is some space in this buffer:
*/
- if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space)
+ if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) {
intelFlushBatch(intel, GL_TRUE);
-
+ intel->vtbl.emit_state( intel );
+ }
#if 1
if (((int)intel->batch.ptr) & 0x4) {
intel->prim.start_ptr = batch_ptr;
intel->prim.primitive = prim;
intel->prim.flush = intel_flush_inline_primitive;
+ intel->batch.contains_geometry = 1;
OUT_BATCH( 0 );
ADVANCE_BATCH();
*/
intel->vtbl.emit_state( intel );
+ if ((1+dwords)*4 >= intel->batch.space) {
+ intelFlushBatch(intel, GL_TRUE);
+ intel->vtbl.emit_state( intel );
+ }
+
if (1) {
int used = dwords * 4;
ADVANCE_BATCH();
+ intel->batch.contains_geometry = 1;
+
do_discard:
return tmp;
}
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
{
- intelScreenPrivate *intelScreen = intel->intelScreen;
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
- int nbox = dPriv->numClipRects;
- drm_clip_rect_t *pbox = dPriv->pClipRects;
- int pitch = intelScreen->front.pitch;
- int cpp = intelScreen->cpp;
+ const intelScreenPrivate *intelScreen = intel->intelScreen;
+ const __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ const int nbox = dPriv->numClipRects;
+ const drm_clip_rect_t *pbox = dPriv->pClipRects;
+ const int cpp = intelScreen->cpp;
+ const int pitch = intelScreen->front.pitch; /* in bytes */
int i;
GLuint CMD, BR13;
BATCH_LOCALS;
switch(cpp) {
case 2:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+ BR13 = (pitch) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
+ BR13 = (pitch) | (0xCC << 16) | (1<<24) | (1<<25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
- BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+ BR13 = (pitch) | (0xCC << 16) | (1<<24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
}
-
- if (0)
+
+ if (0)
intel_draw_performance_boxes( intel );
for (i = 0 ; i < nbox; i++, pbox++)
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->width ||
- pbox->y2 > intelScreen->height)
+ pbox->y2 > intelScreen->height) {
+ _mesa_warning(&intel->ctx, "Bad cliprect in intelCopyBuffer()");
continue;
-
+ }
+
BEGIN_BATCH( 8);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint cpp,
- GLshort dst_pitch,
+ GLshort dst_pitch, /* in bytes */
GLuint dst_offset,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint BR13, CMD;
BATCH_LOCALS;
- dst_pitch *= cpp;
-
switch(cpp) {
case 1:
case 2:
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cx, cy;
- GLint pitch = intelScreen->front.pitch;
+ GLint pitch;
GLint cpp = intelScreen->cpp;
GLint i;
GLuint BR13, CMD, D_CMD;
BATCH_LOCALS;
-
+ intelFlush( &intel->ctx );
+ LOCK_HARDWARE( intel );
+
+ pitch = intelScreen->front.pitch;
+
clear_color = intel->ClearColor;
clear_depth = 0;
switch(cpp) {
case 2:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+ BR13 = (0xF0 << 16) | (pitch) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
case 4:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
+ BR13 = (0xF0 << 16) | (pitch) | (1<<24) | (1<<25);
CMD = (XY_COLOR_BLT_CMD |
XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
break;
default:
- BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+ BR13 = (0xF0 << 16) | (pitch) | (1<<24);
D_CMD = CMD = XY_COLOR_BLT_CMD;
break;
}
- intelFlush( &intel->ctx );
- LOCK_HARDWARE( intel );
{
/* flip top to bottom */
cy = intel->driDrawable->h-cy1-ch;
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
- if (intel->alloc.ptr) {
+ if (intel->alloc.offset) {
intelFreeAGP( intel, intel->alloc.ptr );
- intel->alloc.ptr = 0;
+ intel->alloc.ptr = NULL;
+ intel->alloc.offset = 0;
+ }
+ else if (intel->alloc.ptr) {
+ free(intel->alloc.ptr);
+ intel->alloc.ptr = NULL;
}
+
+ memset(&intel->batch, 0, sizeof(intel->batch));
}
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
- if (!intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
- intel->alloc.size = 8 * 1024;
- intel->alloc.ptr = malloc( intel->alloc.size );
- intel->alloc.offset = 0;
- }
- else {
+ /* This path isn't really safe with rotate:
+ */
+ if (getenv("INTEL_BATCH") && intel->intelScreen->allow_batchbuffer) {
switch (intel->intelScreen->deviceID) {
case PCI_CHIP_I865_G:
/* HW bug? Seems to crash if batchbuffer crosses 4k boundary.
break;
}
+ /* KW: temporary - this make crashes & lockups more frequent, so
+ * leave in until they are solved.
+ */
+ intel->alloc.size = 8 * 1024;
+
intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
if (intel->alloc.ptr)
intel->alloc.offset =
intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
+ else
+ intel->alloc.offset = 0; /* OK? */
}
+ /* The default is now to use a local buffer and pass that to the
+ * kernel. This is also a fallback if allocation fails on the
+ * above path:
+ */
if (!intel->alloc.ptr) {
- FALLBACK(intel, INTEL_FALLBACK_NO_BATCHBUFFER, 1);
+ intel->alloc.size = 8 * 1024;
+ intel->alloc.ptr = malloc( intel->alloc.size );
+ intel->alloc.offset = 0;
}
- else {
- intel->prim.flush = 0;
- intel->vtbl.emit_invarient_state( intel );
- /* Make sure this gets to the hardware, even if we have no cliprects:
- */
- LOCK_HARDWARE( intel );
- intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
- UNLOCK_HARDWARE( intel );
- }
+ assert(intel->alloc.ptr);
}
(n), __FUNCTION__, intel->batch.space/4); \
if (intel->batch.space < (n)*4) \
intelFlushBatch(intel, GL_TRUE); \
+ if (intel->batch.space == intel->batch.size) intel->batch.func = __FUNCTION__; \
batch_ptr = intel->batch.ptr; \
} while (0)
chipset = "Intel(R) 915GM"; break;
case PCI_CHIP_I945_G:
chipset = "Intel(R) 945G"; break;
+ case PCI_CHIP_I945_GM:
+ chipset = "Intel(R) 945GM"; break;
default:
chipset = "Unknown Intel Chipset"; break;
}
{
_mesa_init_driver_functions( functions );
- functions->Flush = intelFlush;
functions->Clear = intelClear;
+ functions->Flush = intelglFlush;
functions->Finish = intelFinish;
functions->GetBufferSize = intelBufferSize;
functions->ResizeBuffers = _mesa_resize_framebuffer;
intelInitStateFuncs( functions );
}
+static void intel_emit_invarient_state( GLcontext *ctx )
+{
+ intelContextPtr intel = INTEL_CONTEXT(ctx);
+
+ intel->vtbl.emit_invarient_state( intel );
+ intel->prim.flush = 0;
+
+ /* Make sure this gets to the hardware, even if we have no cliprects:
+ */
+ LOCK_HARDWARE( intel );
+ intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
+ UNLOCK_HARDWARE( intel );
+}
+
GLboolean intelInitContext( intelContextPtr intel,
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
- intel->prim.flush = intelInitBatchBuffer;
+ intelInitBatchBuffer(&intel->ctx);
+ intel->prim.flush = intel_emit_invarient_state;
intel->prim.primitive = ~0;
return GL_TRUE;
}
+/**
+ * Use the information in the sarea to update the screen parameters
+ * related to screen rotation.
+ */
+static void
+intelUpdateScreenRotation(intelContextPtr intel,
+ __DRIscreenPrivate *sPriv,
+ drmI830Sarea *sarea)
+{
+ intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
+ intelRegion *colorBuf;
+
+ intelUnmapScreenRegions(intelScreen);
+
+ intelUpdateScreenFromSAREA(intelScreen, sarea);
+
+ /* update the current hw offsets for the color and depth buffers */
+ if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
+ colorBuf = &intelScreen->back;
+ else
+ colorBuf = &intelScreen->front;
+ intel->vtbl.update_color_z_regions(intel, colorBuf, &intelScreen->depth);
+
+ if (!intelMapScreenRegions(sPriv)) {
+ fprintf(stderr, "ERROR Remapping screen regions!!!\n");
+ }
+}
+
void intelGetLock( intelContextPtr intel, GLuint flags )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
__DRIscreenPrivate *sPriv = intel->driScreen;
+ intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
drmI830Sarea * sarea = intel->sarea;
- int me = intel->hHWContext;
unsigned i;
drmGetLock(intel->driFd, intel->hHWContext, flags);
if (dPriv)
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+ if (dPriv && intel->lastStamp != dPriv->lastStamp) {
+ intelWindowMoved( intel );
+ intel->lastStamp = dPriv->lastStamp;
+ }
+
/* If we lost context, need to dump all registers to hardware.
* Note that we don't care about 2d contexts, even if they perform
* accelerated commands, so the DRI locking in the X server is even
* more broken than usual.
*/
- if (sarea->ctxOwner != me) {
- intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
- sarea->ctxOwner = me;
+ if (sarea->width != intelScreen->width ||
+ sarea->height != intelScreen->height ||
+ sarea->rotation != intelScreen->current_rotation) {
+ intelUpdateScreenRotation(intel, sPriv, sarea);
+
+ /* This will drop the outstanding batchbuffer on the floor */
+ intel->batch.ptr -= (intel->batch.size - intel->batch.space);
+ intel->batch.space = intel->batch.size;
+ /* lose all primitives */
+ intel->prim.primitive = ~0;
+ intel->prim.start_ptr = 0;
+ intel->prim.flush = 0;
+ intel->vtbl.lost_hardware( intel );
+
+ intel->lastStamp = 0; /* force window update */
+
+ /* Release batch buffer
+ */
+ intelDestroyBatchBuffer(&intel->ctx);
+ intelInitBatchBuffer(&intel->ctx);
+ intel->prim.flush = intel_emit_invarient_state;
+
+ /* Still need to reset the global LRU?
+ */
+ intel_driReinitTextureHeap( intel->texture_heaps[0], intel->intelScreen->tex.size );
}
/* Shared texture managment - if another client has played with
* texture space, figure out which if any of our textures have been
* ejected, and update our global LRU.
*/
-
for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
}
-
- if (dPriv && intel->lastStamp != dPriv->lastStamp) {
- intelWindowMoved( intel );
- intel->lastStamp = dPriv->lastStamp;
- }
}
+
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
+ intelScreenPrivate *screen = intel->intelScreen;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv );
}
+ if (screen->current_rotation != 0) {
+ intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
+ }
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
void (*update_texture_state)( intelContextPtr intel );
void (*render_start)( intelContextPtr intel );
- void (*set_draw_offset)( intelContextPtr intel, int offset );
+ void (*set_color_region)( intelContextPtr intel, const intelRegion *reg );
+ void (*set_z_region)( intelContextPtr intel, const intelRegion *reg );
+ void (*update_color_z_regions)(intelContextPtr intel,
+ const intelRegion *colorRegion,
+ const intelRegion *depthRegion);
void (*emit_flush)( intelContextPtr intel );
-
void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim );
GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected );
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch);
+ void (*rotate_window)( intelContextPtr intel,
+ __DRIdrawablePrivate *dPriv, GLuint srcBuf);
+
intelTextureObjectPtr (*alloc_tex_obj)( struct gl_texture_object *tObj );
} vtbl;
GLint size;
GLint space;
GLubyte *ptr;
+ GLuint counter;
+ GLuint last_emit_state;
+ GLboolean contains_geometry;
+ const char *func;
+ GLuint last_swap;
} batch;
struct {
intel_line_func draw_line;
intel_tri_func draw_tri;
- /* These refer to the current draw (front vs. back) buffer:
+ /* Drawing buffer state
*/
- GLuint drawOffset; /* agp offset of drawbuffer */
+ intelRegion *drawRegion; /* current drawing buffer */
+ intelRegion *readRegion; /* current reading buffer */
+
int drawX; /* origin of drawable in draw buffer */
int drawY;
GLuint numClipRects; /* cliprects for that buffer */
#define PCI_CHIP_I915_G 0x2582
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
+#define PCI_CHIP_I945_GM 0x27A2
/* ================================================================
static int intelEmitIrqLocked( intelContextPtr intel )
{
drmI830IrqEmit ie;
- int ret, seq = 0;
+ int ret, seq;
assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) ==
(DRM_LOCK_HELD|intel->hHWContext));
fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf);
intel->batch.start_offset = intel->alloc.offset + buf * half;
- intel->batch.ptr = (GLubyte *)intel->alloc.ptr + buf * half;
+ intel->batch.ptr = (char *)intel->alloc.ptr + buf * half;
intel->batch.size = half - 8;
intel->batch.space = half - 8;
assert(intel->batch.space >= 0);
assert(intel->locked);
if (0)
- fprintf(stderr, "%s used %d of %d offset %x..%x refill %d\n",
+ fprintf(stderr, "%s used %d of %d offset %x..%x refill %d (started in %s)\n",
__FUNCTION__,
(intel->batch.size - intel->batch.space),
intel->batch.size,
intel->batch.start_offset,
intel->batch.start_offset +
(intel->batch.size - intel->batch.space),
- refill);
+ refill,
+ intel->batch.func);
/* Throw away non-effective packets. Won't work once we have
* hardware contexts which would preserve statechanges beyond a
}
if (intel->batch.space != intel->batch.size) {
+
+ if (intel->sarea->ctxOwner != intel->hHWContext) {
+ intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
+ intel->sarea->ctxOwner = intel->hHWContext;
+ }
+
batch.start = intel->batch.start_offset;
batch.used = intel->batch.size - intel->batch.space;
batch.cliprects = intel->pClipRects;
(int *)(intel->batch.ptr - batch.used),
batch.used );
- if (0)
- fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
- __FUNCTION__,
- batch.start,
- batch.start + batch.used,
- batch.DR4, batch.num_cliprects);
-
intel->batch.start_offset += batch.used;
intel->batch.size -= batch.used;
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
+ if (intel->batch.contains_geometry)
+ assert(intel->batch.last_emit_state == intel->batch.counter);
+
+ intel->batch.counter++;
+ intel->batch.contains_geometry = 0;
+ intel->batch.func = 0;
intel->vtbl.lost_hardware( intel );
}
}
-
-
-
-
-
void intelWaitForIdle( intelContextPtr intel )
{
if (0)
}
+/**
+ * Check if we need to rotate/warp the front color buffer to the
+ * rotated screen. We generally need to do this when we get a glFlush
+ * or glFinish after drawing to the front color buffer.
+ */
+static void
+intelCheckFrontRotate(GLcontext *ctx)
+{
+ intelContextPtr intel = INTEL_CONTEXT( ctx );
+ if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
+ intelScreenPrivate *screen = intel->intelScreen;
+ if (screen->current_rotation != 0) {
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
+ }
+ }
+}
+
+/**
+ * NOT directly called via glFlush.
+ */
void intelFlush( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelFlushBatch( intel, GL_FALSE );
}
+
+/**
+ * Called via glFlush.
+ */
+void intelglFlush( GLcontext *ctx )
+{
+ intelFlush(ctx);
+ intelCheckFrontRotate(ctx);
+}
+
+
void intelFinish( GLcontext *ctx )
{
intelContextPtr intel = INTEL_CONTEXT( ctx );
intelFlush( ctx );
intelWaitForIdle( intel );
+ intelCheckFrontRotate(ctx);
}
}
+void
+intelRotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+ GLuint srcBuffer)
+{
+ if (intel->vtbl.rotate_window) {
+ intel->vtbl.rotate_window(intel, dPriv, srcBuffer);
+ }
+}
+
void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
{
- int region_offset = 0;
+ int region_offset;
drmI830MemAlloc alloc;
int ret;
GLint cx, GLint cy, GLint cw, GLint ch);
extern void intelPageFlip( const __DRIdrawablePrivate *dpriv );
+
+extern void intelRotateWindow(intelContextPtr intel,
+ __DRIdrawablePrivate *dPriv, GLuint srcBuffer);
+
extern void intelWaitForIdle( intelContextPtr intel );
extern void intelFlushBatch( intelContextPtr intel, GLboolean refill );
extern void intelFlushBatchLocked( intelContextPtr intel,
extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock );
extern void intelFinish( GLcontext *ctx );
extern void intelFlush( GLcontext *ctx );
+extern void intelglFlush( GLcontext *ctx );
extern void *intelAllocateAGP( intelContextPtr intel, GLsizei size );
extern void intelFreeAGP( intelContextPtr intel, void *pointer );
}
-
+/**
+ * Clip the given rectangle against the buffer's bounds (including scissor).
+ * \param size returns the
+ * \return GL_TRUE if any pixels remain, GL_FALSE if totally clipped.
+ *
+ * XXX Replace this with _mesa_clip_drawpixels() and _mesa_clip_readpixels()
+ * from Mesa 6.4. We shouldn't apply scissor for ReadPixels.
+ */
static GLboolean
clip_pixelrect( const GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
- GLsizei *width, GLsizei *height,
- GLint *size )
+ GLsizei *width, GLsizei *height)
{
- intelContextPtr intel = INTEL_CONTEXT(ctx);
-
/* left clipping */
if (*x < buffer->_Xmin) {
*width -= (buffer->_Xmin - *x);
if (*height <= 0)
return GL_FALSE;
- *size = ((*y + *height - 1) * intel->intelScreen->front.pitch +
- (*x + *width - 1) * intel->intelScreen->cpp);
+ return GL_TRUE;
+}
+
+/**
+ * Compute intersection of a clipping rectangle and pixel rectangle,
+ * returning results in x/y/w/hOut vars.
+ * \return GL_TRUE if there's intersection, GL_FALSE if disjoint.
+ */
+static INLINE GLboolean
+intersect_region(const drm_clip_rect_t *box,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint *xOut, GLint *yOut, GLint *wOut, GLint *hOut)
+{
+ GLint bx = box->x1;
+ GLint by = box->y1;
+ GLint bw = box->x2 - bx;
+ GLint bh = box->y2 - by;
+
+ if (bx < x) bw -= x - bx, bx = x;
+ if (by < y) bh -= y - by, by = y;
+ if (bx + bw > x + width) bw = x + width - bx;
+ if (by + bh > y + height) bh = y + height - by;
+ if (bw <= 0) return GL_FALSE;
+ if (bh <= 0) return GL_FALSE;
+
+ *xOut = bx;
+ *yOut = by;
+ *wOut = bw;
+ *hOut = bh;
return GL_TRUE;
}
+
+
static GLboolean
intelTryReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLvoid *pixels )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
- GLint size = 0;
+ GLint size = 0; /* not really used */
GLint pitch = pack->RowLength ? pack->RowLength : width;
if (INTEL_DEBUG & DEBUG_PIXEL)
/* Although the blits go on the command buffer, need to do this and
- * fire with lock held to guarentee cliprects and drawOffset are
+ * fire with lock held to guarentee cliprects and drawing offset are
* correct.
*
* This is an unusual situation however, as the code which flushes
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
- int src_offset = intel->drawOffset;
+ int src_offset = intel->readRegion->offset;
int src_pitch = intel->intelScreen->front.pitch;
int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
- if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height,
- &size)) {
+ assert(dst_offset != ~0); /* should have been caught above */
+
+ if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s totally clipped -- nothing to do\n",
return GL_TRUE;
}
-
+ /* convert to screen coords (y=0=top) */
y = dPriv->h - y - height;
x += dPriv->x;
y += dPriv->y;
-
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
src_pitch, pitch);
+ /* We don't really have to do window clipping for readpixels.
+ * The OpenGL spec says that pixels read from outside the
+ * visible window region (pixel ownership) have undefined value.
+ */
for (i = 0 ; i < nbox ; i++)
{
- GLint bx = box[i].x1;
- GLint by = box[i].y1;
- GLint bw = box[i].x2 - bx;
- GLint bh = box[i].y2 - by;
-
- if (bx < x) bw -= x - bx, bx = x;
- if (by < y) bh -= y - by, by = y;
- if (bx + bw > x + width) bw = x + width - bx;
- if (by + bh > y + height) bh = y + height - by;
- if (bw <= 0) continue;
- if (bh <= 0) continue;
-
- intelEmitCopyBlitLocked( intel,
- intel->intelScreen->cpp,
- src_pitch, src_offset,
- pitch, dst_offset,
- bx, by,
- bx - x, by - y,
- bw, bh );
+ GLint bx, by, bw, bh;
+ if (intersect_region(box+i, x, y, width, height,
+ &bx, &by, &bw, &bh)) {
+ intelEmitCopyBlitLocked( intel,
+ intel->intelScreen->cpp,
+ src_pitch, src_offset,
+ pitch, dst_offset,
+ bx, by,
+ bx - x, by - y,
+ bw, bh );
+ }
}
}
UNLOCK_HARDWARE( intel );
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack,
- pixels))
+ pixels))
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
pixels);
}
drm_clip_rect_t *box = dPriv->pClipRects;
int nbox = dPriv->numClipRects;
int i;
- int size;
int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
int src_pitch = pitch;
+ assert(src_offset != ~0); /* should be caught earlier */
+
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
y -= height; /* cope with pixel zoom */
if (!clip_pixelrect(ctx, ctx->DrawBuffer,
- &x, &y, &width, &height,
- &size)) {
+ &x, &y, &width, &height)) {
UNLOCK_HARDWARE( intel );
return;
}
x += dPriv->x;
y += dPriv->y;
-
for (i = 0 ; i < nbox ; i++ )
{
- GLint bx = box[i].x1;
- GLint by = box[i].y1;
- GLint bw = box[i].x2 - bx;
- GLint bh = box[i].y2 - by;
-
- if (bx < x) bw -= x - bx, bx = x;
- if (by < y) bh -= y - by, by = y;
- if (bx + bw > x + width) bw = x + width - bx;
- if (by + bh > y + height) bh = y + height - by;
- if (bw <= 0) continue;
- if (bh <= 0) continue;
-
- intelEmitCopyBlitLocked( intel,
- intel->intelScreen->cpp,
- src_pitch, src_offset,
- intel->intelScreen->front.pitch,
- intel->drawOffset,
- bx - x, by - y,
- bx, by,
- bw, bh );
+ GLint bx, by, bw, bh;
+ if (intersect_region(box + i, x, y, width, height,
+ &bx, &by, &bw, &bh)) {
+ intelEmitCopyBlitLocked( intel,
+ intel->intelScreen->cpp,
+ src_pitch, src_offset,
+ intel->intelScreen->front.pitch,
+ intel->drawRegion->offset,
+ bx - x, by - y,
+ bx, by,
+ bw, bh );
+ }
}
}
UNLOCK_HARDWARE( intel );
-
static GLboolean
intelTryDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
case GL_RGB:
case GL_RGBA:
case GL_BGRA:
- dest = intel->drawOffset;
+ dest = intel->drawRegion->offset;
/* Planemask doesn't have full support in blits.
*/
if ( intelIsAgpMemory(intel, pixels, size) )
{
- do_draw_pix( ctx, x, y, width, height, pitch, pixels,
- dest );
+ do_draw_pix( ctx, x, y, width, height, pitch, pixels, dest );
return GL_TRUE;
}
else if (0)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!intelTryDrawPixels( ctx, x, y, width, height, format, type,
- unpack, pixels ))
+ unpack, pixels ))
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
}
--- /dev/null
+
+/**
+ * Routines for simple 2D->2D transformations for rotated, flipped screens.
+ *
+ * XXX This code is not intel-specific. Move it into a common/utility
+ * someday.
+ */
+
+#include "intel_rotate.h"
+
+#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) )
+
+#define ABS(A) ( ((A) < 0) ? -(A) : (A) )
+
+
+void
+matrix23Set(struct matrix23 *m,
+ int m00, int m01, int m02,
+ int m10, int m11, int m12)
+{
+ m->m00 = m00; m->m01 = m01; m->m02 = m02;
+ m->m10 = m10; m->m11 = m11; m->m12 = m12;
+}
+
+
+/*
+ * Transform (x,y) coordinate by the given matrix.
+ */
+void
+matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y)
+{
+ const float x0 = *x;
+ const float y0 = *y;
+
+ *x = m->m00 * x0 + m->m01 * y0 + m->m02;
+ *y = m->m10 * x0 + m->m11 * y0 + m->m12;
+}
+
+
+void
+matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y)
+{
+ const int x0 = *x;
+ const int y0 = *y;
+
+ *x = m->m00 * x0 + m->m01 * y0 + m->m02;
+ *y = m->m10 * x0 + m->m11 * y0 + m->m12;
+}
+
+
+/*
+ * Transform a width and height by the given matrix.
+ * XXX this could be optimized quite a bit.
+ */
+void
+matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist)
+{
+ int x0 = 0, y0 = 0;
+ int x1 = *xDist, y1 = 0;
+ int x2 = 0, y2 = *yDist;
+ matrix23TransformCoordi(m, &x0, &y0);
+ matrix23TransformCoordi(m, &x1, &y1);
+ matrix23TransformCoordi(m, &x2, &y2);
+
+ *xDist = (x1 - x0) + (x2 - x0);
+ *yDist = (y1 - y0) + (y2 - y0);
+
+ if (*xDist < 0)
+ *xDist = -*xDist;
+ if (*yDist < 0)
+ *yDist = -*yDist;
+}
+
+
+/**
+ * Transform the rect defined by (x, y, w, h) by m.
+ */
+void
+matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, int *h)
+{
+ int x0 = *x, y0 = *y;
+ int x1 = *x + *w, y1 = *y;
+ int x2 = *x + *w, y2 = *y + *h;
+ int x3 = *x, y3 = *y + *h;
+ matrix23TransformCoordi(m, &x0, &y0);
+ matrix23TransformCoordi(m, &x1, &y1);
+ matrix23TransformCoordi(m, &x2, &y2);
+ matrix23TransformCoordi(m, &x3, &y3);
+ *w = ABS(x1 - x0) + ABS(x2 - x1);
+ /**w = ABS(*w);*/
+ *h = ABS(y1 - y0) + ABS(y2 - y1);
+ /**h = ABS(*h);*/
+ *x = MIN2(x0, x1);
+ *x = MIN2(*x, x2);
+ *y = MIN2(y0, y1);
+ *y = MIN2(*y, y2);
+}
+
+
+/*
+ * Make rotation matrix for width X height screen.
+ */
+void
+matrix23Rotate(struct matrix23 *m, int width, int height, int angle)
+{
+ switch (angle) {
+ case 0:
+ matrix23Set(m, 1, 0, 0, 0, 1, 0);
+ break;
+ case 90:
+ matrix23Set(m, 0, 1, 0, -1, 0, width);
+ break;
+ case 180:
+ matrix23Set(m, -1, 0, width, 0, -1, height);
+ break;
+ case 270:
+ matrix23Set(m, 0, -1, height, 1, 0, 0);
+ break;
+ default:
+ /*abort()*/;
+ }
+}
+
+
+/*
+ * Make flip/reflection matrix for width X height screen.
+ */
+void
+matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip)
+{
+ if (xflip) {
+ m->m00 = -1; m->m01 = 0; m->m02 = width - 1;
+ }
+ else {
+ m->m00 = 1; m->m01 = 0; m->m02 = 0;
+ }
+ if (yflip) {
+ m->m10 = 0; m->m11 = -1; m->m12 = height - 1;
+ }
+ else {
+ m->m10 = 0; m->m11 = 1; m->m12 = 0;
+ }
+}
+
+
+/*
+ * result = a * b
+ */
+void
+matrix23Multiply(struct matrix23 *result,
+ const struct matrix23 *a, const struct matrix23 *b)
+{
+ result->m00 = a->m00 * b->m00 + a->m01 * b->m10;
+ result->m01 = a->m00 * b->m01 + a->m01 * b->m11;
+ result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02;
+
+ result->m10 = a->m10 * b->m00 + a->m11 * b->m10;
+ result->m11 = a->m10 * b->m01 + a->m11 * b->m11;
+ result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12;
+}
+
+
+#if 000
+
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ int width = 500, height = 400;
+ int rot;
+ int fx = 0, fy = 0; /* flip x and/or y ? */
+ int coords[4][2];
+
+ /* four corner coords to test with */
+ coords[0][0] = 0; coords[0][1] = 0;
+ coords[1][0] = width-1; coords[1][1] = 0;
+ coords[2][0] = width-1; coords[2][1] = height-1;
+ coords[3][0] = 0; coords[3][1] = height-1;
+
+
+ for (rot = 0; rot < 360; rot += 90) {
+ struct matrix23 rotate, flip, m;
+ int i;
+
+ printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy);
+
+ /* make transformation matrix 'm' */
+ matrix23Rotate(&rotate, width, height, rot);
+ matrix23Flip(&flip, width, height, fx, fy);
+ matrix23Multiply(&m, &rotate, &flip);
+
+ /* xform four coords */
+ for (i = 0; i < 4; i++) {
+ int x = coords[i][0];
+ int y = coords[i][1];
+ matrix23TransformCoordi(&m, &x, &y);
+ printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y);
+ }
+
+ /* xform width, height */
+ {
+ int x = width;
+ int y = height;
+ matrix23TransformDistance(&m, &x, &y);
+ printf(" %d x %d -> %d x %d\n", width, height, x, y);
+ }
+
+ /* xform rect */
+ {
+ int x = 50, y = 10, w = 200, h = 100;
+ matrix23TransformRect(&m, &x, &y, &w, &h);
+ printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100,
+ x, y, w, h);
+ }
+
+ }
+
+ return 0;
+}
+#endif
--- /dev/null
+#ifndef INTEL_ROTATE_H
+#define INTEL_ROTATE_H 1
+
+struct matrix23
+{
+ int m00, m01, m02;
+ int m10, m11, m12;
+};
+
+
+
+extern void
+matrix23Set(struct matrix23 *m,
+ int m00, int m01, int m02,
+ int m10, int m11, int m12);
+
+extern void
+matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y);
+
+extern void
+matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y);
+
+extern void
+matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist);
+
+extern void
+matrix23TransformRect(const struct matrix23 *m,
+ int *x, int *y, int *w, int *h);
+
+extern void
+matrix23Rotate(struct matrix23 *m, int width, int height, int angle);
+
+extern void
+matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip);
+
+extern void
+matrix23Multiply(struct matrix23 *result,
+ const struct matrix23 *a, const struct matrix23 *b);
+
+
+#endif /* INTEL_ROTATE_H */
#include "intel_tris.h"
#include "intel_ioctl.h"
-
-
#include "i830_dri.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
- DRI_CONF_SECTION_PERFORMANCE
- DRI_CONF_FORCE_S3TC_ENABLE(false)
- DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_PERFORMANCE
+ DRI_CONF_FORCE_S3TC_ENABLE(false)
+ DRI_CONF_SECTION_END
DRI_CONF_END;
const GLuint __driNConfigOptions = 1;
+#ifdef USE_NEW_INTERFACE
+static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
+#endif /*USE_NEW_INTERFACE*/
+
extern const struct dri_extension card_extensions[];
-static void intelPrintDRIInfo(intelScreenPrivate *intelScreen,
- __DRIscreenPrivate *sPriv,
- I830DRIPtr gDRIPriv)
+/**
+ * Map all the memory regions described by the screen.
+ * \return GL_TRUE if success, GL_FALSE if error.
+ */
+GLboolean
+intelMapScreenRegions(__DRIscreenPrivate *sPriv)
+{
+ intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
+
+ if (intelScreen->front.handle) {
+ if (drmMap(sPriv->fd,
+ intelScreen->front.handle,
+ intelScreen->front.size,
+ (drmAddress *)&intelScreen->front.map) != 0) {
+ _mesa_problem(NULL, "drmMap(frontbuffer) failed!");
+ return GL_FALSE;
+ }
+ }
+ else {
+ _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!");
+ }
+
+ if (drmMap(sPriv->fd,
+ intelScreen->back.handle,
+ intelScreen->back.size,
+ (drmAddress *)&intelScreen->back.map) != 0) {
+ intelUnmapScreenRegions(intelScreen);
+ return GL_FALSE;
+ }
+
+ if (drmMap(sPriv->fd,
+ intelScreen->depth.handle,
+ intelScreen->depth.size,
+ (drmAddress *)&intelScreen->depth.map) != 0) {
+ intelUnmapScreenRegions(intelScreen);
+ return GL_FALSE;
+ }
+
+ if (drmMap(sPriv->fd,
+ intelScreen->tex.handle,
+ intelScreen->tex.size,
+ (drmAddress *)&intelScreen->tex.map) != 0) {
+ intelUnmapScreenRegions(intelScreen);
+ return GL_FALSE;
+ }
+
+ if (0)
+ printf("Mappings: front: %p back: %p depth: %p tex: %p\n",
+ intelScreen->front.map,
+ intelScreen->back.map,
+ intelScreen->depth.map,
+ intelScreen->tex.map);
+ return GL_TRUE;
+}
+
+
+void
+intelUnmapScreenRegions(intelScreenPrivate *intelScreen)
+{
+#define REALLY_UNMAP 1
+ if (intelScreen->front.map) {
+#if REALLY_UNMAP
+ if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0)
+ printf("drmUnmap front failed!\n");
+#endif
+ intelScreen->front.map = NULL;
+ }
+ if (intelScreen->back.map) {
+#if REALLY_UNMAP
+ if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0)
+ printf("drmUnmap back failed!\n");
+#endif
+ intelScreen->back.map = NULL;
+ }
+ if (intelScreen->depth.map) {
+#if REALLY_UNMAP
+ drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
+ intelScreen->depth.map = NULL;
+#endif
+ }
+ if (intelScreen->tex.map) {
+#if REALLY_UNMAP
+ drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
+ intelScreen->tex.map = NULL;
+#endif
+ }
+}
+
+
+static void
+intelPrintDRIInfo(intelScreenPrivate *intelScreen,
+ __DRIscreenPrivate *sPriv,
+ I830DRIPtr gDRIPriv)
{
- fprintf(stderr, "Front size : 0x%x\n", sPriv->fbSize);
- fprintf(stderr, "Front offset : 0x%x\n", intelScreen->front.offset);
- fprintf(stderr, "Back size : 0x%x\n", intelScreen->back.size);
- fprintf(stderr, "Back offset : 0x%x\n", intelScreen->back.offset);
- fprintf(stderr, "Depth size : 0x%x\n", intelScreen->depth.size);
- fprintf(stderr, "Depth offset : 0x%x\n", intelScreen->depth.offset);
- fprintf(stderr, "Texture size : 0x%x\n", intelScreen->tex.size);
- fprintf(stderr, "Texture offset : 0x%x\n", intelScreen->tex.offset);
- fprintf(stderr, "Memory : 0x%x\n", gDRIPriv->mem);
+ fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
+ sPriv->fbSize, intelScreen->front.offset,
+ intelScreen->front.pitch);
+ fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n",
+ intelScreen->back.size, intelScreen->back.offset,
+ intelScreen->back.pitch);
+ fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n",
+ intelScreen->depth.size, intelScreen->depth.offset,
+ intelScreen->depth.pitch);
+ fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n",
+ intelScreen->rotated.size, intelScreen->rotated.offset,
+ intelScreen->rotated.pitch);
+ fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n",
+ intelScreen->tex.size, intelScreen->tex.offset);
+ fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
}
+
+static void
+intelPrintSAREA(const drmI830Sarea *sarea)
+{
+ fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, sarea->height);
+ fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
+ fprintf(stderr,
+ "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->front_offset, sarea->front_size,
+ (unsigned) sarea->front_handle);
+ fprintf(stderr,
+ "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->back_offset, sarea->back_size,
+ (unsigned) sarea->back_handle);
+ fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->depth_offset, sarea->depth_size,
+ (unsigned) sarea->depth_handle);
+ fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->tex_offset, sarea->tex_size,
+ (unsigned) sarea->tex_handle);
+ fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation);
+ fprintf(stderr,
+ "SAREA: rotated offset: 0x%08x size: 0x%x\n",
+ sarea->rotated_offset, sarea->rotated_size);
+ fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch);
+}
+
+
+/**
+ * A number of the screen parameters are obtained/computed from
+ * information in the SAREA. This function updates those parameters.
+ */
+void
+intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
+ drmI830Sarea *sarea)
+{
+ intelScreen->width = sarea->width;
+ intelScreen->height = sarea->height;
+
+ intelScreen->front.offset = sarea->front_offset;
+ intelScreen->front.pitch = sarea->pitch * intelScreen->cpp;
+ intelScreen->front.handle = sarea->front_handle;
+ intelScreen->front.size = sarea->front_size;
+
+ intelScreen->back.offset = sarea->back_offset;
+ intelScreen->back.pitch = sarea->pitch * intelScreen->cpp;
+ intelScreen->back.handle = sarea->back_handle;
+ intelScreen->back.size = sarea->back_size;
+
+ intelScreen->depth.offset = sarea->depth_offset;
+ intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp;
+ intelScreen->depth.handle = sarea->depth_handle;
+ intelScreen->depth.size = sarea->depth_size;
+
+ intelScreen->tex.offset = sarea->tex_offset;
+ intelScreen->logTextureGranularity = sarea->log_tex_granularity;
+ intelScreen->tex.handle = sarea->tex_handle;
+ intelScreen->tex.size = sarea->tex_size;
+
+ intelScreen->rotated.offset = sarea->rotated_offset;
+ intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp;
+ intelScreen->rotated.size = sarea->rotated_size;
+ intelScreen->current_rotation = sarea->rotation;
+ matrix23Rotate(&intelScreen->rotMatrix,
+ sarea->width, sarea->height, sarea->rotation);
+ intelScreen->rotatedWidth = sarea->virtualX;
+ intelScreen->rotatedHeight = sarea->virtualY;
+
+ if (0)
+ intelPrintSAREA(sarea);
+}
+
+
static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen;
I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv;
+ drmI830Sarea *sarea;
PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
(PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
void * const psc = sPriv->psc->screenConfigs;
intelScreen->driScrnPriv = sPriv;
sPriv->private = (void *)intelScreen;
+ intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
+ sarea = (drmI830Sarea *)
+ (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
intelScreen->deviceID = gDRIPriv->deviceID;
- intelScreen->width = gDRIPriv->width;
- intelScreen->height = gDRIPriv->height;
intelScreen->mem = gDRIPriv->mem;
intelScreen->cpp = gDRIPriv->cpp;
-
+
switch (gDRIPriv->bitsPerPixel) {
case 15: intelScreen->fbFormat = DV_PF_555; break;
case 16: intelScreen->fbFormat = DV_PF_565; break;
case 32: intelScreen->fbFormat = DV_PF_8888; break;
}
-
- intelScreen->front.pitch = gDRIPriv->fbStride;
- intelScreen->front.offset = gDRIPriv->fbOffset;
- intelScreen->front.map = sPriv->pFB;
-
- intelScreen->back.offset = gDRIPriv->backOffset;
- intelScreen->back.pitch = gDRIPriv->backPitch;
- intelScreen->back.handle = gDRIPriv->backbuffer;
- intelScreen->back.size = gDRIPriv->backbufferSize;
- if (drmMap(sPriv->fd,
- intelScreen->back.handle,
- intelScreen->back.size,
- (drmAddress *)&intelScreen->back.map) != 0) {
- fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n",
- __LINE__, __FUNCTION__, __FILE__);
- FREE(intelScreen);
- sPriv->private = NULL;
- return GL_FALSE;
- }
+ intelUpdateScreenFromSAREA(intelScreen, sarea);
- intelScreen->depth.offset = gDRIPriv->depthOffset;
- intelScreen->depth.pitch = gDRIPriv->depthPitch;
- intelScreen->depth.handle = gDRIPriv->depthbuffer;
- intelScreen->depth.size = gDRIPriv->depthbufferSize;
-
- if (drmMap(sPriv->fd,
- intelScreen->depth.handle,
- intelScreen->depth.size,
- (drmAddress *)&intelScreen->depth.map) != 0) {
- fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n",
- __LINE__, __FUNCTION__, __FILE__);
- FREE(intelScreen);
- drmUnmap(intelScreen->back.map, intelScreen->back.size);
- sPriv->private = NULL;
- return GL_FALSE;
- }
-
- intelScreen->tex.offset = gDRIPriv->textureOffset;
- intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity;
- intelScreen->tex.handle = gDRIPriv->textures;
- intelScreen->tex.size = gDRIPriv->textureSize;
+ if (0)
+ intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
- if (drmMap(sPriv->fd,
- intelScreen->tex.handle,
- intelScreen->tex.size,
- (drmAddress *)&intelScreen->tex.map) != 0) {
- fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n",
- __LINE__, __FUNCTION__, __FILE__);
- FREE(intelScreen);
- drmUnmap(intelScreen->back.map, intelScreen->back.size);
- drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
+ if (!intelMapScreenRegions(sPriv)) {
+ fprintf(stderr,"\nERROR! mapping regions\n");
+ _mesa_free(intelScreen);
sPriv->private = NULL;
return GL_FALSE;
}
-
- intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
-
- if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
intelScreen->drmMinor = sPriv->drmMinor;
+ /* Determine if IRQs are active? */
{
int ret;
drmI830GetParam gp;
}
}
+ /* Determine if batchbuffers are allowed */
{
int ret;
drmI830GetParam gp;
{
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
- /* Need to unmap all the bufs and maps here:
- */
- drmUnmap(intelScreen->back.map, intelScreen->back.size);
- drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
- drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
+ intelUnmapScreenRegions(intelScreen);
FREE(intelScreen);
sPriv->private = NULL;
}
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
+ case PCI_CHIP_I945_GM:
return i915CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
__DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 4, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
- static const __DRIversion drm_expected = { 1, 1, 0 };
+ static const __DRIversion drm_expected = { 1, 4, 0 };
dri_interface = interface;
#define _INTEL_INIT_H_
#include <sys/time.h>
-#include "dri_util.h"
#include "xmlconfig.h"
+#include "dri_util.h"
+#include "intel_rotate.h"
+#include "i830_common.h"
+
+/* This roughly corresponds to a gl_renderbuffer (Mesa 6.4) */
typedef struct {
drm_handle_t handle;
drmSize size; /* region size in bytes */
char *map; /* memory map */
int offset; /* from start of video mem, in bytes */
- int pitch; /* row stride, in pixels */
+ int pitch; /* row stride, in bytes */
} intelRegion;
typedef struct
{
intelRegion front;
intelRegion back;
+ intelRegion rotated;
intelRegion depth;
intelRegion tex;
int width;
int height;
int mem; /* unused */
-
+
int cpp; /* for front and back buffers */
- int bitsPerPixel; /* unused */
int fbFormat;
int logTextureGranularity;
int irq_active;
int allow_batchbuffer;
+ struct matrix23 rotMatrix;
+
+ int current_rotation; /* 0, 90, 180 or 270 */
+ int rotatedWidth, rotatedHeight;
+
/**
- * Configuration cache with default values for all contexts
- */
+ * Configuration cache with default values for all contexts
+ */
driOptionCache optionCache;
} intelScreenPrivate;
+extern GLboolean
+intelMapScreenRegions(__DRIscreenPrivate *sPriv);
+
+extern void
+intelUnmapScreenRegions(intelScreenPrivate *intelScreen);
+
+extern void
+intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
+ drmI830Sarea *sarea);
+
extern void
intelDestroyContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
- __DRIdrawablePrivate *driDrawPriv,
- __DRIdrawablePrivate *driReadPriv);
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv);
extern void
-intelSwapBuffers( __DRIdrawablePrivate *dPriv);
+intelSwapBuffers(__DRIdrawablePrivate *dPriv);
#endif
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
- intelScreenPrivate *screen = intel->intelScreen;
int front = 0;
if (!ctx->DrawBuffer)
intelSetFrontClipRects( intel );
if (front) {
- intel->drawOffset = screen->front.offset;
+ intel->drawRegion = &intel->intelScreen->front;
+ intel->readRegion = &intel->intelScreen->front;
} else {
- intel->drawOffset = screen->back.offset;
+ intel->drawRegion = &intel->intelScreen->back;
+ intel->readRegion = &intel->intelScreen->back;
}
- intel->vtbl.set_draw_offset( intel, intel->drawOffset );
+ intel->vtbl.set_color_region( intel, intel->drawRegion );
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
break;
}
}
+ /* Time for another vtbl entry:
+ */
+ else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G ||
+ intel->intelScreen->deviceID == PCI_CHIP_I945_GM) {
+ GLuint row_len = image->Width * image->TexFormat->TexelBytes;
+ GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ GLuint d, j;
+
+ if (INTEL_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr,
+ "Upload image %dx%dx%d offset %xm row_len %x "
+ "pitch %x depth_pitch %x\n",
+ image->Width, image->Height, image->Depth, offset,
+ row_len, t->Pitch, t->depth_pitch);
+
+ if (row_len == t->Pitch) {
+ memcpy( dst, src, row_len * image->Height * image->Depth );
+ }
+ else {
+ GLuint x = 0, y = 0;
+
+ for (d = 0 ; d < image->Depth ; d++) {
+ GLubyte *dst0 = dst + x + y * t->Pitch;
+
+ for (j = 0 ; j < image->Height ; j++) {
+ __memcpy(dst0, src, row_len );
+ src += row_len;
+ dst0 += t->Pitch;
+ }
+
+ x += MIN2(4, row_len); /* Guess: 4 byte minimum alignment */
+ if (x > t->Pitch) {
+ x = 0;
+ y += image->Height;
+ }
+ }
+ }
+
+ }
else {
GLuint row_len = image->Width * image->TexFormat->TexelBytes;
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t,
GLuint face );
+GLboolean
+intel_driReinitTextureHeap( driTexHeap *heap,
+ unsigned size );
#endif
--- /dev/null
+#include "texmem.h"
+#include "simple_list.h"
+#include "imports.h"
+#include "macros.h"
+
+#include "intel_tex.h"
+
+static GLuint
+driLog2( GLuint n )
+{
+ GLuint log2;
+
+ for ( log2 = 1 ; n > 1 ; log2++ ) {
+ n >>= 1;
+ }
+
+ return log2;
+}
+
+static void calculate_heap_size( driTexHeap * heap, unsigned size,
+ unsigned nr_regions, unsigned alignmentShift )
+{
+ unsigned l;
+
+ l = driLog2( (size - 1) / nr_regions );
+ if ( l < alignmentShift )
+ {
+ l = alignmentShift;
+ }
+
+ heap->logGranularity = l;
+ heap->size = size & ~((1L << l) - 1);
+}
+
+
+GLboolean
+intel_driReinitTextureHeap( driTexHeap *heap,
+ unsigned size )
+{
+ driTextureObject *t, *tmp;
+
+ /* Kick out everything:
+ */
+ foreach_s ( t, tmp, & heap->texture_objects ) {
+ if ( t->tObj != NULL ) {
+ driSwapOutTextureObject( t );
+ }
+ else {
+ driDestroyTextureObject( t );
+ }
+ }
+
+ /* Destroy the memory manager:
+ */
+ mmDestroy( heap->memory_heap );
+
+ /* Recreate the memory manager:
+ */
+ calculate_heap_size(heap, size, heap->nrRegions, heap->alignmentShift);
+ heap->memory_heap = mmInit( 0, heap->size );
+ if ( heap->memory_heap == NULL ) {
+ fprintf(stderr, "driReinitTextureHeap: couldn't recreate memory heap\n");
+ FREE( heap );
+ return GL_FALSE;
+ }
+
+ make_empty_list( & heap->texture_objects );
+
+ return GL_TRUE;
+}
+
+
#define DRM_I830_FREE 0x09
#define DRM_I830_INIT_HEAP 0x0a
#define DRM_I830_CMDBUFFER 0x0b
+#define DRM_I830_DESTROY_HEAP 0x0c
typedef struct {
enum {
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
+ int width, height; /* screen size in pixels */
+
+ drm_handle_t front_handle;
+ int front_offset;
+ int front_size;
+
+ drm_handle_t back_handle;
+ int back_offset;
+ int back_size;
+
+ drm_handle_t depth_handle;
+ int depth_offset;
+ int depth_size;
+
+ drm_handle_t tex_handle;
+ int tex_offset;
+ int tex_size;
+ int log_tex_granularity;
+ int pitch;
+ int rotation; /* 0, 90, 180 or 270 */
+ int rotated_offset;
+ int rotated_size;
+ int rotated_pitch;
+ int virtualX, virtualY;
} drmI830Sarea;
/* Flags for perf_boxes
int num_cliprects; /* mulitpass with multiple cliprects? */
drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */
} drmI830CmdBuffer;
-
-
+
typedef struct {
int *irq_seq;
} drmI830IrqEmit;
int start;
} drmI830MemInitHeap;
+typedef struct {
+ int region;
+} drmI830MemDestroyHeap;
+
#endif /* _I830_DRM_H_ */
#define I830_REG_SIZE 0x80000
-/* Note: This structure has changed slightly from what is expected by
- * the i830_drv.o driver. Maybe that should be reverted.
- */
typedef struct _I830DRIRec {
drm_handle_t regs;
drmSize regsSize;
drmSize depthbufferSize;
drm_handle_t depthbuffer;
+ drmSize rotatedSize;
+ drm_handle_t rotatedbuffer;
+
drm_handle_t textures;
int textureSize;
int mem;
int cpp;
int bitsPerPixel;
+
int fbOffset;
int fbStride;
int depthOffset;
int depthPitch;
+ int rotatedOffset;
+ int rotatedPitch;
+
int logTextureGranularity;
int textureOffset;