[965] Enable EXT_framebuffer_object.

To do so, merge the remainnig necessary code from the buffers, blit, span, and
screen code to shared, and replace it with those.
This commit is contained in:
Eric Anholt 2007-12-20 11:29:39 -08:00
parent 106f398220
commit bea6b5fe5a
28 changed files with 324 additions and 2575 deletions

View file

@ -12,6 +12,8 @@ DRIVER_SOURCES = \
intel_bufmgr_ttm.c \
intel_context.c \
intel_decode.c \
intel_depthstencil.c \
intel_fbo.c \
intel_ioctl.c \
intel_mipmap_tree.c \
intel_regions.c \
@ -21,6 +23,7 @@ DRIVER_SOURCES = \
intel_pixel_bitmap.c \
intel_state.c \
intel_tex.c \
intel_tex_copy.c \
intel_tex_format.c \
intel_tex_image.c \
intel_tex_layout.c \

View file

@ -42,7 +42,7 @@
#include "intel_ioctl.h"
#include "intel_batchbuffer.h"
#include "intel_buffer_objects.h"
#include "intel_tex.h"
struct brw_array_state {
union header_union header;

View file

@ -45,7 +45,8 @@ static GLboolean do_check_fallback(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
GLuint i;
struct gl_framebuffer *fb = ctx->DrawBuffer;
/* BRW_NEW_METAOPS
*/
if (brw->metaops.active)
@ -58,11 +59,15 @@ static GLboolean do_check_fallback(struct brw_context *brw)
/* _NEW_BUFFERS
*/
if (ctx->DrawBuffer->_ColorDrawBufferMask[0] != BUFFER_BIT_FRONT_LEFT &&
ctx->DrawBuffer->_ColorDrawBufferMask[0] != BUFFER_BIT_BACK_LEFT) {
DBG("FALLBACK: draw buffer %d: 0x%08x\n",
ctx->DrawBuffer->_ColorDrawBufferMask[0]);
return GL_TRUE;
/* We can only handle a single draw buffer at the moment, and only as the
* first color buffer.
*/
for (i = 0; i < MAX_DRAW_BUFFERS; i++) {
if (fb->_NumColorDrawBuffers[i] > (i == 0 ? 1 : 0)) {
DBG("FALLBACK: draw buffer %d: 0x%08x\n",
i, ctx->DrawBuffer->_ColorDrawBufferMask[i]);
return GL_TRUE;
}
}
/* _NEW_RENDERMODE

View file

@ -376,8 +376,7 @@ static void meta_draw_quad(struct intel_context *intel,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLfloat z,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLuint color,
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1)
{
@ -388,7 +387,6 @@ static void meta_draw_quad(struct intel_context *intel,
struct gl_client_array *attribs[VERT_ATTRIB_MAX];
struct _mesa_prim prim[1];
GLfloat pos[4][3];
GLubyte color[4];
ctx->Driver.BufferData(ctx,
GL_ARRAY_BUFFER_ARB,
@ -413,7 +411,6 @@ static void meta_draw_quad(struct intel_context *intel,
pos[3][1] = y1;
pos[3][2] = z;
ctx->Driver.BufferSubData(ctx,
GL_ARRAY_BUFFER_ARB,
0,
@ -421,16 +418,14 @@ static void meta_draw_quad(struct intel_context *intel,
pos,
brw->metaops.vbo);
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;
/* Convert incoming ARGB to required RGBA */
color = (color >> 24) | (color << 8);
ctx->Driver.BufferSubData(ctx,
GL_ARRAY_BUFFER_ARB,
sizeof(pos),
sizeof(color),
color,
&color,
brw->metaops.vbo);
/* Ignoring texture coords.

View file

@ -77,7 +77,6 @@ const struct brw_tracked_state brw_blend_constant_color = {
static void upload_drawing_rect(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct brw_drawrect bdr;
int x1, y1;
int x2, y2;
@ -105,8 +104,8 @@ static void upload_drawing_rect(struct brw_context *brw)
bdr.ymin = y1;
bdr.xmax = x2;
bdr.ymax = y2;
bdr.xorg = dPriv->x;
bdr.yorg = dPriv->y;
bdr.xorg = intel->drawX;
bdr.yorg = intel->drawY;
/* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted
* uncached in brw_draw.c:

View file

@ -35,26 +35,44 @@
#include "brw_state.h"
#include "brw_defines.h"
#include "macros.h"
#include "intel_fbo.h"
static void upload_sf_vp(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
struct brw_sf_viewport sfv;
struct intel_renderbuffer *irb =
intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
GLfloat y_scale, y_bias;
memset(&sfv, 0, sizeof(sfv));
if (ctx->DrawBuffer->Name) {
/* User-created FBO */
if (irb && !irb->RenderToTexture) {
y_scale = -1.0;
y_bias = ctx->DrawBuffer->Height;
} else {
y_scale = 1.0;
y_bias = 0;
}
} else {
y_scale = -1.0;
y_bias = ctx->DrawBuffer->Height;
}
/* _NEW_VIEWPORT, BRW_NEW_METAOPS */
if (!brw->metaops.active) {
const GLfloat *v = ctx->Viewport._WindowMap.m;
sfv.viewport.m00 = v[MAT_SX];
sfv.viewport.m11 = - v[MAT_SY];
sfv.viewport.m22 = v[MAT_SZ] * depth_scale;
sfv.viewport.m30 = v[MAT_TX];
sfv.viewport.m31 = - v[MAT_TY] + ctx->DrawBuffer->Height;
sfv.viewport.m32 = v[MAT_TZ] * depth_scale;
sfv.viewport.m00 = v[MAT_SX];
sfv.viewport.m11 = v[MAT_SY] * y_scale;
sfv.viewport.m22 = v[MAT_SZ] * depth_scale;
sfv.viewport.m30 = v[MAT_TX];
sfv.viewport.m31 = v[MAT_TY] * y_scale + y_bias;
sfv.viewport.m32 = v[MAT_TZ] * depth_scale;
} else {
sfv.viewport.m00 = 1;
sfv.viewport.m11 = - 1;

View file

@ -1,617 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <stdio.h>
#include <errno.h>
#include "mtypes.h"
#include "context.h"
#include "enums.h"
#include "vblank.h"
#include "intel_reg.h"
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_structs.h"
#include "dri_bufmgr.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
/**
* Copy the back color buffer to the front color buffer.
* Used for SwapBuffers().
*/
void
intelCopyBuffer(__DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
struct intel_context *intel;
GLboolean missed_target;
int64_t ust;
DBG("%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
if (intel->last_swap_fence) {
dri_fence_wait(intel->last_swap_fence);
dri_fence_unreference(intel->last_swap_fence);
intel->last_swap_fence = NULL;
}
intel->last_swap_fence = intel->first_swap_fence;
intel->first_swap_fence = NULL;
/* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
* should work regardless.
*/
LOCK_HARDWARE(intel);
if (!rect)
{
UNLOCK_HARDWARE( intel );
driWaitForVBlank( dPriv, &missed_target );
LOCK_HARDWARE( intel );
}
{
intelScreenPrivate *intelScreen = intel->intelScreen;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_region *src, *dst;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *pbox = dPriv->pClipRects;
int cpp = intelScreen->cpp;
int src_pitch, dst_pitch;
int BR13, CMD;
int i;
if (intel->sarea->pf_current_page == 0) {
dst = intel->front_region;
src = intel->back_region;
}
else {
assert(0);
src = intel->front_region;
dst = intel->back_region;
}
src_pitch = src->pitch * src->cpp;
dst_pitch = dst->pitch * dst->cpp;
if (cpp == 2) {
BR13 = (0xCC << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
}
else {
BR13 = (0xCC << 16) | (1 << 24) | (1 << 25);
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
if (src->tiled) {
CMD |= XY_SRC_TILED;
src_pitch /= 4;
}
if (dst->tiled) {
CMD |= XY_DST_TILED;
dst_pitch /= 4;
}
for (i = 0; i < nbox; i++, pbox++) {
drm_clip_rect_t box = *pbox;
if (rect) {
if (!intel_intersect_cliprects(&box, &box, rect))
continue;
}
if (box.x1 > box.x2 ||
box.y1 > box.y2 ||
box.x2 > intelScreen->width ||
box.y2 > intelScreen->height)
continue;
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13 | dst_pitch);
OUT_BATCH((box.y1 << 16) | box.x1);
OUT_BATCH((box.y2 << 16) | box.x2);
OUT_RELOC(dst->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, 0);
OUT_BATCH((box.y1 << 16) | box.x1);
OUT_BATCH(src_pitch);
OUT_RELOC(src->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0);
ADVANCE_BATCH();
}
if (intel->first_swap_fence)
dri_fence_unreference(intel->first_swap_fence);
intel_batchbuffer_flush(intel->batch);
intel->first_swap_fence = intel->batch->last_fence;
if (intel->first_swap_fence)
dri_fence_reference(intel->first_swap_fence);
}
UNLOCK_HARDWARE(intel);
if (!rect)
{
intel->swap_count++;
(*dri_interface->getUST)(&ust);
if (missed_target) {
intel->swap_missed_count++;
intel->swap_missed_ust = ust - intel->swap_ust;
}
intel->swap_ust = ust;
}
}
void
intelEmitFillBlit(struct intel_context *intel,
GLuint cpp,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color)
{
GLuint BR13, CMD;
BATCH_LOCALS;
dst_pitch *= cpp;
switch (cpp) {
case 1:
case 2:
case 3:
BR13 = (0xF0 << 16) | (1 << 24);
CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = (0xF0 << 16) | (1 << 24) | (1 << 25);
CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
return;
}
if (dst_tiled) {
CMD |= XY_DST_TILED;
dst_pitch /= 4;
}
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13 | dst_pitch);
OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w));
OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
OUT_BATCH(color);
ADVANCE_BATCH();
}
static GLuint translate_raster_op(GLenum logicop)
{
switch(logicop) {
case GL_CLEAR: return 0x00;
case GL_AND: return 0x88;
case GL_AND_REVERSE: return 0x44;
case GL_COPY: return 0xCC;
case GL_AND_INVERTED: return 0x22;
case GL_NOOP: return 0xAA;
case GL_XOR: return 0x66;
case GL_OR: return 0xEE;
case GL_NOR: return 0x11;
case GL_EQUIV: return 0x99;
case GL_INVERT: return 0x55;
case GL_OR_REVERSE: return 0xDD;
case GL_COPY_INVERTED: return 0x33;
case GL_OR_INVERTED: return 0xBB;
case GL_NAND: return 0x77;
case GL_SET: return 0xFF;
default: return 0;
}
}
/* Copy BitBlt
*/
void
intelEmitCopyBlit(struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
dri_bo *src_buffer,
GLuint src_offset,
GLboolean src_tiled,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort src_x, GLshort src_y,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h,
GLenum logic_op)
{
GLuint CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
BATCH_LOCALS;
DBG("%s src:buf(%d)/%d+%d %d,%d dst:buf(%d)/%d+%d %d,%d sz:%dx%d op:%d\n",
__FUNCTION__,
src_buffer, src_pitch, src_offset, src_x, src_y,
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y,
w, h, logic_op);
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
src_pitch *= cpp;
dst_pitch *= cpp;
BR13 = translate_raster_op(logic_op) << 16;
switch (cpp) {
case 1:
case 2:
case 3:
BR13 |= (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 |= (1 << 24) | (1 << 25);
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
break;
default:
return;
}
if (dst_tiled) {
CMD |= XY_DST_TILED;
dst_pitch /= 4;
}
if (src_tiled) {
CMD |= XY_SRC_TILED;
src_pitch /= 4;
}
if (dst_y2 < dst_y || dst_x2 < dst_x) {
return;
}
dst_pitch &= 0xffff;
src_pitch &= 0xffff;
/* Initial y values don't seem to work with negative pitches. If
* we adjust the offsets manually (below), it seems to work fine.
*
* On the other hand, if we always adjust, the hardware doesn't
* know which blit directions to use, so overlapping copypixels get
* the wrong result.
*/
if (dst_pitch > 0 && src_pitch > 0) {
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13 | dst_pitch);
OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2);
OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
dst_offset);
OUT_BATCH((src_y << 16) | src_x);
OUT_BATCH(src_pitch);
OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
src_offset);
ADVANCE_BATCH();
}
else {
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13 | dst_pitch);
OUT_BATCH((0 << 16) | dst_x);
OUT_BATCH((h << 16) | dst_x2);
OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
dst_offset + dst_y * dst_pitch);
OUT_BATCH((0 << 16) | src_x);
OUT_BATCH(src_pitch);
OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
src_offset + src_y * src_pitch);
ADVANCE_BATCH();
}
}
void
intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
{
struct intel_context *intel = intel_context(ctx);
struct gl_framebuffer *fb = ctx->DrawBuffer;
intelScreenPrivate *intelScreen = intel->intelScreen;
GLuint clear_depth, clear_color;
GLint cpp = intelScreen->cpp;
GLboolean all;
GLint i;
struct intel_region *front = intel->front_region;
struct intel_region *back = intel->back_region;
struct intel_region *depth = intel->depth_region;
GLuint BR13, FRONT_CMD, BACK_CMD, DEPTH_CMD;
GLuint front_pitch;
GLuint back_pitch;
GLuint depth_pitch;
BATCH_LOCALS;
clear_color = intel->ClearColor;
clear_depth = 0;
if (mask & BUFFER_BIT_DEPTH) {
clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
}
if (mask & BUFFER_BIT_STENCIL) {
clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
}
switch (cpp) {
case 2:
BR13 = (0xF0 << 16) | (1 << 24);
BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD;
DEPTH_CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = (0xF0 << 16) | (1 << 24) | (1 << 25);
BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD |
XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
DEPTH_CMD = XY_COLOR_BLT_CMD;
if (mask & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_BLT_WRITE_RGB;
if (mask & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_BLT_WRITE_ALPHA;
break;
default:
return;
}
intelFlush(&intel->ctx);
LOCK_HARDWARE( intel );
if (intel->numClipRects) {
GLint cx, cy, cw, ch;
/* Get clear bounds after locking */
cx = fb->_Xmin;
cy = fb->_Ymin;
cw = fb->_Xmax - cx;
ch = fb->_Ymax - cy;
all = (cw == fb->Width && ch == fb->Height);
/* flip top to bottom */
cy = intel->driDrawable->h - cy - ch;
cx = cx + intel->drawX;
cy += intel->drawY;
/* adjust for page flipping */
if ( intel->sarea->pf_current_page == 0 ) {
front = intel->front_region;
back = intel->back_region;
}
else {
back = intel->front_region;
front = intel->back_region;
}
front_pitch = front->pitch * front->cpp;
back_pitch = back->pitch * back->cpp;
depth_pitch = depth->pitch * depth->cpp;
if (front->tiled) {
FRONT_CMD |= XY_DST_TILED;
front_pitch /= 4;
}
if (back->tiled) {
BACK_CMD |= XY_DST_TILED;
back_pitch /= 4;
}
if (depth->tiled) {
DEPTH_CMD |= XY_DST_TILED;
depth_pitch /= 4;
}
for (i = 0 ; i < intel->numClipRects ; i++)
{
drm_clip_rect_t *box = &intel->pClipRects[i];
drm_clip_rect_t b;
if (!all) {
GLint x = box->x1;
GLint y = box->y1;
GLint w = box->x2 - x;
GLint h = box->y2 - y;
if (x < cx) w -= cx - x, x = cx;
if (y < cy) h -= cy - y, y = cy;
if (x + w > cx + cw) w = cx + cw - x;
if (y + h > cy + ch) h = cy + ch - y;
if (w <= 0) continue;
if (h <= 0) continue;
b.x1 = x;
b.y1 = y;
b.x2 = x + w;
b.y2 = y + h;
} else {
b = *box;
}
if (b.x1 > b.x2 ||
b.y1 > b.y2 ||
b.x2 > intelScreen->width ||
b.y2 > intelScreen->height)
continue;
if ( mask & BUFFER_BIT_FRONT_LEFT ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(FRONT_CMD);
OUT_BATCH(BR13 | front_pitch);
OUT_BATCH((b.y1 << 16) | b.x1);
OUT_BATCH((b.y2 << 16) | b.x2);
OUT_RELOC(front->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
0);
OUT_BATCH(clear_color);
ADVANCE_BATCH();
}
if ( mask & BUFFER_BIT_BACK_LEFT ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(BACK_CMD);
OUT_BATCH(BR13 | back_pitch);
OUT_BATCH((b.y1 << 16) | b.x1);
OUT_BATCH((b.y2 << 16) | b.x2);
OUT_RELOC(back->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
0);
OUT_BATCH(clear_color);
ADVANCE_BATCH();
}
if ( mask & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(DEPTH_CMD);
OUT_BATCH(BR13 | depth_pitch);
OUT_BATCH((b.y1 << 16) | b.x1);
OUT_BATCH((b.y2 << 16) | b.x2);
OUT_RELOC(depth->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
0);
OUT_BATCH(clear_depth);
ADVANCE_BATCH();
}
}
intel_batchbuffer_flush(intel->batch);
}
UNLOCK_HARDWARE(intel);
}
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
GLuint fg_color,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLenum logic_op)
{
struct xy_text_immediate_blit text;
int dwords = ALIGN(src_size, 8) / 4;
uint32_t opcode, br13;
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
if (w < 0 || h < 0)
return;
dst_pitch *= cpp;
if (dst_tiled)
dst_pitch /= 4;
DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
__FUNCTION__,
dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
memset(&text, 0, sizeof(text));
text.dw0.client = CLIENT_2D;
text.dw0.opcode = OPCODE_XY_TEXT_IMMEDIATE_BLT;
text.dw0.pad0 = 0;
text.dw0.byte_packed = 1; /* ?maybe? */
text.dw0.pad1 = 0;
text.dw0.dst_tiled = dst_tiled;
text.dw0.pad2 = 0;
text.dw0.length = (sizeof(text)/sizeof(int)) - 2 + dwords;
text.dw1.dest_y1 = y; /* duplicates info in setup blit */
text.dw1.dest_x1 = x;
text.dw2.dest_y2 = y + h;
text.dw2.dest_x2 = x + w;
intel_batchbuffer_require_space( intel->batch,
(8 * 4) +
sizeof(text) +
dwords,
INTEL_BATCH_NO_CLIPRECTS );
opcode = XY_SETUP_BLT_CMD;
if (cpp == 4)
opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
if (dst_tiled)
opcode |= XY_DST_TILED;
br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
if (cpp == 2)
br13 |= BR13_565;
else
br13 |= BR13_8888;
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(opcode);
OUT_BATCH(br13);
OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
OUT_BATCH(0); /* bg */
OUT_BATCH(fg_color); /* fg */
OUT_BATCH(0); /* pattern base addr */
ADVANCE_BATCH();
intel_batchbuffer_data( intel->batch,
&text,
sizeof(text),
INTEL_BATCH_NO_CLIPRECTS );
intel_batchbuffer_data( intel->batch,
src_bits,
dwords * 4,
INTEL_BATCH_NO_CLIPRECTS );
}

View file

@ -0,0 +1 @@
../intel/intel_blit.c

View file

@ -1,76 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef INTEL_BLIT_H
#define INTEL_BLIT_H
#include "intel_context.h"
#include "intel_ioctl.h"
extern void intelCopyBuffer( __DRIdrawablePrivate *dpriv,
const drm_clip_rect_t *rect );
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask);
extern void intelEmitCopyBlit( struct intel_context *intel,
GLuint cpp,
GLshort src_pitch,
dri_bo *src_buffer,
GLuint src_offset,
GLboolean src_tiled,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort srcx, GLshort srcy,
GLshort dstx, GLshort dsty,
GLshort w, GLshort h,
GLenum logic_op );
extern void intelEmitFillBlit( struct intel_context *intel,
GLuint cpp,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLuint color );
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
GLuint fg_color,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort dst_x, GLshort dst_y,
GLshort w, GLshort h,
GLenum logic_op );
#endif

