Add Intel 945GM support

Add rotation support
(Tungsten Graphics)
This commit is contained in:
Alan Hourihane 2006-01-23 10:10:48 +00:00
parent acd1f16b35
commit 39c492bb14
30 changed files with 1615 additions and 308 deletions

View file

@ -27,10 +27,12 @@ DRIVER_SOURCES = \
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 = \

View file

@ -209,7 +209,9 @@ extern void
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

View file

@ -49,9 +49,10 @@
#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
@ -147,13 +148,12 @@ static void set_color_mask( i830ContextPtr i830, GLboolean state )
(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;
}
@ -181,13 +181,12 @@ static void set_no_texture( i830ContextPtr i830 )
/* 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
};
@ -211,14 +210,12 @@ static void set_tex_rect_source( i830ContextPtr i830,
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 ); */
@ -249,16 +246,19 @@ static void set_tex_rect_source( i830ContextPtr i830,
/* 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)
@ -269,6 +269,7 @@ static void set_draw_format( i830ContextPtr i830,
DEPTH_IS_Z |
depth_format);
}
#endif
static void set_vertex_format( i830ContextPtr i830 )
@ -352,6 +353,45 @@ static void draw_quad(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,
@ -362,10 +402,10 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
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);
@ -389,7 +429,7 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
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,
@ -399,7 +439,7 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
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,
@ -413,17 +453,18 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
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,
@ -546,13 +587,13 @@ 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 );
@ -624,7 +665,8 @@ i830TryTextureDrawPixels( GLcontext *ctx,
!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;
}
@ -704,7 +746,7 @@ i830TryTextureDrawPixels( GLcontext *ctx,
textureFormat );
enable_texture_blend_replace( i830, glTextureFormat );
enable_texture_blend_replace( i830 );
/* Draw to the current draw buffer:
@ -730,3 +772,142 @@ i830TryTextureDrawPixels( GLcontext *ctx,
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 );
}

View file

@ -1003,14 +1003,14 @@ static void i830_init_packets( i830ContextPtr i830 )
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;

View file

@ -335,11 +335,22 @@ static void i830TexEnv( GLcontext *ctx, GLenum target,
}
}
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;
}

View file

@ -361,6 +361,32 @@ do { \
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.
*/
@ -369,10 +395,15 @@ static void i830_emit_state( intelContextPtr intel )
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");
@ -403,6 +434,8 @@ static void i830_emit_state( intelContextPtr intel )
}
state->emitted |= dirty;
intel->batch.last_emit_state = counter;
assert(counter == intel->batch.counter);
}
static void i830_destroy_context( intelContextPtr intel )
@ -410,13 +443,45 @@ 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_CBUFADDR2] = offset;
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_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 )
@ -444,12 +509,15 @@ void i830InitVtbl( i830ContextPtr i830 )
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;

View file

@ -36,6 +36,8 @@
#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
@ -309,7 +311,6 @@ extern void i915_print_ureg( const char *msg, GLuint ureg );
*/
extern void i915InitStateFunctions( struct dd_function_table *functions );
extern void i915InitState( i915ContextPtr i915 );
extern void i915_update_fog( GLcontext *ctx );
/*======================================================================
@ -341,6 +342,10 @@ i915ClearWithTris( intelContextPtr intel, GLbitfield mask,
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
extern void
i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
GLuint srcBuf);
/*======================================================================
* i915_fragprog.c
*/

View file

@ -34,6 +34,7 @@
#include "intel_screen.h"
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "intel_rotate.h"
#include "i915_context.h"
#include "i915_reg.h"
@ -240,7 +241,7 @@ static void set_no_texture( i915ContextPtr i915 )
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
}
#if 0
static void enable_texture_blend_replace( i915ContextPtr i915 )
{
static const GLuint prog[] = {
@ -289,14 +290,16 @@ static void set_tex_rect_source( i915ContextPtr i915,
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 ); */
@ -308,7 +311,6 @@ static void set_tex_rect_source( i915ContextPtr i915,
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) |
@ -323,17 +325,23 @@ static void set_tex_rect_source( i915ContextPtr i915,
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.
@ -442,6 +450,47 @@ static void draw_quad(i915ContextPtr i915,
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,
@ -459,7 +508,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
LOCK_HARDWARE(intel);
if(!all) {
if (!all) {
x0 = cx;
y0 = cy;
x1 = x0 + cw;
@ -478,7 +527,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
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,
@ -489,7 +538,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
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,
@ -503,7 +552,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
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 );
}
@ -514,3 +563,138 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
}
/**
* 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 );
}

View file

@ -749,6 +749,8 @@
#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)

View file

@ -779,6 +779,14 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
}
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:
;
}
@ -856,23 +864,27 @@ static void i915_init_packets( i915ContextPtr i915 )
{
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:
@ -893,6 +905,8 @@ static void i915_init_packets( i915ContextPtr i915 )
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;

View file

@ -158,7 +158,12 @@ static void i915TexEnv( GLcontext *ctx, GLenum target,
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;

View file

@ -496,7 +496,8 @@ static void i915SetTexImages( i915ContextPtr i915,
}
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 );

View file

@ -213,6 +213,58 @@ do { \
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.
*/
@ -221,17 +273,15 @@ static void i915_emit_state( intelContextPtr intel )
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);
@ -305,6 +355,8 @@ static void i915_emit_state( intelContextPtr intel )
}
state->emitted |= dirty;
intel->batch.last_emit_state = counter;
assert(counter == intel->batch.counter);
}
static void i915_destroy_context( intelContextPtr intel )
@ -312,13 +364,58 @@ 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_CBUFADDR2] = offset;
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_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;
@ -340,13 +437,16 @@ void i915InitVtbl( i915ContextPtr i915 )
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;
}

