summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915/i915_metaops.c
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2006-01-23 10:10:48 +0000
committerAlan Hourihane <alanh@tungstengraphics.com>2006-01-23 10:10:48 +0000
commit39c492bb14d706ffa8bf04f78048c05de735492b (patch)
treef29a5df4f7dc8013fb38b7b92b48b5f24a9cb8d2 /src/mesa/drivers/dri/i915/i915_metaops.c
parentacd1f16b356ee21d40c706eda14b7105a84c8001 (diff)
Add Intel 945GM support
Add rotation support (Tungsten Graphics)
Diffstat (limited to 'src/mesa/drivers/dri/i915/i915_metaops.c')
-rw-r--r--src/mesa/drivers/dri/i915/i915_metaops.c208
1 files changed, 196 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c
index a3d22b7bd0..f7b8e5415e 100644
--- a/src/mesa/drivers/dri/i915/i915_metaops.c
+++ b/src/mesa/drivers/dri/i915/i915_metaops.c
@@ -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 );
+}
+