View file

@ -1,587 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "context.h"
#include "framebuffer.h"
#include "macros.h"
#include "utils.h"
#include "vblank.h"
#include "swrast/swrast.h"
GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
const drm_clip_rect_t *a,
const drm_clip_rect_t *b )
{
dst->x1 = MAX2(a->x1, b->x1);
dst->x2 = MIN2(a->x2, b->x2);
dst->y1 = MAX2(a->y1, b->y1);
dst->y2 = MIN2(a->y2, b->y2);
return (dst->x1 <= dst->x2 &&
dst->y1 <= dst->y2);
}
struct intel_region *intel_drawbuf_region( struct intel_context *intel )
{
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
return intel->front_region;
case BUFFER_BIT_BACK_LEFT:
return intel->back_region;
default:
/* Not necessary to fallback - could handle either NONE or
* FRONT_AND_BACK cases below.
*/
return NULL;
}
}
struct intel_region *intel_readbuf_region( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
/* This will have to change to support EXT_fbo's, but is correct
* for now:
*/
switch (ctx->ReadBuffer->_ColorReadBufferIndex) {
case BUFFER_FRONT_LEFT:
return intel->front_region;
case BUFFER_BACK_LEFT:
return intel->back_region;
default:
assert(0);
return NULL;
}
}
static void intelBufferSize(GLframebuffer *buffer,
GLuint *width,
GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
/* Need to lock to make sure the driDrawable is uptodate. This
* information is used to resize Mesa's software buffers, so it has
* to be correct.
*/
LOCK_HARDWARE(intel);
if (intel->driDrawable) {
*width = intel->driDrawable->w;
*height = intel->driDrawable->h;
}
else {
*width = 0;
*height = 0;
}
UNLOCK_HARDWARE(intel);
}
static void intelSetFrontClipRects( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
}
static void intelSetBackClipRects( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!dPriv) return;
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
} else {
intel->numClipRects = dPriv->numBackClipRects;
intel->pClipRects = dPriv->pBackClipRects;
intel->drawX = dPriv->backX;
intel->drawY = dPriv->backY;
if (dPriv->numBackClipRects == 1 &&
dPriv->x == dPriv->backX &&
dPriv->y == dPriv->backY) {
/* Repeat the calculation of the back cliprect dimensions here
* as early versions of dri.a in the Xserver are incorrect. Try
* very hard not to restrict future versions of dri.a which
* might eg. allocate truly private back buffers.
*/
int x1, y1;
int x2, y2;
x1 = dPriv->x;
y1 = dPriv->y;
x2 = dPriv->x + dPriv->w;
y2 = dPriv->y + dPriv->h;
if (x1 < 0) x1 = 0;
if (y1 < 0) y1 = 0;
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
if (x1 == dPriv->pBackClipRects[0].x1 &&
y1 == dPriv->pBackClipRects[0].y1) {
dPriv->pBackClipRects[0].x2 = x2;
dPriv->pBackClipRects[0].y2 = y2;
}
}
}
}
void intelWindowMoved( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
if (!intel->ctx.DrawBuffer) {
intelSetFrontClipRects( intel );
}
else {
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects( intel );
break;
case BUFFER_BIT_BACK_LEFT:
intelSetBackClipRects( intel );
break;
default:
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
intelSetFrontClipRects( intel );
}
}
/* Get updated plane info so we sync against the right vblank counter */
if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
volatile drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
.y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
.x2 = sarea->planeA_x + sarea->planeA_w,
.y2 = sarea->planeA_y + sarea->planeA_h };
drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
.x2 = sarea->planeB_x + sarea->planeB_w,
.y2 = sarea->planeB_y + sarea->planeB_h };
GLint areaA = driIntersectArea( drw_rect, planeA_rect );
GLint areaB = driIntersectArea( drw_rect, planeB_rect );
GLuint flags = dPriv->vblFlags;
/* Update vblank info
*/
if (areaB > areaA || (areaA == areaB && areaB > 0)) {
flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
} else {
flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
}
/* Check to see if we changed pipes */
if (flags != dPriv->vblFlags && dPriv->vblFlags &&
!(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
int64_t count;
/*
* Update msc_base from old pipe
*/
driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
dPriv->msc_base = count;
/*
* Then get new vblank_base and vblSeq values
*/
dPriv->vblFlags = flags;
driGetCurrentVBlank(dPriv);
dPriv->vblank_base = dPriv->vblSeq;
}
} else {
dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
}
_mesa_resize_framebuffer(&intel->ctx,
(GLframebuffer*)dPriv->driverPrivate,
dPriv->w, dPriv->h);
/* Set state we know depends on drawable parameters:
*/
{
GLcontext *ctx = &intel->ctx;
if (ctx->Driver.Scissor)
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
if (ctx->Driver.DepthRange)
ctx->Driver.DepthRange( ctx,
ctx->Viewport.Near,
ctx->Viewport.Far );
intel->NewGLState |= _NEW_SCISSOR;
}
/* This works because the lock is always grabbed before emitting
* commands and commands are always flushed prior to releasing
* the lock.
*/
intel->NewGLState |= _NEW_WINDOW_POS;
}
/* A true meta version of this would be very simple and additionally
* machine independent. Maybe we'll get there one day.
*/
static void intelClearWithTris(struct intel_context *intel,
GLbitfield mask)
{
GLcontext *ctx = &intel->ctx;
drm_clip_rect_t clear;
GLint cx, cy, cw, ch;
if (INTEL_DEBUG & DEBUG_DRI)
_mesa_printf("%s %x\n", __FUNCTION__, mask);
{
intel->vtbl.install_meta_state(intel);
/* Get clear bounds after locking */
cx = ctx->DrawBuffer->_Xmin;
cy = ctx->DrawBuffer->_Ymin;
cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
clear.x1 = cx;
clear.y1 = cy;
clear.x2 = cx + cw;
clear.y2 = cy + ch;
/* Back and stencil cliprects are the same. Try and do both
* buffers at once:
*/
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL|BUFFER_BIT_DEPTH)) {
intel->vtbl.meta_draw_region(intel,
intel->back_region,
intel->depth_region );
if (mask & BUFFER_BIT_BACK_LEFT)
intel->vtbl.meta_color_mask(intel, GL_TRUE );
else
intel->vtbl.meta_color_mask(intel, GL_FALSE );
if (mask & BUFFER_BIT_STENCIL)
intel->vtbl.meta_stencil_replace( intel,
intel->ctx.Stencil.WriteMask[0],
intel->ctx.Stencil.Clear);
else
intel->vtbl.meta_no_stencil_write(intel);
if (mask & BUFFER_BIT_DEPTH)
intel->vtbl.meta_depth_replace( intel );
else
intel->vtbl.meta_no_depth_write(intel);
/* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
* drawing origin may not be correctly emitted.
*/
intel->vtbl.meta_draw_quad(intel,
clear.x1, clear.x2,
clear.y1, clear.y2,
intel->ctx.Depth.Clear,
intel->clear_chan[0],
intel->clear_chan[1],
intel->clear_chan[2],
intel->clear_chan[3],
0, 0, 0, 0);
}
/* Front may have different cliprects:
*/
if (mask & BUFFER_BIT_FRONT_LEFT) {
intel->vtbl.meta_no_depth_write(intel);
intel->vtbl.meta_no_stencil_write(intel);
intel->vtbl.meta_color_mask(intel, GL_TRUE );
intel->vtbl.meta_draw_region(intel,
intel->front_region,
intel->depth_region);
/* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
* drawing origin may not be correctly emitted.
*/
intel->vtbl.meta_draw_quad(intel,
clear.x1, clear.x2,
clear.y1, clear.y2,
0,
intel->clear_chan[0],
intel->clear_chan[1],
intel->clear_chan[2],
intel->clear_chan[3],
0, 0, 0, 0);
}
intel->vtbl.leave_meta_state( intel );
}
}
static void intelClear(GLcontext *ctx, GLbitfield mask)
{
struct intel_context *intel = intel_context( ctx );
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
if (INTEL_DEBUG & DEBUG_DRI)
fprintf(stderr, "%s %x\n", __FUNCTION__, mask);
if (mask & BUFFER_BIT_FRONT_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_FRONT_LEFT;
}
else {
tri_mask |= BUFFER_BIT_FRONT_LEFT;
}
}
if (mask & BUFFER_BIT_BACK_LEFT) {
if (colorMask == ~0) {
blit_mask |= BUFFER_BIT_BACK_LEFT;
}
else {
tri_mask |= BUFFER_BIT_BACK_LEFT;
}
}
if (mask & BUFFER_BIT_STENCIL) {
if (!intel->hw_stencil) {
swrast_mask |= BUFFER_BIT_STENCIL;
}
else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff ||
intel->depth_region->tiled) {
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
blit_mask |= BUFFER_BIT_STENCIL;
}
}
/* Do depth with stencil if possible to avoid 2nd pass over the
* same buffer.
*/
if (mask & BUFFER_BIT_DEPTH) {
if ((tri_mask & BUFFER_BIT_STENCIL) ||
intel->depth_region->tiled)
tri_mask |= BUFFER_BIT_DEPTH;
else
blit_mask |= BUFFER_BIT_DEPTH;
}
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
intelFlush( ctx );
if (blit_mask)
intelClearWithBlit( ctx, blit_mask );
if (tri_mask)
intelClearWithTris( intel, tri_mask );
if (swrast_mask)
_swrast_Clear( ctx, swrast_mask );
}
/* Flip the front & back buffers
*/
static void intelPageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
struct intel_context *intel;
int tmp, ret;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
if (dPriv->pClipRects) {
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
intel->sarea->nbox = 1;
}
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
if (ret) {
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
UNLOCK_HARDWARE( intel );
exit(1);
}
tmp = intel->sarea->last_enqueue;
intelRefillBatchLocked( intel );
UNLOCK_HARDWARE( intel );
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
#endif
}
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
struct intel_context *intel;
GLcontext *ctx;
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv, NULL );
}
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
struct intel_context *intel = dPriv->driContextPriv->driverPrivate;
GLcontext *ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
intelCopyBuffer( dPriv, &rect );
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
{
struct intel_context *intel = intel_context(ctx);
int front = 0;
if (!ctx->DrawBuffer)
return;
switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
case BUFFER_BIT_FRONT_LEFT:
front = 1;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
case BUFFER_BIT_BACK_LEFT:
front = 0;
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
if ( intel->sarea->pf_current_page == 1 )
front ^= 1;
intelSetFrontClipRects( intel );
if (front) {
if (intel->draw_region != intel->front_region) {
intel_region_release(&intel->draw_region);
intel_region_reference(&intel->draw_region, intel->front_region);
}
} else {
if (intel->draw_region != intel->back_region) {
intel_region_release(&intel->draw_region);
intel_region_reference(&intel->draw_region, intel->back_region);
}
}
intel->vtbl.set_draw_region( intel,
intel->draw_region,
intel->depth_region);
}
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
{
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}
void intelInitBufferFuncs( struct dd_function_table *functions )
{
functions->Clear = intelClear;
functions->GetBufferSize = intelBufferSize;
functions->DrawBuffer = intelDrawBuffer;
functions->ReadBuffer = intelReadBuffer;
}