View file

@ -49,13 +49,19 @@ static void intel_fill_box( intelContextPtr intel,
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 )
@ -203,9 +209,10 @@ void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
/* 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) {
@ -224,6 +231,7 @@ void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
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();
@ -270,6 +278,11 @@ GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
*/
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;
@ -309,6 +322,8 @@ GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
ADVANCE_BATCH();
intel->batch.contains_geometry = 1;
do_discard:
return tmp;
}
@ -334,33 +349,33 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
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++)
@ -368,9 +383,11 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
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 );
@ -402,7 +419,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
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,
@ -411,8 +428,6 @@ void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint BR13, CMD;
BATCH_LOCALS;
dst_pitch *= cpp;
switch(cpp) {
case 1:
case 2:
@ -502,13 +517,17 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
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;
@ -522,11 +541,11 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
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);
@ -535,13 +554,11 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
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;
@ -635,10 +652,17 @@ void intelDestroyBatchBuffer( GLcontext *ctx )
{
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));
}
@ -646,12 +670,9 @@ void intelInitBatchBuffer( GLcontext *ctx )
{
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.
@ -666,23 +687,28 @@ void intelInitBatchBuffer( GLcontext *ctx )
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);
}

View file

@ -47,6 +47,7 @@ do { \
(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)

View file

@ -118,6 +118,8 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
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;
}
@ -256,8 +258,8 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
{
_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;
@ -273,6 +275,20 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
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,
@ -387,7 +403,8 @@ 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;
@ -580,12 +597,40 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
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);
@ -598,32 +643,54 @@ void intelGetLock( intelContextPtr intel, GLuint 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) {
@ -632,12 +699,16 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
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 */

View file

@ -111,9 +111,12 @@ struct intel_context
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 );
@ -122,6 +125,9 @@ struct intel_context
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;
@ -135,6 +141,11 @@ struct intel_context
GLint size;
GLint space;
GLubyte *ptr;
GLuint counter;
GLuint last_emit_state;
GLboolean contains_geometry;
const char *func;
GLuint last_swap;
} batch;
struct {
@ -204,9 +215,11 @@ struct intel_context
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 */
@ -411,6 +424,7 @@ extern int INTEL_DEBUG;
#define PCI_CHIP_I915_G 0x2582
#define PCI_CHIP_I915_GM 0x2592
#define PCI_CHIP_I945_G 0x2772
#define PCI_CHIP_I945_GM 0x27A2
/* ================================================================

View file

@ -45,7 +45,7 @@
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));
@ -130,7 +130,7 @@ void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock )
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);
@ -149,14 +149,15 @@ void intelFlushBatchLocked( intelContextPtr intel,
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
@ -183,6 +184,12 @@ void intelFlushBatchLocked( intelContextPtr intel,
}
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;
@ -210,13 +217,6 @@ void intelFlushBatchLocked( intelContextPtr intel,
(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;
@ -268,6 +268,12 @@ void intelFlushBatchLocked( intelContextPtr intel,
/* 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 );
}
@ -288,11 +294,6 @@ void intelFlushBatch( intelContextPtr intel, GLboolean refill )
}
void intelWaitForIdle( intelContextPtr intel )
{
if (0)
@ -309,7 +310,28 @@ void intelWaitForIdle( intelContextPtr intel )
}
/**
* 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 );
@ -323,11 +345,23 @@ void intelFlush( GLcontext *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);
}
@ -395,10 +429,19 @@ void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
}
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;

View file

@ -36,6 +36,10 @@ extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
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,
@ -45,6 +49,7 @@ 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 );

View file

@ -94,16 +94,20 @@ check_color_per_fragment_ops( const GLcontext *ctx )
}
/**
* 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);
@ -130,12 +134,41 @@ clip_pixelrect( const GLcontext *ctx,
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,
@ -144,7 +177,7 @@ intelTryReadPixels( GLcontext *ctx,
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)
@ -180,7 +213,7 @@ intelTryReadPixels( GLcontext *ctx,
/* 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
@ -192,14 +225,15 @@ intelTryReadPixels( GLcontext *ctx,
{
__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",
@ -207,37 +241,32 @@ intelTryReadPixels( GLcontext *ctx,
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 );
@ -257,7 +286,7 @@ intelReadPixels( GLcontext *ctx,
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);
}
@ -276,10 +305,11 @@ static void do_draw_pix( GLcontext *ctx,
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__);
@ -290,8 +320,7 @@ static void do_draw_pix( GLcontext *ctx,
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;
}
@ -300,29 +329,20 @@ static void do_draw_pix( GLcontext *ctx,
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 );
@ -331,7 +351,6 @@ static void do_draw_pix( GLcontext *ctx,
static GLboolean
intelTryDrawPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
@ -352,7 +371,7 @@ intelTryDrawPixels( GLcontext *ctx,
case GL_RGB:
case GL_RGBA:
case GL_BGRA:
dest = intel->drawOffset;
dest = intel->drawRegion->offset;
/* Planemask doesn't have full support in blits.
*/
@ -391,8 +410,7 @@ intelTryDrawPixels( GLcontext *ctx,
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)
@ -418,7 +436,7 @@ intelDrawPixels( GLcontext *ctx,
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 );
}