View file

@ -0,0 +1 @@
../intel/intel_buffers.c

View file

@ -57,10 +57,13 @@
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_buffers.h"
#include "intel_buffer_objects.h"
#include "intel_decode.h"
#include "intel_fbo.h"
#include "intel_bufmgr_ttm.h"
#include "drirenderbuffer.h"
#include "i915_drm.h"
#include "utils.h"
@ -83,6 +86,7 @@ int INTEL_DEBUG = (0);
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_EXT_point_parameters
@ -202,12 +206,12 @@ const struct dri_extension card_extensions[] =
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions},
{ "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
{ "GL_ARB_fragment_shader", NULL },
/* XXX not implement yet, to compile builtin glsl lib */
{ "GL_ARB_draw_buffers", NULL },
{ NULL, NULL }
};
const struct dri_extension ttm_extensions[] = {
{"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
{"GL_ARB_pixel_buffer_object", NULL},
{NULL, NULL}
};
@ -262,6 +266,7 @@ static const struct dri_debug_control debug_control[] =
{ "blit", DEBUG_BLIT},
{ "mip", DEBUG_MIPTREE},
{ "reg", DEBUG_REGION},
{ "fbo", DEBUG_FBO },
{ NULL, 0 }
};
@ -551,6 +556,8 @@ GLboolean intelInitContext( struct intel_context *intel,
intel_recreate_static_regions(intel);
intel_bufferobj_init( intel );
intel_fbo_init( intel );
intel->batch = intel_batchbuffer_alloc( intel );
intel->last_swap_fence = NULL;
intel->first_swap_fence = NULL;
@ -623,16 +630,6 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
*/
}
/* Free the regions created to describe front/back/depth
* buffers:
*/
#if 0
intel_region_release(&intel->front_region);
intel_region_release(&intel->back_region);
intel_region_release(&intel->depth_region);
intel_region_release(&intel->draw_region);
#endif
/* free the Mesa context */
intel->ctx.VertexProgram.Current = NULL;
intel->ctx.FragmentProgram.Current = NULL;
@ -653,7 +650,44 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
{
if (driContextPriv) {
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
struct intel_context *intel =
(struct intel_context *) driContextPriv->driverPrivate;
struct intel_framebuffer *intel_fb =
(struct intel_framebuffer *) driDrawPriv->driverPrivate;
GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
/* XXX FBO temporary fix-ups! */
/* if the renderbuffers don't have regions, init them from the context.
* They will be unreferenced when the renderbuffer is destroyed.
*/
{
struct intel_renderbuffer *irbDepth
= intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
struct intel_renderbuffer *irbStencil
= intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
if (intel_fb->color_rb[0] && !intel_fb->color_rb[0]->region) {
intel_region_reference(&intel_fb->color_rb[0]->region,
intel->front_region);
}
if (intel_fb->color_rb[1] && !intel_fb->color_rb[1]->region) {
intel_region_reference(&intel_fb->color_rb[1]->region,
intel->back_region);
}
if (intel_fb->color_rb[2] && !intel_fb->color_rb[2]->region) {
intel_region_reference(&intel_fb->color_rb[2]->region,
intel->third_region);
}
if (irbDepth && !irbDepth->region) {
intel_region_reference(&irbDepth->region, intel->depth_region);
}
if (irbStencil && !irbStencil->region) {
intel_region_reference(&irbStencil->region, intel->depth_region);
}
}
/* set GLframebuffer size to match window, if needed */
driUpdateFramebufferSize(&intel->ctx, driDrawPriv);
if (intel->driReadDrawable != driReadPriv) {
intel->driReadDrawable = driReadPriv;
@ -673,10 +707,10 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
}
_mesa_make_current(&intel->ctx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
&intel_fb->Base,
readFb);
intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] );
intel_draw_buffer(&intel->ctx, &intel_fb->Base);
} else {
_mesa_make_current(NULL, NULL, NULL);
}

View file

@ -33,6 +33,7 @@
#include "mtypes.h"
#include "drm.h"
#include "texmem.h"
#include "dri_bufmgr.h"
#include "intel_screen.h"
#include "intel_tex_obj.h"
@ -60,6 +61,8 @@ typedef void (*intel_point_func)(struct intel_context *, intelVertex *);
#define INTEL_FALLBACK_USER 0x4
#define INTEL_FALLBACK_RENDERMODE 0x8
#define INTEL_FALLBACK_TEXTURE 0x10
#define INTEL_FALLBACK_DEPTH_BUFFER 0x20
#define INTEL_FALLBACK_STENCIL_BUFFER 0x40
extern void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode );
#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
@ -124,12 +127,11 @@ struct intel_context
void (*meta_frame_buffer_texture)( struct intel_context *intel,
GLint xoff, GLint yoff );
void (*meta_draw_quad)(struct intel_context *intel,
void (*meta_draw_quad)(struct intel_context *intel,
GLfloat x0, GLfloat x1,
GLfloat y0, GLfloat y1,
GLfloat y0, GLfloat y1,
GLfloat z,
GLubyte red, GLubyte green,
GLubyte blue, GLubyte alpha,
GLuint color, /* ARGB32 */
GLfloat s0, GLfloat s1,
GLfloat t0, GLfloat t1);
@ -163,7 +165,8 @@ struct intel_context
unsigned batch_id;
GLubyte clear_chan[4];
GLuint ClearColor;
GLuint ClearColor565;
GLuint ClearColor8888;
GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */
@ -189,6 +192,7 @@ struct intel_context
GLuint numClipRects; /* cliprects for that buffer */
drm_clip_rect_t *pClipRects;
struct gl_texture_object *frame_buffer_texobj;
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */
GLboolean scissor;
drm_clip_rect_t draw_rect;
@ -313,6 +317,7 @@ extern int INTEL_DEBUG;
#define DEBUG_BLIT 0x200000
#define DEBUG_REGION 0x400000
#define DEBUG_MIPTREE 0x800000
#define DEBUG_FBO 0x1000000
#define DBG(...) do { \
if (INTEL_DEBUG & FILE_DEBUG_FLAG) \

View file

@ -0,0 +1 @@
../intel/intel_depthstencil.c

View file

@ -0,0 +1 @@
../intel/intel_fbo.c

View file

@ -1 +0,0 @@
../intel/intel_mipmap_tree.h

View file

@ -190,7 +190,7 @@ do_texture_copypixels(GLcontext * ctx,
dstx, dstx + width,
dsty, dsty + height,
ctx->Current.RasterPos[ 2 ],
0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0 );
0, 0.0, 0.0, 0.0, 0.0 );
intel->vtbl.leave_meta_state( intel );