View file

@ -0,0 +1,221 @@
/**
* 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

View file

@ -0,0 +1,41 @@
#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 */

View file

@ -42,39 +42,211 @@
#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)
{
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);
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 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;
@ -96,80 +268,35 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
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);
intelUpdateScreenFromSAREA(intelScreen, sarea);
if (0)
intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
if (!intelMapScreenRegions(sPriv)) {
fprintf(stderr,"\nERROR! mapping regions\n");
_mesa_free(intelScreen);
sPriv->private = NULL;
return GL_FALSE;
}
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 (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);
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;
@ -185,6 +312,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
}
}
/* Determine if batchbuffers are allowed */
{
int ret;
drmI830GetParam gp;
@ -217,11 +345,7 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv)
{
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;
}
@ -348,6 +472,7 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
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 );
@ -482,7 +607,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
__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;

View file

@ -29,21 +29,26 @@
#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;
@ -51,9 +56,8 @@ typedef struct
int width;
int height;
int mem; /* unused */
int cpp; /* for front and back buffers */
int bitsPerPixel; /* unused */
int fbFormat;
int logTextureGranularity;
@ -66,13 +70,28 @@ typedef struct
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);
@ -81,10 +100,10 @@ intelUnbindContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
extern void
intelSwapBuffers( __DRIdrawablePrivate *dPriv);
intelSwapBuffers(__DRIdrawablePrivate *dPriv);
#endif

View file

@ -167,7 +167,6 @@ int intel_translate_logic_op( GLenum opcode )
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
intelScreenPrivate *screen = intel->intelScreen;
int front = 0;
if (!ctx->DrawBuffer)
@ -193,12 +192,14 @@ static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
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 )

View file

@ -672,6 +672,46 @@ static void intelUploadTexImage( intelContextPtr intel,
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);

View file

@ -39,4 +39,7 @@ void intelDestroyTexObj( intelContextPtr intel, intelTextureObjectPtr t );
int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t,
GLuint face );
GLboolean
intel_driReinitTextureHeap( driTexHeap *heap,
unsigned size );
#endif

View file

@ -0,0 +1,72 @@
#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;
}

View file

@ -51,6 +51,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#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 {
@ -87,6 +88,30 @@ typedef struct {
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
@ -115,8 +140,7 @@ typedef struct {
int num_cliprects; /* mulitpass with multiple cliprects? */
drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */
} drmI830CmdBuffer;
typedef struct {
int *irq_seq;
} drmI830IrqEmit;
@ -165,5 +189,9 @@ typedef struct {
int start;
} drmI830MemInitHeap;
typedef struct {
int region;
} drmI830MemDestroyHeap;
#endif /* _I830_DRM_H_ */

View file

@ -14,9 +14,6 @@
#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;
@ -27,6 +24,9 @@ typedef struct _I830DRIRec {
drmSize depthbufferSize;
drm_handle_t depthbuffer;
drmSize rotatedSize;
drm_handle_t rotatedbuffer;
drm_handle_t textures;
int textureSize;
@ -39,6 +39,7 @@ typedef struct _I830DRIRec {
int mem;
int cpp;
int bitsPerPixel;
int fbOffset;
int fbStride;
@ -48,6 +49,9 @@ typedef struct _I830DRIRec {
int depthOffset;
int depthPitch;
int rotatedOffset;
int rotatedPitch;
int logTextureGranularity;
int textureOffset;