View file

@ -1,693 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "framebuffer.h"
#include "matrix.h"
#include "renderbuffer.h"
#include "simple_list.h"
#include "utils.h"
#include "vblank.h"
#include "xmlpool.h"
#include "intel_screen.h"
#include "intel_context.h"
#include "intel_tex.h"
#include "intel_span.h"
#include "intel_ioctl.h"
#include "intel_regions.h"
#include "intel_bufmgr_ttm.h"
#include "i915_drm.h"
#include "i830_dri.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END
DRI_CONF_END;
const GLuint __driNConfigOptions = 4;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /*USE_NEW_INTERFACE*/
/**
* 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 {
/* Use the old static allocation method if the server isn't setting up
* a movable handle for us. Add in the front buffer offset from
* framebuffer start, as our span routines (unlike other drivers) expect
* the renderbuffer address to point to the beginning of the
* renderbuffer.
*/
intelScreen->front.map = (char *)sPriv->pFB;
if (intelScreen->front.map == NULL) {
fprintf(stderr, "Failed to find framebuffer mapping\n");
return GL_FALSE;
}
}
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 front.handle is present, we're doing the dynamic front buffer mapping,
* but if we've fallen back to static allocation then we shouldn't try to
* unmap here.
*/
if (intelScreen->front.handle) {
#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",
intelScreen->front.size, 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(volatile 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,
volatile 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->front.tiled = sarea->front_tiled;
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->back.tiled = sarea->back_tiled;
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->depth.tiled = sarea->depth_tiled;
if (intelScreen->driScrnPriv->ddx_version.minor >= 9) {
intelScreen->front.bo_handle = sarea->front_bo_handle;
intelScreen->back.bo_handle = sarea->back_bo_handle;
intelScreen->depth.bo_handle = sarea->depth_bo_handle;
} else {
intelScreen->front.bo_handle = -1;
intelScreen->back.bo_handle = -1;
intelScreen->depth.bo_handle = -1;
}
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->rotated.tiled = sarea->rotated_tiled;
intelScreen->current_rotation = sarea->rotation;
#if 0
matrix23Rotate(&intelScreen->rotMatrix,
sarea->width, sarea->height, sarea->rotation);
#endif
intelScreen->rotatedWidth = sarea->virtualX;
intelScreen->rotatedHeight = sarea->virtualY;
if (0)
intelPrintSAREA(sarea);
}
static const __DRIextension *intelExtensions[] = {
&driReadDrawableExtension,
&driCopySubBufferExtension.base,
&driSwapControlExtension.base,
&driFrameTrackingExtension.base,
&driMediaStreamCounterExtension.base,
NULL
};
static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen;
I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv;
volatile drmI830Sarea *sarea;
if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
fprintf(stderr,"\nERROR! sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", (unsigned long)sizeof(I830DRIRec), sPriv->devPrivSize);
return GL_FALSE;
}
/* Allocate the private area */
intelScreen = (intelScreenPrivate *)CALLOC(sizeof(intelScreenPrivate));
if (!intelScreen) {
fprintf(stderr,"\nERROR! Allocating private area failed\n");
return GL_FALSE;
}
/* parse information in __driConfigOptions */
driParseOptionInfo (&intelScreen->optionCache,
__driConfigOptions, __driNConfigOptions);
intelScreen->driScrnPriv = sPriv;
sPriv->private = (void *)intelScreen;
intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
sarea = (volatile drmI830Sarea *)
(((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
intelScreen->deviceID = gDRIPriv->deviceID;
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;
}
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->drmMinor = sPriv->drm_version.minor;
/* Determine if IRQs are active? */
{
int ret;
drmI830GetParam gp;
gp.param = I830_PARAM_IRQ_ACTIVE;
gp.value = &intelScreen->irq_active;
ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmI830GetParam: %d\n", ret);
return GL_FALSE;
}
}
/* Determine if batchbuffers are allowed */
{
int ret;
drmI830GetParam gp;
gp.param = I830_PARAM_ALLOW_BATCHBUFFER;
gp.value = &intelScreen->allow_batchbuffer;
ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret);
return GL_FALSE;
}
}
sPriv->extensions = intelExtensions;
return GL_TRUE;
}
static void intelDestroyScreen(__DRIscreenPrivate *sPriv)
{
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
intelUnmapScreenRegions(intelScreen);
FREE(intelScreen);
sPriv->private = NULL;
}
static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private;
if (isPixmap) {
return GL_FALSE; /* not implemented */
} else {
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24);
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
{
driRenderbuffer *frontRb
= driNewRenderbuffer(GL_RGBA,
screen->front.map,
screen->cpp,
screen->front.offset, screen->front.pitch,
driDrawPriv);
intelSetSpanFunctions(frontRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
}
if (mesaVis->doubleBufferMode) {
driRenderbuffer *backRb
= driNewRenderbuffer(GL_RGBA,
screen->back.map,
screen->cpp,
screen->back.offset, screen->back.pitch,
driDrawPriv);
intelSetSpanFunctions(backRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
}
if (mesaVis->depthBits == 16) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT16,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
else if (mesaVis->depthBits == 24) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT24,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
if (mesaVis->stencilBits > 0 && !swStencil) {
driRenderbuffer *stencilRb
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
screen->depth.map,
screen->cpp,
screen->depth.offset, screen->depth.pitch,
driDrawPriv);
intelSetSpanFunctions(stencilRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
}
_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
GL_FALSE, /* depth */
swStencil,
mesaVis->accumRedBits > 0,
GL_FALSE, /* alpha */
GL_FALSE /* aux */);
driDrawPriv->driverPrivate = (void *) fb;
return (driDrawPriv->driverPrivate != NULL);
}
}
static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}
/**
* Get information about previous buffer swaps.
*/
static int
intelGetSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
{
struct intel_context *intel;
if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
|| (dPriv->driContextPriv->driverPrivate == NULL)
|| (sInfo == NULL) ) {
return -1;
}
intel = dPriv->driContextPriv->driverPrivate;
sInfo->swap_count = intel->swap_count;
sInfo->swap_ust = intel->swap_ust;
sInfo->swap_missed_count = intel->swap_missed_count;
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
? driCalculateSwapUsage( dPriv, 0, intel->swap_missed_ust )
: 0.0;
return 0;
}
/* There are probably better ways to do this, such as an
* init-designated function to register chipids and createcontext
* functions.
*/
extern GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate)
{
#if 0
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
switch (intelScreen->deviceID) {
case PCI_CHIP_845_G:
case PCI_CHIP_I830_M:
case PCI_CHIP_I855_GM:
case PCI_CHIP_I865_G:
return i830CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
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 );
default:
fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
return GL_FALSE;
}
#else
return brwCreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
#endif
}
static const struct __DriverAPIRec intelAPI = {
.DestroyScreen = intelDestroyScreen,
.CreateContext = intelCreateContext,
.DestroyContext = intelDestroyContext,
.CreateBuffer = intelCreateBuffer,
.DestroyBuffer = intelDestroyBuffer,
.SwapBuffers = intelSwapBuffers,
.MakeCurrent = intelMakeCurrent,
.UnbindContext = intelUnbindContext,
.GetSwapInfo = intelGetSwapInfo,
.GetMSC = driGetMSC32,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
.CopySubBuffer = intelCopySubBuffer
};
static __GLcontextModes *
intelFillInModes( unsigned pixel_bits, unsigned depth_bits,
unsigned stencil_bits, GLboolean have_back_buffer )
{
__GLcontextModes * modes;
__GLcontextModes * m;
unsigned num_modes;
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
GLenum fb_format;
GLenum fb_type;
/* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
* support pageflipping at all.
*/
static const GLenum back_buffer_modes[] = {
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
};
u_int8_t depth_bits_array[3];
u_int8_t stencil_bits_array[3];
depth_bits_array[0] = 0;
depth_bits_array[1] = depth_bits;
depth_bits_array[2] = depth_bits;
/* Just like with the accumulation buffer, always provide some modes
* with a stencil buffer. It will be a sw fallback, but some apps won't
* care about that.
*/
stencil_bits_array[0] = 0;
stencil_bits_array[1] = 0;
stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
back_buffer_factor = (have_back_buffer) ? 3 : 1;
num_modes = depth_buffer_factor * back_buffer_factor * 4;
if ( pixel_bits == 16 ) {
fb_format = GL_RGB;
fb_type = GL_UNSIGNED_SHORT_5_6_5;
}
else {
fb_format = GL_BGRA;
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
m = modes;
if ( ! driFillInModes( & m, fb_format, fb_type,
depth_bits_array, stencil_bits_array, depth_buffer_factor,
back_buffer_modes, back_buffer_factor,
GLX_TRUE_COLOR ) ) {
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
__func__, __LINE__ );
return NULL;
}
if ( ! driFillInModes( & m, fb_format, fb_type,
depth_bits_array, stencil_bits_array, depth_buffer_factor,
back_buffer_modes, back_buffer_factor,
GLX_DIRECT_COLOR ) ) {
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
__func__, __LINE__ );
return NULL;
}
/* Mark the visual as slow if there are "fake" stencil bits.
*/
for ( m = modes ; m != NULL ; m = m->next ) {
if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
m->visualRating = GLX_SLOW_CONFIG;
}
}
return modes;
}
/**
* This is the driver specific part of the createNewScreen entry point.
*
* \todo maybe fold this into intelInitDriver
*
* \return the __GLcontextModes supported by this driver
*/
__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
static const __DRIversion ddx_expected = { 1, 6, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 3, 0 };
I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
psp->DriverAPI = intelAPI;
if ( ! driCheckDriDdxDrmVersions2( "i915",
&psp->dri_version, &dri_expected,
&psp->ddx_version, &ddx_expected,
&psp->drm_version, &drm_expected ) ) {
return NULL;
}
/* Calling driInitExtensions here, with a NULL context pointer,
* does not actually enable the extensions. It just makes sure
* that all the dispatch offsets for all the extensions that
* *might* be enables are known. This is needed because the
* dispatch offsets need to be known when _mesa_context_create is
* called, but we can't enable the extensions until we have a
* context pointer.
*
* Hello chicken. Hello egg. How are you two today?
*/
intelInitExtensions(NULL, GL_FALSE);
if (!intelInitDriver(psp))
return NULL;
return intelFillInModes( dri_priv->cpp * 8,
(dri_priv->cpp == 2) ? 16 : 24,
(dri_priv->cpp == 2) ? 0 : 8,
GL_TRUE );
}

View file

@ -0,0 +1 @@
../intel/intel_screen.c

View file

@ -1,116 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_INIT_H_
#define _INTEL_INIT_H_
#include <sys/time.h>
#include "dri_util.h"
#include "dri_bufmgr.h"
#include "xmlconfig.h"
#include "i830_common.h"
/* XXX: change name or eliminate to avoid conflict with "struct
* intel_region"!!!
*/
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 */
unsigned int bo_handle;
unsigned int tiled;
} intelRegion;
typedef struct
{
intelRegion front;
intelRegion back;
intelRegion rotated;
intelRegion depth;
intelRegion tex;
int deviceID;
int width;
int height;
int mem; /* unused */
int cpp; /* for front and back buffers */
int fbFormat;
int logTextureGranularity;
__DRIscreenPrivate *driScrnPriv;
unsigned int sarea_priv_offset;
int drmMinor;
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
*/
driOptionCache optionCache;
} intelScreenPrivate;
extern GLboolean
intelMapScreenRegions(__DRIscreenPrivate *sPriv);
extern void
intelUnmapScreenRegions(intelScreenPrivate *intelScreen);
extern void
intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen,
volatile drmI830Sarea *sarea);
extern void
intelDestroyContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelUnbindContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
extern void
intelSwapBuffers(__DRIdrawablePrivate *dPriv);
extern void
intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
int x, int y, int w, int h );
#endif

View file

@ -1,299 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "colormac.h"
#include "intel_screen.h"
#include "intel_regions.h"
#include "intel_span.h"
#include "intel_ioctl.h"
#include "intel_tex.h"
#include "intel_batchbuffer.h"
#include "swrast/swrast.h"
#undef DBG
#define DBG 0
#define LOCAL_VARS \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *) drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch; \
GLushort p; \
(void) buf; (void) p
#define LOCAL_DEPTH_VARS \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *) drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
#define INIT_MONO_PIXEL(p,color)\
p = INTEL_PACKCOLOR565(color[0],color[1],color[2])
#define Y_FLIP(_y) (height - _y - 1)
#define HW_LOCK()
#define HW_UNLOCK()
/* 16 bit, 565 rgb color spanline and pixel functions
*/
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \
(((int)g & 0xfc) << 3) | \
(((int)b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
rgba[3] = 255; \
} while(0)
#define TAG(x) intel##x##_565
#include "spantmp.h"
/* 15 bit, 555 rgb color spanline and pixel functions
*/
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
((g & 0xf8) << 3) | \
((b & 0xf8) >> 3))
#define WRITE_PIXEL( _x, _y, p ) \
*(GLushort *)(buf + _x*2 + _y*pitch) = p
#define READ_RGBA( rgba, _x, _y ) \
do { \
GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
rgba[0] = (p >> 7) & 0xf8; \
rgba[1] = (p >> 3) & 0xf8; \
rgba[2] = (p << 3) & 0xf8; \
rgba[3] = 255; \
} while(0)
#define TAG(x) intel##x##_555
#include "spantmp.h"
/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
#define TAG(x) intel##x##_z16
#include "depthtmp.h"
#undef LOCAL_VARS
#define LOCAL_VARS \
struct intel_context *intel = intel_context(ctx); \
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint pitch = drb->pitch; \
GLuint height = dPriv->h; \
char *buf = (char *)drb->Base.Data + \
dPriv->x * drb->cpp + \
dPriv->y * pitch; \
GLuint p; \
(void) buf; (void) p
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p,color)\
p = INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3])
/* 32 bit, 8888 argb color spanline and pixel functions
*/
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
(g << 8) | \
(b << 0) | \
(a << 24) )
#define WRITE_PIXEL(_x, _y, p) \
*(GLuint *)(buf + _x*4 + _y*pitch) = p
#define READ_RGBA(rgba, _x, _y) \
do { \
GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = (p >> 24) & 0xff; \
} while (0)
#define TAG(x) intel##x##_8888
#include "spantmp.h"
/* 24/8 bit interleaved depth/stencil functions
*/
#define WRITE_DEPTH( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xff000000; \
tmp |= (d) & 0xffffff; \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
}
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff;
#define TAG(x) intel##x##_z24_s8
#include "depthtmp.h"
#define WRITE_STENCIL( _x, _y, d ) { \
GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \
tmp &= 0xffffff; \
tmp |= ((d)<<24); \
*(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \
}
#define READ_STENCIL( d, _x, _y ) \
d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24;
#define TAG(x) intel##x##_z24_s8
#include "stenciltmp.h"
/* Move locking out to get reasonable span performance.
*/
void intelSpanRenderStart( GLcontext *ctx )
{
struct intel_context *intel = intel_context(ctx);
int i;
if (intel->need_flush) {
LOCK_HARDWARE(intel);
intel->vtbl.emit_flush(intel, 0);
intel_batchbuffer_flush(intel->batch);
intel->need_flush = 0;
UNLOCK_HARDWARE(intel);
intelFinish(&intel->ctx);
}
LOCK_HARDWARE(intel);
/* Just map the framebuffer and all textures. Bufmgr code will
* take care of waiting on the necessary fences:
*/
intel_region_map(intel, intel->front_region);
intel_region_map(intel, intel->back_region);
intel_region_map(intel, intel->depth_region);
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
intel_tex_map_images(intel, intel_texture_object(texObj));
}
}
}
void intelSpanRenderFinish( GLcontext *ctx )
{
struct intel_context *intel = intel_context( ctx );
int i;
_swrast_flush( ctx );
/* Now unmap the framebuffer:
*/
intel_region_unmap(intel, intel->front_region);
intel_region_unmap(intel, intel->back_region);
intel_region_unmap(intel, intel->depth_region);
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled) {
struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
intel_tex_unmap_images(intel, intel_texture_object(texObj));
}
}
UNLOCK_HARDWARE( intel );
}
void intelInitSpanFuncs( GLcontext *ctx )
{
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SpanRenderStart = intelSpanRenderStart;
swdd->SpanRenderFinish = intelSpanRenderFinish;
}
/**
* Plug in the Get/Put routines for the given driRenderbuffer.
*/
void
intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
{
if (drb->Base.InternalFormat == GL_RGBA) {
if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
intelInitPointers_555(&drb->Base);
}
else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
intelInitPointers_565(&drb->Base);
}
else {
assert(vis->redBits == 8);
assert(vis->greenBits == 8);
assert(vis->blueBits == 8);
intelInitPointers_8888(&drb->Base);
}
}
else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
intelInitDepthPointers_z16(&drb->Base);
}
else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
intelInitDepthPointers_z24_s8(&drb->Base);
}
else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
intelInitStencilPointers_z24_s8(&drb->Base);
}
}

View file

@ -0,0 +1 @@
../intel/intel_span.c

View file

@ -1,41 +0,0 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _INTEL_SPAN_H
#define _INTEL_SPAN_H
#include "drirenderbuffer.h"
extern void intelInitSpanFuncs( GLcontext *ctx );
extern void intelSpanRenderFinish( GLcontext *ctx );
extern void intelSpanRenderStart( GLcontext *ctx );
extern void
intelSetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis);
#endif

View file

@ -195,15 +195,16 @@ int intel_translate_logic_op( GLenum opcode )
static void intelClearColor(GLcontext *ctx, const GLfloat color[4])
{
struct intel_context *intel = intel_context(ctx);
intelScreenPrivate *screen = intel->intelScreen;
UNCLAMPED_FLOAT_TO_RGBA_CHAN(intel->clear_chan, color);
intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat,
intel->clear_chan[0],
intel->clear_chan[1],
intel->clear_chan[2],
intel->clear_chan[3]);
intel->ClearColor8888 = INTEL_PACKCOLOR8888(intel->clear_chan[0],
intel->clear_chan[1],
intel->clear_chan[2],
intel->clear_chan[3]);
intel->ClearColor565 = INTEL_PACKCOLOR565(intel->clear_chan[0],
intel->clear_chan[1],
intel->clear_chan[2]);
}

View file

@ -0,0 +1 @@
../intel/intel_tex_copy.c

View file

@ -536,3 +536,77 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
UNLOCK_HARDWARE(intel);
}
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
GLuint fg_color,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLenum logic_op)
{
int dwords = ALIGN(src_size, 8) / 4;
uint32_t opcode, br13, blit_cmd;
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
if (w < 0 || h < 0)
return;
dst_pitch *= cpp;
if (dst_tiled)
dst_pitch /= 4;
DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
__FUNCTION__,
dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
intel_batchbuffer_require_space( intel->batch,
(8 * 4) +
(3 * 4) +
dwords,
INTEL_BATCH_NO_CLIPRECTS );
opcode = XY_SETUP_BLT_CMD;
if (cpp == 4)
opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
if (dst_tiled)
opcode |= XY_DST_TILED;
br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
if (cpp == 2)
br13 |= BR13_565;
else
br13 |= BR13_8888;
blit_cmd = XY_TEXT_IMMEDIATE_BLIT_CMD | XY_TEXT_BYTE_PACKED; /* packing? */
if (dst_tiled)
blit_cmd |= XY_DST_TILED;
BEGIN_BATCH(8 + 3, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(opcode);
OUT_BATCH(br13);
OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset);
OUT_BATCH(0); /* bg */
OUT_BATCH(fg_color); /* fg */
OUT_BATCH(0); /* pattern base addr */
OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w));
ADVANCE_BATCH();
intel_batchbuffer_data( intel->batch,
src_bits,
dwords * 4,
INTEL_BATCH_NO_CLIPRECTS );
}

View file

@ -61,5 +61,17 @@ extern void intelEmitFillBlit(struct intel_context *intel,
GLshort x, GLshort y,
GLshort w, GLshort h, GLuint color);
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLuint cpp,
GLubyte *src_bits, GLuint src_size,
GLuint fg_color,
GLshort dst_pitch,
dri_bo *dst_buffer,
GLuint dst_offset,
GLboolean dst_tiled,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLenum logic_op);
#endif

View file

@ -1,4 +1,4 @@
/**************************************************************************
/**************************************************************************
*
* Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.

View file

@ -29,6 +29,7 @@
#include "intel_context.h"
#include "intel_blit.h"
#include "intel_buffers.h"
#include "intel_chipset.h"
#include "intel_depthstencil.h"
#include "intel_fbo.h"
#include "intel_regions.h"
@ -40,7 +41,7 @@
#include "framebuffer.h"
#include "swrast/swrast.h"
#include "vblank.h"
#include "i915_drm.h"
/* This block can be removed when libdrm >= 2.3.1 is required */
@ -196,6 +197,77 @@ intelSetBackClipRects(struct intel_context *intel)
}
}
#ifdef I915
static void
intelUpdatePageFlipping(struct intel_context *intel,
GLint areaA, GLint areaB)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
GLboolean pf_active;
GLint pf_planes;
/* Update page flipping info */
pf_planes = 0;
if (areaA > 0)
pf_planes |= 1;
if (areaB > 0)
pf_planes |= 2;
intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
(intel_fb->pf_planes & 0x2)) & 0x3;
intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;
pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes;
if (INTEL_DEBUG & DEBUG_LOCK)
if (pf_active != intel_fb->pf_active)
_mesa_printf("%s - Page flipping %sactive\n", __progname,
pf_active ? "" : "in");
if (pf_active) {
/* Sync pages between planes if flipping on both at the same time */
if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes &&
(intel->sarea->pf_current_page & 0x3) !=
(((intel->sarea->pf_current_page) >> 2) & 0x3)) {
drm_i915_flip_t flip;
if (intel_fb->pf_current_page ==
(intel->sarea->pf_current_page & 0x3)) {
/* XXX: This is ugly, but emitting two flips 'in a row' can cause
* lockups for unknown reasons.
*/
intel->sarea->pf_current_page =
intel->sarea->pf_current_page & 0x3;
intel->sarea->pf_current_page |=
((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
intel_fb->pf_num_pages) << 2;
flip.pipes = 0x2;
} else {
intel->sarea->pf_current_page =
intel->sarea->pf_current_page & (0x3 << 2);
intel->sarea->pf_current_page |=
(intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
intel_fb->pf_num_pages;
flip.pipes = 0x1;
}
drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
}
intel_fb->pf_planes = pf_planes;
}
intel_fb->pf_active = pf_active;
intel_flip_renderbuffers(intel_fb);
intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
}
#endif /* I915 */
/**
* This will be called whenever the currently bound window is moved/resized.
@ -232,7 +304,7 @@ intelWindowMoved(struct intel_context *intel)
}
if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
drmI830Sarea *sarea = intel->sarea;
volatile drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
.y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
@ -244,69 +316,10 @@ intelWindowMoved(struct intel_context *intel)
GLint areaA = driIntersectArea( drw_rect, planeA_rect );
GLint areaB = driIntersectArea( drw_rect, planeB_rect );
GLuint flags = dPriv->vblFlags;
GLboolean pf_active;
GLint pf_planes;
/* Update page flipping info
*/
pf_planes = 0;
if (areaA > 0)
pf_planes |= 1;
if (areaB > 0)
pf_planes |= 2;
intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
(intel_fb->pf_planes & 0x2)) & 0x3;
intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;
pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes;
if (INTEL_DEBUG & DEBUG_LOCK)
if (pf_active != intel_fb->pf_active)
_mesa_printf("%s - Page flipping %sactive\n", __progname,
pf_active ? "" : "in");
if (pf_active) {
/* Sync pages between planes if flipping on both at the same time */
if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes &&
(intel->sarea->pf_current_page & 0x3) !=
(((intel->sarea->pf_current_page) >> 2) & 0x3)) {
drm_i915_flip_t flip;
if (intel_fb->pf_current_page ==
(intel->sarea->pf_current_page & 0x3)) {
/* XXX: This is ugly, but emitting two flips 'in a row' can cause
* lockups for unknown reasons.
*/
intel->sarea->pf_current_page =
intel->sarea->pf_current_page & 0x3;
intel->sarea->pf_current_page |=
((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
intel_fb->pf_num_pages) << 2;
flip.pipes = 0x2;
} else {
intel->sarea->pf_current_page =
intel->sarea->pf_current_page & (0x3 << 2);
intel->sarea->pf_current_page |=
(intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
intel_fb->pf_num_pages;
flip.pipes = 0x1;
}
drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
}
intel_fb->pf_planes = pf_planes;
}
intel_fb->pf_active = pf_active;
intel_flip_renderbuffers(intel_fb);
intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
#ifdef I915
intelUpdatePageFlipping(intel, areaA, areaB);
#endif
/* Update vblank info
*/
@ -523,8 +536,12 @@ intelClear(GLcontext *ctx, GLbitfield mask)
= intel_get_rb_region(fb, BUFFER_STENCIL);
if (stencilRegion) {
/* have hw stencil */
if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* not clearing all stencil bits, so use triangle clearing */
if (IS_965(intel->intelScreen->deviceID) ||
(ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
/* We have to use the 3D engine if we're clearing a partial mask
* of the stencil buffer, or if we're on a 965 which has a tiled
* depth/stencil buffer in a layout we can't blit to.
*/
tri_mask |= BUFFER_BIT_STENCIL;
}
else {
@ -537,7 +554,8 @@ intelClear(GLcontext *ctx, GLbitfield mask)
/* HW depth */
if (mask & BUFFER_BIT_DEPTH) {
/* clear depth with whatever method is used for stencil (see above) */
if (tri_mask & BUFFER_BIT_STENCIL)
if (IS_965(intel->intelScreen->deviceID) ||
tri_mask & BUFFER_BIT_STENCIL)
tri_mask |= BUFFER_BIT_DEPTH;
else
blit_mask |= BUFFER_BIT_DEPTH;
@ -632,6 +650,7 @@ intel_wait_flips(struct intel_context *intel, GLuint batch_flags)
static GLboolean
intelPageFlip(const __DRIdrawablePrivate * dPriv)
{
#ifdef I915
struct intel_context *intel;
int ret;
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
@ -684,6 +703,9 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
intel_draw_buffer(&intel->ctx, &intel_fb->Base);
return GL_TRUE;
#else
return GL_FALSE;
#endif
}
#if 0

View file

@ -493,7 +493,8 @@ intel_bind_framebuffer(GLcontext * ctx, GLenum target,
if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
intel_draw_buffer(ctx, fb);
/* Integer depth range depends on depth buffer bits */
ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far);
if (ctx->Driver.DepthRange != NULL)
ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far);
}
else {
/* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */

View file

@ -61,6 +61,9 @@
#define XY_SRC_COPY_BLT_CMD (CMD_2D | (0x53 << 22) | 6)
#define XY_TEXT_IMMEDIATE_BLIT_CMD (CMD_2D | (0x31 << 22))
# define XY_TEXT_BYTE_PACKED (1 << 16)
/* BR00 */
#define XY_BLT_WRITE_ALPHA (1 << 21)
#define XY_BLT_WRITE_RGB (1 << 20)

View file

@ -43,7 +43,9 @@
#include "intel_span.h"
#include "intel_ioctl.h"
#include "intel_fbo.h"
#include "intel_chipset.h"
#include "i915_drm.h"
#include "i830_dri.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
@ -570,9 +572,9 @@ extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis,
extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
static GLboolean
intelCreateContext(const __GLcontextModes * mesaVis,
@ -582,29 +584,21 @@ intelCreateContext(const __GLcontextModes * mesaVis,
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
switch (intelScreen->deviceID) {
/* Don't deal with i830 until texture work complete:
*/
case PCI_CHIP_845_G:
case PCI_CHIP_I830_M:
case PCI_CHIP_I855_GM:
case PCI_CHIP_I865_G:
#ifdef I915
if (IS_9XX(intelScreen->deviceID)) {
if (!IS_965(intelScreen->deviceID)) {
return i915CreateContext(mesaVis, driContextPriv,
sharedContextPrivate);
}
} else {
return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
case PCI_CHIP_I945_G:
case PCI_CHIP_I945_GM:
case PCI_CHIP_I945_GME:
case PCI_CHIP_G33_G:
case PCI_CHIP_Q35_G:
case PCI_CHIP_Q33_G:
return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
default:
fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
return GL_FALSE;
}
#else
if (IS_965(intelScreen->deviceID))
return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate);
#endif
fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
return GL_FALSE;
}
@ -624,7 +618,9 @@ static const struct __DriverAPIRec intelAPI = {
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL,
.CopySubBuffer = intelCopySubBuffer,
#ifdef I915
.setTexOffset = intelSetTexOffset,
#endif
};
@ -722,7 +718,11 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
*/
PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
#ifdef I915
static const __DRIversion ddx_expected = { 1, 5, 0 };
#else
static const __DRIversion ddx_expected = { 1, 6, 0 };
#endif
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 5, 0 };
I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;