Turn back on some fallback cases. Turn back on the unclipped rastersetup-to-dma render path.tags/texman_0_1_20060325
@@ -5,7 +5,15 @@ include $(TOP)/configs/current | |||
LIBNAME = i915_dri.so | |||
DRIVER_SOURCES = \ | |||
i830_context.c \ | |||
i830_metaops.c \ | |||
i830_state.c \ | |||
i830_texblend.c \ | |||
i830_tex.c \ | |||
i830_texstate.c \ | |||
i830_vtbl.c \ | |||
bufmgr_fake.c \ | |||
intel_render.c \ | |||
intel_regions.c \ | |||
intel_buffer_objects.c \ | |||
intel_batchbuffer.c \ | |||
@@ -41,15 +49,6 @@ DRIVER_SOURCES = \ | |||
intel_tris.c | |||
DISABLED = \ | |||
intel_render.c \ | |||
i830_context.c \ | |||
i830_metaops.c \ | |||
i830_state.c \ | |||
i830_texblend.c \ | |||
i830_tex.c \ | |||
i830_texstate.c \ | |||
i830_vtbl.c | |||
C_SOURCES = \ | |||
$(COMMON_SOURCES) \ |
@@ -58,7 +58,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, | |||
void *sharedContextPrivate) | |||
{ | |||
struct dd_function_table functions; | |||
i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context); | |||
struct i830_context *i830 = CALLOC_STRUCT(i830_context); | |||
struct intel_context *intel = &i830->intel; | |||
GLcontext *ctx = &intel->ctx; | |||
if (!i830) return GL_FALSE; | |||
@@ -76,33 +76,14 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, | |||
intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; | |||
intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; | |||
intel->nr_heaps = 1; | |||
intel->texture_heaps[0] = | |||
driCreateTextureHeap( 0, intel, | |||
intel->intelScreen->tex.size, | |||
12, | |||
I830_NR_TEX_REGIONS, | |||
intel->sarea->texList, | |||
& intel->sarea->texAge, | |||
& intel->swapped, | |||
sizeof( struct i830_texture_object ), | |||
(destroy_texture_object_t *)intelDestroyTexObj ); | |||
/* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly | |||
* FIXME: packed, but they're not in Intel graphics hardware. | |||
/* Advertise the full hardware capabilities. The new memory | |||
* manager should cope much better with overload situations: | |||
*/ | |||
intel->ctx.Const.MaxTextureUnits = 1; | |||
driCalculateMaxTextureLevels( intel->texture_heaps, | |||
intel->nr_heaps, | |||
&intel->ctx.Const, | |||
4, | |||
11, /* max 2D texture size is 2048x2048 */ | |||
8, /* max 3D texture size is 256^3 */ | |||
10, /* max CUBE texture size is 1024x1024 */ | |||
11, /* max RECT. supported */ | |||
12, | |||
GL_FALSE ); | |||
intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; | |||
ctx->Const.MaxTextureLevels = 12; | |||
ctx->Const.Max3DTextureLevels = 9; | |||
ctx->Const.MaxCubeTextureLevels = 11; | |||
ctx->Const.MaxTextureRectSize = (1<<11); | |||
ctx->Const.MaxTextureUnits = I830_TEX_UNITS; | |||
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, | |||
18 * sizeof(GLfloat) ); | |||
@@ -112,7 +93,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, | |||
driInitExtensions( ctx, i830_extensions, GL_FALSE ); | |||
i830InitState( i830 ); | |||
i830InitMetaFuncs( i830 ); | |||
_tnl_allow_vertex_fog( ctx, 1 ); | |||
_tnl_allow_pixel_fog( ctx, 0 ); |
@@ -39,6 +39,7 @@ | |||
#define I830_UPLOAD_CTX 0x1 | |||
#define I830_UPLOAD_BUFFERS 0x2 | |||
#define I830_UPLOAD_STIPPLE 0x4 | |||
#define I830_UPLOAD_INVARIENT 0x8 | |||
#define I830_UPLOAD_TEX(i) (0x10<<(i)) | |||
#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) | |||
#define I830_UPLOAD_TEX_ALL (0x0f0) | |||
@@ -48,15 +49,15 @@ | |||
*/ | |||
#define I830_DESTREG_CBUFADDR0 0 | |||
#define I830_DESTREG_CBUFADDR1 1 | |||
#define I830_DESTREG_DBUFADDR0 3 | |||
#define I830_DESTREG_DBUFADDR1 4 | |||
#define I830_DESTREG_DV0 6 | |||
#define I830_DESTREG_DV1 7 | |||
#define I830_DESTREG_SENABLE 8 | |||
#define I830_DESTREG_SR0 9 | |||
#define I830_DESTREG_SR1 10 | |||
#define I830_DESTREG_SR2 11 | |||
#define I830_DEST_SETUP_SIZE 12 | |||
#define I830_DESTREG_DBUFADDR0 2 | |||
#define I830_DESTREG_DBUFADDR1 3 | |||
#define I830_DESTREG_DV0 4 | |||
#define I830_DESTREG_DV1 5 | |||
#define I830_DESTREG_SENABLE 6 | |||
#define I830_DESTREG_SR0 7 | |||
#define I830_DESTREG_SR1 8 | |||
#define I830_DESTREG_SR2 9 | |||
#define I830_DEST_SETUP_SIZE 10 | |||
#define I830_CTXREG_STATE1 0 | |||
#define I830_CTXREG_STATE2 1 | |||
@@ -82,14 +83,13 @@ | |||
#define I830_STP_SETUP_SIZE 2 | |||
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ | |||
#define I830_TEXREG_TM0S0 1 | |||
#define I830_TEXREG_TM0S1 2 | |||
#define I830_TEXREG_TM0S2 3 | |||
#define I830_TEXREG_TM0S3 4 | |||
#define I830_TEXREG_TM0S4 5 | |||
#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */ | |||
#define I830_TEXREG_CUBE 7 /* _3DSTATE_MAP_SUBE */ | |||
#define I830_TEX_SETUP_SIZE 8 | |||
#define I830_TEXREG_TM0S1 1 | |||
#define I830_TEXREG_TM0S2 2 | |||
#define I830_TEXREG_TM0S3 3 | |||
#define I830_TEXREG_TM0S4 4 | |||
#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ | |||
#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ | |||
#define I830_TEX_SETUP_SIZE 7 | |||
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ | |||
@@ -108,6 +108,17 @@ struct i830_hw_state { | |||
GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; | |||
GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; | |||
GLuint TexBlendWordsUsed[I830_TEX_UNITS]; | |||
struct intel_region *draw_region; | |||
struct intel_region *depth_region; | |||
/* Regions aren't actually that appropriate here as the memory may | |||
* be from a PBO or FBO. Just use the buffer id. Will have to do | |||
* this for draw and depth for FBO's... | |||
*/ | |||
GLuint tex_buffer[I830_TEX_UNITS]; | |||
GLuint tex_offset[I830_TEX_UNITS]; | |||
GLuint emitted; /* I810_UPLOAD_* */ | |||
GLuint active; | |||
}; | |||
@@ -116,15 +127,12 @@ struct i830_context | |||
{ | |||
struct intel_context intel; | |||
GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; | |||
GLuint last_index; | |||
struct i830_hw_state meta, initial, state, *current; | |||
}; | |||
typedef struct i830_context *i830ContextPtr; | |||
typedef struct i830_texture_object *i830TextureObjectPtr; | |||
#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx)) | |||
@@ -146,7 +154,7 @@ do { \ | |||
/* i830_vtbl.c | |||
*/ | |||
extern void | |||
i830InitVtbl( i830ContextPtr i830 ); | |||
i830InitVtbl( struct i830_context *i830 ); | |||
/* i830_context.c | |||
*/ | |||
@@ -163,17 +171,14 @@ i830UpdateTextureState( struct intel_context *intel ); | |||
extern void | |||
i830InitTextureFuncs( struct dd_function_table *functions ); | |||
extern intelTextureObjectPtr | |||
i830AllocTexObj( struct gl_texture_object *tObj ); | |||
/* i830_texblend.c | |||
*/ | |||
extern GLuint i830SetTexEnvCombine(i830ContextPtr i830, | |||
extern GLuint i830SetTexEnvCombine(struct i830_context *i830, | |||
const struct gl_tex_env_combine_state * combine, GLint blendUnit, | |||
GLuint texel_op, GLuint *state, const GLfloat *factor ); | |||
extern void | |||
i830EmitTextureBlend( i830ContextPtr i830 ); | |||
i830EmitTextureBlend( struct i830_context *i830 ); | |||
/* i830_state.c | |||
@@ -182,32 +187,25 @@ extern void | |||
i830InitStateFuncs( struct dd_function_table *functions ); | |||
extern void | |||
i830EmitState( i830ContextPtr i830 ); | |||
i830EmitState( struct i830_context *i830 ); | |||
extern void | |||
i830InitState( i830ContextPtr i830 ); | |||
i830InitState( struct i830_context *i830 ); | |||
/* i830_metaops.c | |||
*/ | |||
extern GLboolean | |||
i830TryTextureReadPixels( GLcontext *ctx, | |||
GLint x, GLint y, GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *pack, | |||
GLvoid *pixels ); | |||
extern GLboolean | |||
i830TryTextureDrawPixels( GLcontext *ctx, | |||
GLint x, GLint y, GLsizei width, GLsizei height, | |||
GLenum format, GLenum type, | |||
const struct gl_pixelstore_attrib *unpack, | |||
const GLvoid *pixels ); | |||
extern void | |||
i830ClearWithTris( struct intel_context *intel, GLbitfield mask, | |||
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); | |||
i830InitMetaFuncs( struct i830_context *i830 ); | |||
/*====================================================================== | |||
* Inline conversion functions. These are better-typed than the | |||
* macros used previously: | |||
*/ | |||
static inline struct i830_context * | |||
i830_context( GLcontext *ctx ) | |||
{ | |||
return (struct i830_context *)ctx; | |||
} | |||
#endif | |||
@@ -34,13 +34,15 @@ | |||
#include "intel_screen.h" | |||
#include "intel_batchbuffer.h" | |||
#include "intel_ioctl.h" | |||
#include "intel_regions.h" | |||
#include "i830_context.h" | |||
#include "i830_reg.h" | |||
/* A large amount of state doesn't need to be uploaded. | |||
*/ | |||
#define ACTIVE (I830_UPLOAD_TEXBLEND(0) | \ | |||
#define ACTIVE (I830_UPLOAD_INVARIENT | \ | |||
I830_UPLOAD_TEXBLEND(0) | \ | |||
I830_UPLOAD_STIPPLE | \ | |||
I830_UPLOAD_CTX | \ | |||
I830_UPLOAD_BUFFERS | \ | |||
@@ -54,20 +56,11 @@ do { \ | |||
i830->current->emitted &= ~ACTIVE; \ | |||
} while (0) | |||
/* Operations where the 3D engine is decoupled temporarily from the | |||
* current GL state and used for other purposes than simply rendering | |||
* incoming triangles. | |||
*/ | |||
static void set_initial_state( struct intel_context *intel ) | |||
{ | |||
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); | |||
i830->meta.active = ACTIVE; | |||
i830->meta.emitted = 0; | |||
} | |||
static void set_no_depth_stencil_write( struct intel_context *intel ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) | |||
*/ | |||
i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; | |||
@@ -92,6 +85,8 @@ static void set_stencil_replace( struct intel_context *intel, | |||
GLuint s_mask, | |||
GLuint s_clear) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) | |||
*/ | |||
i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; | |||
@@ -142,6 +137,8 @@ static void set_stencil_replace( struct intel_context *intel, | |||
static void set_color_mask( struct intel_context *intel, GLboolean state ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | | |||
(1 << WRITEMASK_GREEN_SHIFT) | | |||
(1 << WRITEMASK_BLUE_SHIFT) | | |||
@@ -163,6 +160,7 @@ static void set_color_mask( struct intel_context *intel, GLboolean state ) | |||
*/ | |||
static void set_no_texture( struct intel_context *intel ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
static const struct gl_tex_env_combine_state comb = { | |||
GL_NONE, GL_NONE, | |||
{ GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, | |||
@@ -181,9 +179,9 @@ static void set_no_texture( struct intel_context *intel ) | |||
/* Set up a single element blend stage for 'replace' texturing with no | |||
* funny ops. | |||
*/ | |||
static void enable_texture_blend_replace( struct intel_context *intel, | |||
GLenum format ) | |||
static void set_texture_blend_replace( struct intel_context *intel ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
static const struct gl_tex_env_combine_state comb = { | |||
GL_REPLACE, GL_REPLACE, | |||
{ GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, | |||
@@ -207,28 +205,80 @@ static void enable_texture_blend_replace( struct intel_context *intel, | |||
/* Set up an arbitary piece of memory as a rectangular texture | |||
* (including the front or back buffer). | |||
*/ | |||
static void set_tex_rect_source( struct intel_context *intel, | |||
GLuint offset, | |||
GLuint width, | |||
GLuint height, | |||
GLuint pitch, | |||
GLuint textureFormat ) | |||
static GLboolean set_tex_rect_source( struct intel_context *intel, | |||
GLuint buffer, | |||
GLuint offset, | |||
GLuint pitch, | |||
GLuint height, | |||
GLenum format, | |||
GLenum type) | |||
{ | |||
GLint numLevels = 1; | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
GLuint *setup = i830->meta.Tex[0]; | |||
GLint numLevels = 1; | |||
GLuint textureFormat; | |||
GLuint cpp; | |||
pitch *= i830->intel.intelScreen->cpp; | |||
/* A full implementation of this would do the upload through | |||
* glTexImage2d, and get all the conversion operations at that | |||
* point. We are restricted, but still at least have access to the | |||
* fragment program swizzle. | |||
*/ | |||
switch (format) { | |||
case GL_BGRA: | |||
switch (type) { | |||
case GL_UNSIGNED_INT_8_8_8_8_REV: | |||
case GL_UNSIGNED_BYTE: | |||
textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); | |||
cpp = 4; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
break; | |||
case GL_RGBA: | |||
switch (type) { | |||
case GL_UNSIGNED_INT_8_8_8_8_REV: | |||
case GL_UNSIGNED_BYTE: | |||
textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); | |||
cpp = 4; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
break; | |||
case GL_BGR: | |||
switch (type) { | |||
case GL_UNSIGNED_SHORT_5_6_5_REV: | |||
textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); | |||
cpp = 2; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
break; | |||
case GL_RGB: | |||
switch (type) { | |||
case GL_UNSIGNED_SHORT_5_6_5: | |||
textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); | |||
cpp = 2; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ | |||
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ | |||
setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | | |||
(LOAD_TEXTURE_MAP0 << 0) | 4); | |||
setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset); | |||
setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | | |||
((width - 1) << TM0S1_WIDTH_SHIFT) | | |||
((pitch - 1) << TM0S1_WIDTH_SHIFT) | | |||
textureFormat); | |||
setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); | |||
setup[I830_TEXREG_TM0S2] = (((((pitch * cpp) / 4) - 1) << TM0S2_PITCH_SHIFT)); | |||
setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; | |||
setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; | |||
setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; | |||
@@ -244,46 +294,131 @@ static void set_tex_rect_source( struct intel_context *intel, | |||
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); | |||
i830->meta.emitted &= ~I830_UPLOAD_TEX(0); | |||
return GL_TRUE; | |||
} | |||
/* Select between front and back draw buffers. | |||
*/ | |||
static void set_draw_offset( struct intel_context *intel, | |||
GLuint offset ) | |||
static void set_vertex_format( struct intel_context *intel ) | |||
{ | |||
/* i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | | |||
VFT0_TEX_COUNT(1) | | |||
VFT0_DIFFUSE | | |||
VFT0_SPEC | | |||
VFT0_XYZW); | |||
i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | | |||
VFT1_TEX0_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX1_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX2_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX3_FMT(TEXCOORDFMT_2D)); | |||
i830->meta.emitted &= ~I830_UPLOAD_CTX; | |||
} | |||
static void meta_import_pixel_state( struct intel_context *intel ) | |||
{ | |||
#if 0 | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
memcpy(i830->meta.Fog, i830->state.Fog, I830_FOG_SETUP_SIZE * 4); | |||
i830->meta.Ctx[I830_CTXREG_LIS5] = i830->state.Ctx[I830_CTXREG_LIS5]; | |||
i830->meta.Ctx[I830_CTXREG_LIS6] = i830->state.Ctx[I830_CTXREG_LIS6]; | |||
i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; | |||
i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; | |||
i830->meta.Ctx[I830_CTXREG_IAB] = i830->state.Ctx[I830_CTXREG_IAB]; | |||
i830->meta.Buffer[I830_DESTREG_SENABLE] = i830->state.Buffer[I830_DESTREG_SENABLE]; | |||
i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; | |||
i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; | |||
i830->meta.emitted &= ~I830_UPLOAD_FOG; | |||
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; | |||
i830->meta.emitted &= ~I830_UPLOAD_CTX; | |||
#endif | |||
} | |||
/* Setup an arbitary draw format, useful for targeting | |||
* texture or agp memory. | |||
/* Select between front and back draw buffers. | |||
*/ | |||
static void set_draw_format( struct intel_context *intel, | |||
GLuint format, | |||
GLuint depth_format) | |||
static void meta_draw_region( struct intel_context *intel, | |||
struct intel_region *draw_region, | |||
struct intel_region *depth_region ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
GLuint format; | |||
GLuint depth_format = DEPTH_FRMT_16_FIXED; | |||
intel_region_release(intel, &i830->meta.draw_region); | |||
intel_region_reference(&i830->meta.draw_region, draw_region); | |||
intel_region_release(intel, &i830->meta.depth_region); | |||
intel_region_reference(&i830->meta.depth_region, depth_region); | |||
/* XXX: 555 support? | |||
*/ | |||
if (draw_region->cpp == 2) | |||
format = DV_PF_565; | |||
else | |||
format = DV_PF_8888; | |||
if (depth_region) { | |||
if (depth_region->cpp == 2) | |||
depth_format = DEPTH_FRMT_16_FIXED; | |||
else | |||
depth_format = DEPTH_FRMT_24_FIXED_8_OTHER; | |||
} | |||
i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ | |||
DSTORG_VERT_BIAS(0x8) | /* .5 */ | |||
format | | |||
DEPTH_IS_Z | | |||
depth_format); | |||
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; | |||
} | |||
static void set_vertex_format( struct intel_context *intel ) | |||
/* Operations where the 3D engine is decoupled temporarily from the | |||
* current GL state and used for other purposes than simply rendering | |||
* incoming triangles. | |||
*/ | |||
static void install_meta_state( struct intel_context *intel ) | |||
{ | |||
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | | |||
VFT0_TEX_COUNT(1) | | |||
VFT0_DIFFUSE | | |||
VFT0_SPEC | | |||
VFT0_XYZW); | |||
i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | | |||
VFT1_TEX0_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX1_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX2_FMT(TEXCOORDFMT_2D) | | |||
VFT1_TEX3_FMT(TEXCOORDFMT_2D)); | |||
i830->meta.emitted &= ~I830_UPLOAD_CTX; | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); | |||
i830->meta.active = ACTIVE; | |||
i830->meta.emitted = 0; | |||
SET_STATE(i830, meta); | |||
set_vertex_format(intel); | |||
set_no_texture(intel); | |||
} | |||
static void leave_meta_state( struct intel_context *intel ) | |||
{ | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
intel_region_release(intel, &i830->meta.draw_region); | |||
intel_region_release(intel, &i830->meta.depth_region); | |||
/* intel_region_release(intel, &i830->meta.tex_region[0]); */ | |||
SET_STATE(i830, state); | |||
} | |||
void i830InitMetaFuncs( struct i830_context *i830 ) | |||
{ | |||
i830->intel.vtbl.install_meta_state = install_meta_state; | |||
i830->intel.vtbl.leave_meta_state = leave_meta_state; | |||
i830->intel.vtbl.meta_no_depth_stencil_write = set_no_depth_stencil_write; | |||
i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; | |||
i830->intel.vtbl.meta_color_mask = set_color_mask; | |||
i830->intel.vtbl.meta_no_texture = set_no_texture; | |||
i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; | |||
i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; | |||
i830->intel.vtbl.meta_draw_region = meta_draw_region; | |||
i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; | |||
} | |||
@@ -44,7 +44,7 @@ static void | |||
i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, | |||
GLuint mask) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int test = intel_translate_compare_func(func); | |||
mask = mask & 0xff; | |||
@@ -69,7 +69,7 @@ i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, | |||
static void | |||
i830StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); | |||
@@ -86,7 +86,7 @@ static void | |||
i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, | |||
GLenum zpass) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int fop, dfop, dpop; | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -193,7 +193,7 @@ i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, | |||
static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int test = intel_translate_compare_func(func); | |||
GLubyte refByte; | |||
GLuint refInt; | |||
@@ -221,7 +221,7 @@ static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) | |||
*/ | |||
static void i830EvalLogicOpBlendState(GLcontext *ctx) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
I830_STATECHANGE(i830, I830_UPLOAD_CTX); | |||
@@ -245,7 +245,7 @@ static void i830EvalLogicOpBlendState(GLcontext *ctx) | |||
static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
GLubyte r, g, b, a; | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -268,7 +268,7 @@ static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) | |||
*/ | |||
static void i830_set_blend_state( GLcontext * ctx ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int funcA; | |||
int funcRGB; | |||
int eqnA; | |||
@@ -406,7 +406,7 @@ static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, | |||
static void i830DepthFunc(GLcontext *ctx, GLenum func) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int test = intel_translate_compare_func(func); | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -420,7 +420,7 @@ static void i830DepthFunc(GLcontext *ctx, GLenum func) | |||
static void i830DepthMask(GLcontext *ctx, GLboolean flag) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); | |||
@@ -443,7 +443,7 @@ static void i830DepthMask(GLcontext *ctx, GLboolean flag) | |||
*/ | |||
static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
const GLubyte *m = mask; | |||
GLubyte p[4]; | |||
int i,j,k; | |||
@@ -496,7 +496,7 @@ static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) | |||
static void i830Scissor(GLcontext *ctx, GLint x, GLint y, | |||
GLsizei w, GLsizei h) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
intelScreenPrivate *screen = i830->intel.intelScreen; | |||
int x1, y1, x2, y2; | |||
@@ -530,7 +530,7 @@ static void i830Scissor(GLcontext *ctx, GLint x, GLint y, | |||
static void i830LogicOp(GLcontext *ctx, GLenum opcode) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
int tmp = intel_translate_logic_op( opcode ); | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -545,7 +545,7 @@ static void i830LogicOp(GLcontext *ctx, GLenum opcode) | |||
static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
GLuint mode; | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -573,7 +573,7 @@ static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) | |||
static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT( ctx ); | |||
struct i830_context *i830 = i830_context( ctx ); | |||
int width; | |||
int state5; | |||
@@ -594,7 +594,7 @@ static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) | |||
static void i830PointSize(GLcontext *ctx, GLfloat size) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
GLint point_size = (int)size; | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -616,7 +616,7 @@ static void i830ColorMask(GLcontext *ctx, | |||
GLboolean r, GLboolean g, | |||
GLboolean b, GLboolean a) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT( ctx ); | |||
struct i830_context *i830 = i830_context( ctx ); | |||
GLuint tmp = 0; | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
@@ -638,7 +638,7 @@ static void i830ColorMask(GLcontext *ctx, | |||
static void update_specular( GLcontext *ctx ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT( ctx ); | |||
struct i830_context *i830 = i830_context( ctx ); | |||
I830_STATECHANGE(i830, I830_UPLOAD_CTX); | |||
i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; | |||
@@ -664,7 +664,7 @@ static void i830LightModelfv(GLcontext *ctx, GLenum pname, | |||
*/ | |||
static void i830ShadeModel(GLcontext *ctx, GLenum mode) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
I830_STATECHANGE(i830, I830_UPLOAD_CTX); | |||
@@ -690,7 +690,7 @@ static void i830ShadeModel(GLcontext *ctx, GLenum mode) | |||
*/ | |||
static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
if (INTEL_DEBUG&DEBUG_DRI) | |||
fprintf(stderr, "%s\n", __FUNCTION__); | |||
@@ -710,7 +710,7 @@ static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) | |||
static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct i830_context *i830 = i830_context(ctx); | |||
switch(cap) { | |||
case GL_LIGHTING: | |||
@@ -844,7 +844,7 @@ static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) | |||
} | |||
static void i830_init_packets( i830ContextPtr i830 ) | |||
static void i830_init_packets( struct i830_context *i830 ) | |||
{ | |||
intelScreenPrivate *screen = i830->intel.intelScreen; | |||
@@ -1067,7 +1067,7 @@ void i830InitStateFuncs( struct dd_function_table *functions ) | |||
functions->StencilOpSeparate = i830StencilOpSeparate; | |||
} | |||
void i830InitState( i830ContextPtr i830 ) | |||
void i830InitState( struct i830_context *i830 ) | |||
{ | |||
GLcontext *ctx = &i830->intel.ctx; | |||
@@ -45,261 +45,12 @@ | |||
/** | |||
* Set the texture wrap modes. | |||
* | |||
* The i830M (and related graphics cores) do not support GL_CLAMP. The Intel | |||
* drivers for "other operating systems" implement GL_CLAMP as | |||
* GL_CLAMP_TO_EDGE, so the same is done here. | |||
* | |||
* \param t Texture object whose wrap modes are to be set | |||
* \param swrap Wrap mode for the \a s texture coordinate | |||
* \param twrap Wrap mode for the \a t texture coordinate | |||
*/ | |||
static void i830SetTexWrapping(i830TextureObjectPtr tex, | |||
GLenum swrap, | |||
GLenum twrap) | |||
{ | |||
tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK); | |||
switch( swrap ) { | |||
case GL_REPEAT: | |||
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP); | |||
break; | |||
case GL_CLAMP: | |||
case GL_CLAMP_TO_EDGE: | |||
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP); | |||
break; | |||
case GL_CLAMP_TO_BORDER: | |||
tex->Setup[I830_TEXREG_MCS] |= | |||
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER); | |||
break; | |||
case GL_MIRRORED_REPEAT: | |||
tex->Setup[I830_TEXREG_MCS] |= | |||
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR); | |||
break; | |||
default: | |||
break; | |||
} | |||
switch( twrap ) { | |||
case GL_REPEAT: | |||
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP); | |||
break; | |||
case GL_CLAMP: | |||
case GL_CLAMP_TO_EDGE: | |||
tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP); | |||
break; | |||
case GL_CLAMP_TO_BORDER: | |||
tex->Setup[I830_TEXREG_MCS] |= | |||
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER); | |||
break; | |||
case GL_MIRRORED_REPEAT: | |||
tex->Setup[I830_TEXREG_MCS] |= | |||
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
/** | |||
* Set the texture magnification and minification modes. | |||
* | |||
* \param t Texture whose filter modes are to be set | |||
* \param minf Texture minification mode | |||
* \param magf Texture magnification mode | |||
* \param bias LOD bias for this texture unit. | |||
*/ | |||
static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf, | |||
GLfloat maxanisotropy ) | |||
{ | |||
int minFilt = 0, mipFilt = 0, magFilt = 0; | |||
if(INTEL_DEBUG&DEBUG_DRI) | |||
fprintf(stderr, "%s\n", __FUNCTION__); | |||
if ( maxanisotropy > 1.0 ) { | |||
minFilt = FILTER_ANISOTROPIC; | |||
magFilt = FILTER_ANISOTROPIC; | |||
} | |||
else { | |||
switch (minf) { | |||
case GL_NEAREST: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_NONE; | |||
break; | |||
case GL_LINEAR: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_NONE; | |||
break; | |||
case GL_NEAREST_MIPMAP_NEAREST: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_NEAREST; | |||
break; | |||
case GL_LINEAR_MIPMAP_NEAREST: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_NEAREST; | |||
break; | |||
case GL_NEAREST_MIPMAP_LINEAR: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_LINEAR; | |||
break; | |||
case GL_LINEAR_MIPMAP_LINEAR: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_LINEAR; | |||
break; | |||
default: | |||
break; | |||
} | |||
switch (magf) { | |||
case GL_NEAREST: | |||
magFilt = FILTER_NEAREST; | |||
break; | |||
case GL_LINEAR: | |||
magFilt = FILTER_LINEAR; | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | | |||
(mipFilt << TM0S3_MIP_FILTER_SHIFT) | | |||
(magFilt << TM0S3_MAG_FILTER_SHIFT)); | |||
} | |||
static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) | |||
{ | |||
if(INTEL_DEBUG&DEBUG_DRI) | |||
fprintf(stderr, "%s\n", __FUNCTION__); | |||
t->Setup[I830_TEXREG_TM0S4] = | |||
INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]); | |||
} | |||
/** | |||
* Allocate space for and load the mesa images into the texture memory block. | |||
* This will happen before drawing with a new texture, or drawing with a | |||
* texture after it was swapped out or teximaged again. | |||
*/ | |||
intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj ) | |||
{ | |||
i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object ); | |||
if ( !t ) | |||
return NULL; | |||
texObj->DriverData = t; | |||
t->intel.base.tObj = texObj; | |||
t->intel.dirty = ~0; | |||
make_empty_list( &t->intel.base ); | |||
t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */ | |||
t->Setup[I830_TEXREG_TM0S0] = 0; | |||
t->Setup[I830_TEXREG_TM0S1] = 0; | |||
t->Setup[I830_TEXREG_TM0S2] = 0; | |||
t->Setup[I830_TEXREG_TM0S3] = 0; | |||
t->Setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | | |||
MAP_UNIT(0) | | |||
ENABLE_TEXCOORD_PARAMS | | |||
TEXCOORDS_ARE_NORMAL | | |||
TEXCOORDTYPE_CARTESIAN | | |||
ENABLE_ADDR_V_CNTL | | |||
TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | | |||
ENABLE_ADDR_U_CNTL | | |||
TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); | |||
i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT ); | |||
i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter, | |||
texObj->MaxAnisotropy ); | |||
i830SetTexBorderColor( t, texObj->_BorderChan ); | |||
return &t->intel; | |||
} | |||
static void i830TexParameter( GLcontext *ctx, GLenum target, | |||
struct gl_texture_object *tObj, | |||
GLenum pname, const GLfloat *params ) | |||
{ | |||
i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; | |||
if (!t) | |||
return; | |||
switch (pname) { | |||
case GL_TEXTURE_MIN_FILTER: | |||
case GL_TEXTURE_MAG_FILTER: | |||
case GL_TEXTURE_MAX_ANISOTROPY_EXT: | |||
i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter, | |||
tObj->MaxAnisotropy); | |||
break; | |||
case GL_TEXTURE_WRAP_S: | |||
case GL_TEXTURE_WRAP_T: | |||
i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); | |||
break; | |||
case GL_TEXTURE_BORDER_COLOR: | |||
i830SetTexBorderColor( t, tObj->_BorderChan ); | |||
break; | |||
case GL_TEXTURE_BASE_LEVEL: | |||
case GL_TEXTURE_MAX_LEVEL: | |||
case GL_TEXTURE_MIN_LOD: | |||
case GL_TEXTURE_MAX_LOD: | |||
/* The i830 and its successors can do a lot of this without | |||
* reloading the textures. A project for someone? | |||
*/ | |||
intelFlush( ctx ); | |||
driSwapOutTextureObject( (driTextureObject *) t ); | |||
break; | |||
default: | |||
return; | |||
} | |||
t->intel.dirty = ~0; | |||
} | |||
static void i830TexEnv( GLcontext *ctx, GLenum target, | |||
GLenum pname, const GLfloat *param ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT( ctx ); | |||
GLuint unit = ctx->Texture.CurrentUnit; | |||
switch (pname) { | |||
case GL_TEXTURE_ENV_COLOR: | |||
#if 0 | |||
{ | |||
GLubyte r, g, b, a; | |||
GLuint col; | |||
UNCLAMPED_FLOAT_TO_UBYTE(r, param[RCOMP]); | |||
UNCLAMPED_FLOAT_TO_UBYTE(g, param[GCOMP]); | |||
UNCLAMPED_FLOAT_TO_UBYTE(b, param[BCOMP]); | |||
UNCLAMPED_FLOAT_TO_UBYTE(a, param[ACOMP]); | |||
col = ((a << 24) | (r << 16) | (g << 8) | b); | |||
if (col != i830->state.TexEnv[unit][I830_TEXENVREG_COL1]) { | |||
I830_STATECHANGE(i830, I830_UPLOAD_TEXENV); | |||
i830->state.TexEnv[unit][I830_TEXENVREG_COL1] = col; | |||
} | |||
break; | |||
} | |||
#endif | |||
case GL_TEXTURE_ENV_MODE: | |||
case GL_COMBINE_RGB: | |||
case GL_COMBINE_ALPHA: | |||
@@ -320,13 +71,13 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, | |||
break; | |||
case GL_TEXTURE_LOD_BIAS: { | |||
struct i830_context *i830 = i830_context( ctx ); | |||
GLuint unit = ctx->Texture.CurrentUnit; | |||
int b = (int) ((*param) * 16.0); | |||
if (b > 63) b = 63; | |||
if (b < -64) b = -64; | |||
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); | |||
i830->state.Tex[unit][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; | |||
i830->state.Tex[unit][I830_TEXREG_TM0S3] |= | |||
((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); | |||
i830->lodbias_tm0s3[unit] = ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); | |||
break; | |||
} | |||
@@ -341,5 +92,4 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, | |||
void i830InitTextureFuncs( struct dd_function_table *functions ) | |||
{ | |||
functions->TexEnv = i830TexEnv; | |||
functions->TexParameter = i830TexParameter; | |||
} |
@@ -132,7 +132,7 @@ static inline GLuint GetTexelOp(GLint unit) | |||
* partial support for the extension? | |||
*/ | |||
GLuint | |||
i830SetTexEnvCombine(i830ContextPtr i830, | |||
i830SetTexEnvCombine(struct i830_context *i830, | |||
const struct gl_tex_env_combine_state * combine, | |||
GLint blendUnit, | |||
GLuint texel_op, | |||
@@ -394,7 +394,7 @@ i830SetTexEnvCombine(i830ContextPtr i830, | |||
} | |||
static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, | |||
static void emit_texblend( struct i830_context *i830, GLuint unit, GLuint blendUnit, | |||
GLboolean last_stage ) | |||
{ | |||
struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; | |||
@@ -423,7 +423,7 @@ static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); | |||
} | |||
static void emit_passthrough( i830ContextPtr i830 ) | |||
static void emit_passthrough( struct i830_context *i830 ) | |||
{ | |||
GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; | |||
GLuint unit = 0; | |||
@@ -442,7 +442,7 @@ static void emit_passthrough( i830ContextPtr i830 ) | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); | |||
} | |||
void i830EmitTextureBlend( i830ContextPtr i830 ) | |||
void i830EmitTextureBlend( struct i830_context *i830 ) | |||
{ | |||
GLcontext *ctx = &i830->intel.ctx; | |||
GLuint unit, last_stage = 0, blendunit = 0; |
@@ -38,438 +38,277 @@ | |||
#include "intel_screen.h" | |||
#include "intel_ioctl.h" | |||
#include "intel_tex.h" | |||
#include "intel_mipmap_tree.h" | |||
#include "intel_regions.h" | |||
#include "i830_context.h" | |||
#include "i830_reg.h" | |||
static const GLint initial_offsets[6][2] = { {0,0}, | |||
{0,2}, | |||
{1,0}, | |||
{1,2}, | |||
{1,1}, | |||
{1,3} }; | |||
static const GLint step_offsets[6][2] = { {0,2}, | |||
{0,2}, | |||
{-1,2}, | |||
{-1,2}, | |||
{-1,1}, | |||
{-1,1} }; | |||
#define I830_TEX_UNIT_ENABLED(unit) (1<<unit) | |||
static GLboolean i830SetTexImages( i830ContextPtr i830, | |||
struct gl_texture_object *tObj ) | |||
static GLuint translate_texture_format( GLuint mesa_format ) | |||
{ | |||
GLuint total_height, pitch, i, textureFormat; | |||
i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; | |||
const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; | |||
GLint firstLevel, lastLevel, numLevels; | |||
switch( baseImage->TexFormat->MesaFormat ) { | |||
switch (mesa_format) { | |||
case MESA_FORMAT_L8: | |||
t->intel.texelBytes = 1; | |||
textureFormat = MAPSURF_8BIT | MT_8BIT_L8; | |||
break; | |||
return MAPSURF_8BIT | MT_8BIT_L8; | |||
case MESA_FORMAT_I8: | |||
t->intel.texelBytes = 1; | |||
textureFormat = MAPSURF_8BIT | MT_8BIT_I8; | |||
break; | |||
return MAPSURF_8BIT | MT_8BIT_I8; | |||
case MESA_FORMAT_A8: | |||
t->intel.texelBytes = 1; | |||
textureFormat = MAPSURF_8BIT | MT_8BIT_I8; /* Kludge -- check with conform, glean */ | |||
break; | |||
return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ | |||
case MESA_FORMAT_AL88: | |||
t->intel.texelBytes = 2; | |||
textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; | |||
break; | |||
return MAPSURF_16BIT | MT_16BIT_AY88; | |||
case MESA_FORMAT_RGB565: | |||
t->intel.texelBytes = 2; | |||
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; | |||
break; | |||
return MAPSURF_16BIT | MT_16BIT_RGB565; | |||
case MESA_FORMAT_ARGB1555: | |||
t->intel.texelBytes = 2; | |||
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; | |||
break; | |||
return MAPSURF_16BIT | MT_16BIT_ARGB1555; | |||
case MESA_FORMAT_ARGB4444: | |||
t->intel.texelBytes = 2; | |||
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; | |||
break; | |||
return MAPSURF_16BIT | MT_16BIT_ARGB4444; | |||
case MESA_FORMAT_ARGB8888: | |||
t->intel.texelBytes = 4; | |||
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; | |||
break; | |||
return MAPSURF_32BIT | MT_32BIT_ARGB8888; | |||
case MESA_FORMAT_YCBCR_REV: | |||
t->intel.texelBytes = 2; | |||
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL | | |||
TM0S1_COLORSPACE_CONVERSION); | |||
break; | |||
return (MAPSURF_422 | MT_422_YCRCB_NORMAL); | |||
case MESA_FORMAT_YCBCR: | |||
t->intel.texelBytes = 2; | |||
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */ | |||
TM0S1_COLORSPACE_CONVERSION); | |||
break; | |||
return (MAPSURF_422 | MT_422_YCRCB_SWAPY); | |||
case MESA_FORMAT_RGB_FXT1: | |||
case MESA_FORMAT_RGBA_FXT1: | |||
t->intel.texelBytes = 2; | |||
textureFormat = MAPSURF_COMPRESSED | MT_COMPRESS_FXT1; | |||
break; | |||
return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); | |||
case MESA_FORMAT_RGBA_DXT1: | |||
case MESA_FORMAT_RGB_DXT1: | |||
/* | |||
* DXTn pitches are Width/4 * blocksize in bytes | |||
* for DXT1: blocksize=8 so Width/4*8 = Width * 2 | |||
* for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 | |||
*/ | |||
t->intel.texelBytes = 2; | |||
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); | |||
break; | |||
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); | |||
case MESA_FORMAT_RGBA_DXT3: | |||
t->intel.texelBytes = 4; | |||
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); | |||
break; | |||
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); | |||
case MESA_FORMAT_RGBA_DXT5: | |||
t->intel.texelBytes = 4; | |||
textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); | |||
break; | |||
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); | |||
default: | |||
fprintf(stderr, "%s: bad image format\n", __FUNCTION__); | |||
fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, | |||
mesa_format); | |||
abort(); | |||
return 0; | |||
} | |||
/* Compute which mipmap levels we really want to send to the hardware. | |||
* This depends on the base image size, GL_TEXTURE_MIN_LOD, | |||
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. | |||
* Yes, this looks overly complicated, but it's all needed. | |||
*/ | |||
driCalculateTextureFirstLastLevel( (driTextureObject *) t ); | |||
} | |||
/* Figure out the amount of memory required to hold all the mipmap | |||
* levels. Choose the smallest pitch to accomodate the largest | |||
* mipmap: | |||
*/ | |||
firstLevel = t->intel.base.firstLevel; | |||
lastLevel = t->intel.base.lastLevel; | |||
numLevels = lastLevel - firstLevel + 1; | |||
/* All images must be loaded at this pitch. Count the number of | |||
* lines required: | |||
*/ | |||
switch (tObj->Target) { | |||
case GL_TEXTURE_CUBE_MAP: { | |||
const GLuint dim = tObj->Image[0][firstLevel]->Width; | |||
GLuint face; | |||
pitch = dim * t->intel.texelBytes; | |||
pitch *= 2; /* double pitch for cube layouts */ | |||
pitch = (pitch + 3) & ~3; | |||
total_height = dim * 4; | |||
for ( face = 0 ; face < 6 ; face++) { | |||
GLuint x = initial_offsets[face][0] * dim; | |||
GLuint y = initial_offsets[face][1] * dim; | |||
GLuint d = dim; | |||
t->intel.base.dirty_images[face] = ~0; | |||
assert(tObj->Image[face][firstLevel]->Width == dim); | |||
assert(tObj->Image[face][firstLevel]->Height == dim); | |||
for (i = 0; i < numLevels; i++) { | |||
t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; | |||
if (!t->intel.image[face][i].image) { | |||
fprintf(stderr, "no image %d %d\n", face, i); | |||
break; /* can't happen */ | |||
} | |||
t->intel.image[face][i].offset = | |||
y * pitch + x * t->intel.texelBytes; | |||
t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; | |||
d >>= 1; | |||
x += step_offsets[face][0] * d; | |||
y += step_offsets[face][1] * d; | |||
} | |||
} | |||
break; | |||
} | |||
default: | |||
pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; | |||
pitch = (pitch + 3) & ~3; | |||
t->intel.base.dirty_images[0] = ~0; | |||
for ( total_height = i = 0 ; i < numLevels ; i++ ) { | |||
t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; | |||
if (!t->intel.image[0][i].image) | |||
break; | |||
t->intel.image[0][i].offset = total_height * pitch; | |||
t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; | |||
if (t->intel.image[0][i].image->IsCompressed) | |||
{ | |||
if (t->intel.image[0][i].image->Height > 4) | |||
total_height += t->intel.image[0][i].image->Height/4; | |||
else | |||
total_height += 1; | |||
} | |||
else | |||
total_height += MAX2(2, t->intel.image[0][i].image->Height); | |||
} | |||
break; | |||
/* The i915 (and related graphics cores) do not support GL_CLAMP. The | |||
* Intel drivers for "other operating systems" implement GL_CLAMP as | |||
* GL_CLAMP_TO_EDGE, so the same is done here. | |||
*/ | |||
static GLuint translate_wrap_mode( GLenum wrap ) | |||
{ | |||
switch( wrap ) { | |||
case GL_REPEAT: | |||
return TEXCOORDMODE_WRAP; | |||
case GL_CLAMP: | |||
case GL_CLAMP_TO_EDGE: | |||
return TEXCOORDMODE_CLAMP; /* not really correct */ | |||
case GL_CLAMP_TO_BORDER: | |||
return TEXCOORDMODE_CLAMP_BORDER; | |||
case GL_MIRRORED_REPEAT: | |||
return TEXCOORDMODE_MIRROR; | |||
default: | |||
return TEXCOORDMODE_WRAP; | |||
} | |||
t->intel.Pitch = pitch; | |||
t->intel.base.totalSize = total_height*pitch; | |||
t->intel.max_level = i-1; | |||
t->Setup[I830_TEXREG_TM0S1] = | |||
(((tObj->Image[0][firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) | | |||
((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | | |||
textureFormat); | |||
t->Setup[I830_TEXREG_TM0S2] = | |||
(((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | | |||
TM0S2_CUBE_FACE_ENA_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; | |||
t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; | |||
t->intel.dirty = ~0; | |||
return intelUploadTexImages( &i830->intel, &t->intel, 0 ); | |||
} | |||
static void i830_import_tex_unit( i830ContextPtr i830, | |||
i830TextureObjectPtr t, | |||
GLuint unit ) | |||
/* Recalculate all state from scratch. Perhaps not the most | |||
* efficient, but this has gotten complex enough that we need | |||
* something which is understandable and reliable. | |||
*/ | |||
static GLboolean i830_update_tex_unit( struct intel_context *intel, | |||
GLuint unit, | |||
GLuint ss3 ) | |||
{ | |||
if(INTEL_DEBUG&DEBUG_TEXTURE) | |||
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); | |||
i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; | |||
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) ); | |||
GLcontext *ctx = &intel->ctx; | |||
struct i830_context *i830 = i830_context(ctx); | |||
struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; | |||
struct intel_texture_object *intelObj = intel_texture_object(tObj); | |||
struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; | |||
GLuint *state = i830->state.Tex[unit]; | |||
i830->state.Tex[unit][I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | | |||
(LOAD_TEXTURE_MAP0 << unit) | 4); | |||
i830->state.Tex[unit][I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | | |||
t->intel.TextureOffset); | |||
memset(state, 0, sizeof(state)); | |||
i830->state.Tex[unit][I830_TEXREG_TM0S1] = t->Setup[I830_TEXREG_TM0S1]; | |||
i830->state.Tex[unit][I830_TEXREG_TM0S2] = t->Setup[I830_TEXREG_TM0S2]; | |||
if (!intel_finalize_mipmap_tree(intel, unit)) | |||
return GL_FALSE; | |||
i830->state.Tex[unit][I830_TEXREG_TM0S3] &= TM0S3_LOD_BIAS_MASK; | |||
i830->state.Tex[unit][I830_TEXREG_TM0S3] |= (t->Setup[I830_TEXREG_TM0S3] & | |||
~TM0S3_LOD_BIAS_MASK); | |||
i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; | |||
i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, | |||
intelObj->firstLevel); | |||
i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4]; | |||
i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] & | |||
~MAP_UNIT_MASK); | |||
i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE]; | |||
i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit); | |||
t->intel.dirty &= ~(1<<unit); /* This is broken! */ | |||
} | |||
state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | | |||
(LOAD_TEXTURE_MAP0 << unit) | 4); | |||
/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ | |||
/* t->intel.TextureOffset); */ | |||
static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | |||
struct gl_texture_object *tObj = texUnit->_Current; | |||
i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; | |||
state[I830_TEXREG_TM0S1] = | |||
(((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | | |||
((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | | |||
translate_texture_format( firstImage->TexFormat->MesaFormat)); | |||
if (0) fprintf(stderr, "%s\n", __FUNCTION__); | |||
state[I830_TEXREG_TM0S2] = | |||
(((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - 1) << TM0S2_PITCH_SHIFT) | | |||
TM0S2_CUBE_FACE_ENA_MASK); | |||
/* Fallback if there's a texture border */ | |||
if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { | |||
fprintf(stderr, "Texture border\n"); | |||
return GL_FALSE; | |||
{ | |||
if (tObj->Target == GL_TEXTURE_CUBE_MAP) | |||
state[I830_TEXREG_CUBE] = (CUBE_NEGX_ENABLE | | |||
CUBE_POSX_ENABLE | | |||
CUBE_NEGY_ENABLE | | |||
CUBE_POSY_ENABLE | | |||
CUBE_NEGZ_ENABLE | | |||
CUBE_POSZ_ENABLE); | |||
else | |||
state[I830_TEXREG_CUBE] = 0; | |||
} | |||
/* Upload teximages (not pipelined) | |||
*/ | |||
if (t->intel.base.dirty_images[0]) { | |||
if (!i830SetTexImages( i830, tObj )) { | |||
{ | |||
GLuint minFilt, mipFilt, magFilt; | |||
switch (tObj->MinFilter) { | |||
case GL_NEAREST: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_NONE; | |||
break; | |||
case GL_LINEAR: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_NONE; | |||
break; | |||
case GL_NEAREST_MIPMAP_NEAREST: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_NEAREST; | |||
break; | |||
case GL_LINEAR_MIPMAP_NEAREST: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_NEAREST; | |||
break; | |||
case GL_NEAREST_MIPMAP_LINEAR: | |||
minFilt = FILTER_NEAREST; | |||
mipFilt = MIPFILTER_LINEAR; | |||
break; | |||
case GL_LINEAR_MIPMAP_LINEAR: | |||
minFilt = FILTER_LINEAR; | |||
mipFilt = MIPFILTER_LINEAR; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
} | |||
/* Update state if this is a different texture object to last | |||
* time. | |||
*/ | |||
if (i830->intel.CurrentTexObj[unit] != &t->intel || | |||
(t->intel.dirty & (1<<unit))) { | |||
i830_import_tex_unit( i830, t, unit); | |||
} | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); | |||
if ( tObj->MaxAnisotropy > 1.0 ) { | |||
minFilt = FILTER_ANISOTROPIC; | |||
magFilt = FILTER_ANISOTROPIC; | |||
} | |||
else { | |||
switch (tObj->MagFilter) { | |||
case GL_NEAREST: | |||
magFilt = FILTER_NEAREST; | |||
break; | |||
case GL_LINEAR: | |||
magFilt = FILTER_LINEAR; | |||
break; | |||
default: | |||
return GL_FALSE; | |||
} | |||
} | |||
return GL_TRUE; | |||
} | |||
state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; | |||
static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; | |||
#if 0 | |||
/* YUV conversion: | |||
*/ | |||
if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || | |||
firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) | |||
state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; | |||
#endif | |||
mcs &= ~TEXCOORDS_ARE_NORMAL; | |||
mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; | |||
state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - | |||
intelObj->firstLevel)*4) << TM0S3_MIN_MIP_SHIFT; | |||
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) | |||
|| (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { | |||
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); | |||
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; | |||
i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; | |||
state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | | |||
(mipFilt << TM0S3_MIP_FILTER_SHIFT) | | |||
(magFilt << TM0S3_MAG_FILTER_SHIFT)); | |||
} | |||
return GL_TRUE; | |||
} | |||
{ | |||
GLenum ws = tObj->WrapS; | |||
GLenum wt = tObj->WrapT; | |||
/* 3D textures not available on i830 | |||
*/ | |||
if (tObj->Target == GL_TEXTURE_3D) | |||
return GL_FALSE; | |||
static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; | |||
state[I830_TEXREG_MCS] = ss3; /* TEXCOORDS_ARE_NORMAL */ | |||
mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; | |||
mcs |= TEXCOORDS_ARE_NORMAL; | |||
state[I830_TEXREG_MCS] |= (TEXCOORD_ADDR_V_MODE(translate_wrap_mode(ws)) | | |||
TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt))); | |||
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) | |||
|| (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { | |||
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); | |||
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; | |||
i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; | |||
state[I830_TEXREG_MCS] |= MAP_UNIT(unit); | |||
} | |||
return GL_TRUE; | |||
} | |||
static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | |||
struct gl_texture_object *tObj = texUnit->_Current; | |||
i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; | |||
GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; | |||
const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE | |||
| CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE | |||
| CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE; | |||
GLuint face; | |||
mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; | |||
mcs |= TEXCOORDS_ARE_NORMAL; | |||
if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) | |||
|| (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) { | |||
I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); | |||
i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; | |||
i830->state.Tex[unit][I830_TEXREG_CUBE] = cube; | |||
} | |||
state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], | |||
tObj->_BorderChan[1], | |||
tObj->_BorderChan[2], | |||
tObj->_BorderChan[3]); | |||
/* Upload teximages (not pipelined) | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); | |||
/* memcmp was already disabled, but definitely won't work as the | |||
* region might now change and that wouldn't be detected: | |||
*/ | |||
if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || | |||
t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || | |||
t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { | |||
i830SetTexImages( i830, tObj ); | |||
} | |||
/* upload (per face) */ | |||
for (face = 0; face < 6; face++) { | |||
if (t->intel.base.dirty_images[face]) { | |||
if (!intelUploadTexImages( &i830->intel, &t->intel, face )) { | |||
return GL_FALSE; | |||
} | |||
} | |||
} | |||
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) ); | |||
return GL_TRUE; | |||
} | |||
static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(ctx); | |||
/* This is happening too often. I need to conditionally send diffuse | |||
* state to the card. Perhaps a diffuse dirty flag of some kind. | |||
* Will need to change this logic if more than 2 texture units are | |||
* used. We need to only do this up to the last unit enabled, or unit | |||
* one if nothing is enabled. | |||
*/ | |||
/* The old texture is no longer bound to this texture unit. | |||
* Mark it as such. | |||
*/ | |||
i830->intel.CurrentTexObj[unit] = NULL; | |||
return GL_TRUE; | |||
} | |||
static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) | |||
void i830UpdateTextureState( struct intel_context *intel ) | |||
{ | |||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; | |||
if (texUnit->_ReallyEnabled && | |||
intel_context(ctx)->intelScreen->tex.size < 2048 * 1024) | |||
return GL_FALSE; | |||
switch(texUnit->_ReallyEnabled) { | |||
case TEXTURE_1D_BIT: | |||
case TEXTURE_2D_BIT: | |||
return (enable_tex_common( ctx, unit ) && | |||
enable_tex_2d( ctx, unit )); | |||
case TEXTURE_RECT_BIT: | |||
return (enable_tex_common( ctx, unit ) && | |||
enable_tex_rect( ctx, unit )); | |||
case TEXTURE_CUBE_BIT: | |||
return (enable_tex_common( ctx, unit ) && | |||
enable_tex_cube( ctx, unit )); | |||
case 0: | |||
return disable_tex( ctx, unit ); | |||
default: | |||
return GL_FALSE; | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
GLboolean ok = GL_TRUE; | |||
GLuint i; | |||
for (i = 0 ; i < I830_TEX_UNITS && ok ; i++) { | |||
switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { | |||
case TEXTURE_1D_BIT: | |||
case TEXTURE_2D_BIT: | |||
case TEXTURE_CUBE_BIT: | |||
ok = i830_update_tex_unit( intel, i, TEXCOORDS_ARE_NORMAL ); | |||
break; | |||
case TEXTURE_RECT_BIT: | |||
ok = i830_update_tex_unit( intel, i, TEXCOORDS_ARE_IN_TEXELUNITS ); | |||
break; | |||
case 0: | |||
if (i830->state.active & I830_UPLOAD_TEX(i)) | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); | |||
break; | |||
case TEXTURE_3D_BIT: | |||
default: | |||
ok = GL_FALSE; | |||
break; | |||
} | |||
} | |||
} | |||
FALLBACK( intel, I830_FALLBACK_TEXTURE, !ok ); | |||
void i830UpdateTextureState( struct intel_context *intel ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
GLcontext *ctx = &intel->ctx; | |||
GLboolean ok; | |||
if (ok) | |||
i830EmitTextureBlend( i830 ); | |||
} | |||
if (0) fprintf(stderr, "%s\n", __FUNCTION__); | |||
I830_ACTIVESTATE(i830, I830_UPLOAD_TEX_ALL, GL_FALSE); | |||
ok = (i830UpdateTexUnit( ctx, 0 ) && | |||
i830UpdateTexUnit( ctx, 1 ) && | |||
i830UpdateTexUnit( ctx, 2 ) && | |||
i830UpdateTexUnit( ctx, 3 )); | |||
FALLBACK( intel, I830_FALLBACK_TEXTURE, !ok ); | |||
if (ok) | |||
i830EmitTextureBlend( i830 ); | |||
} | |||
@@ -30,6 +30,7 @@ | |||
#include "i830_reg.h" | |||
#include "intel_batchbuffer.h" | |||
#include "intel_regions.h" | |||
#include "tnl/t_context.h" | |||
#include "tnl/t_vertex.h" | |||
@@ -62,7 +63,7 @@ do { \ | |||
static void i830_render_start( struct intel_context *intel ) | |||
{ | |||
GLcontext *ctx = &intel->ctx; | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
struct i830_context *i830 = i830_context(ctx); | |||
TNLcontext *tnl = TNL_CONTEXT(ctx); | |||
struct vertex_buffer *VB = &tnl->vb; | |||
GLuint index = tnl->render_inputs; | |||
@@ -189,7 +190,7 @@ static void i830_render_start( struct intel_context *intel ) | |||
static void i830_reduced_primitive_state( struct intel_context *intel, | |||
GLenum rprim ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; | |||
st1 &= ~ST1_ENABLE; | |||
@@ -220,7 +221,7 @@ static void i830_reduced_primitive_state( struct intel_context *intel, | |||
static GLboolean i830_check_vertex_size( struct intel_context *intel, | |||
GLuint expected ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
int vft0 = i830->current->Ctx[I830_CTXREG_VF]; | |||
int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; | |||
int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; | |||
@@ -330,13 +331,6 @@ static void i830_emit_invarient_state( struct intel_context *intel ) | |||
TRI_FAN_PROVOKE_VRTX(2) | | |||
TRI_STRIP_PROVOKE_VRTX(2)); | |||
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | | |||
DISABLE_SCISSOR_RECT); | |||
OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); | |||
OUT_BATCH(0); | |||
OUT_BATCH(0); | |||
OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); | |||
OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); | |||
@@ -366,7 +360,7 @@ do { \ | |||
*/ | |||
static void i830_emit_state( struct intel_context *intel ) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
struct i830_hw_state *state = i830->current; | |||
int i; | |||
GLuint dirty; | |||
@@ -374,29 +368,76 @@ static void i830_emit_state( struct intel_context *intel ) | |||
dirty = state->active & ~state->emitted; | |||
if (dirty & I830_UPLOAD_INVARIENT) { | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_INVARIENT:\n"); | |||
i830_emit_invarient_state( intel ); | |||
} | |||
if (dirty & I830_UPLOAD_CTX) { | |||
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_CTX:\n"); | |||
emit( i830, state->Ctx, sizeof(state->Ctx) ); | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_CTX:\n"); | |||
BEGIN_BATCH(I830_DEST_SETUP_SIZE+2, 0); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); | |||
OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); | |||
OUT_RELOC(state->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); | |||
OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); | |||
ADVANCE_BATCH(); | |||
} | |||
if (dirty & I830_UPLOAD_BUFFERS) { | |||
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_BUFFERS:\n"); | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_BUFFERS:\n"); | |||
emit( i830, state->Buffer, sizeof(state->Buffer) ); | |||
} | |||
if (dirty & I830_UPLOAD_STIPPLE) { | |||
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_STIPPLE:\n"); | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_STIPPLE:\n"); | |||
emit( i830, state->Stipple, sizeof(state->Stipple) ); | |||
} | |||
for (i = 0; i < I830_TEX_UNITS; i++) { | |||
if ((dirty & I830_UPLOAD_TEX(i))) { | |||
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i); | |||
emit( i830, state->Tex[i], sizeof(state->Tex[i])); | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i); | |||
BEGIN_BATCH(I830_TEX_SETUP_SIZE+1, 0); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); | |||
if (state->tex_buffer[i]) { | |||
OUT_RELOC(state->tex_buffer[i], | |||
BM_MEM_AGP|BM_READ, | |||
state->tex_offset[i] | TM0S0_USE_FENCE); | |||
} | |||
else { | |||
assert(i == 0); | |||
assert(state == &i830->meta); | |||
OUT_BATCH(0); | |||
} | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); | |||
OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); | |||
} | |||
if (dirty & I830_UPLOAD_TEXBLEND(i)) { | |||
if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i); | |||
if (INTEL_DEBUG & DEBUG_STATE) | |||
fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i); | |||
emit( i830, state->TexBlend[i], | |||
state->TexBlendWordsUsed[i] * 4 ); | |||
} | |||
@@ -410,46 +451,47 @@ static void i830_destroy_context( struct intel_context *intel ) | |||
_tnl_free_vertices(&intel->ctx); | |||
} | |||
static void i830_set_draw_offset( struct intel_context *intel, int offset ) | |||
static void i830_set_draw_region( struct intel_context *intel, | |||
struct intel_region *draw_region, | |||
struct intel_region *depth_region) | |||
{ | |||
i830ContextPtr i830 = I830_CONTEXT(intel); | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
intel_region_release(intel, &i830->state.draw_region); | |||
intel_region_release(intel, &i830->state.depth_region); | |||
intel_region_reference(&i830->state.draw_region, draw_region); | |||
intel_region_reference(&i830->state.depth_region, depth_region); | |||
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS ); | |||
/* i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ | |||
} | |||
/* This isn't really handled at the moment. | |||
*/ | |||
static void i830_lost_hardware( struct intel_context *intel ) | |||
{ | |||
I830_CONTEXT(intel)->state.emitted = 0; | |||
struct i830_context *i830 = i830_context(&intel->ctx); | |||
i830->state.emitted = 0; | |||
} | |||
static void i830_emit_flush( struct intel_context *intel ) | |||
static GLuint i830_flush_cmd( void ) | |||
{ | |||
BATCH_LOCALS; | |||
BEGIN_BATCH(2, 0); | |||
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE ); | |||
OUT_BATCH( 0 ); | |||
ADVANCE_BATCH(); | |||
return MI_FLUSH | FLUSH_MAP_CACHE; | |||
} | |||
void i830InitVtbl( i830ContextPtr i830 ) | |||
void i830InitVtbl( struct i830_context *i830 ) | |||
{ | |||
i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; | |||
i830->intel.vtbl.clear_with_tris = i830ClearWithTris; | |||
i830->intel.vtbl.destroy = i830_destroy_context; | |||
i830->intel.vtbl.emit_invarient_state = i830_emit_invarient_state; | |||
i830->intel.vtbl.emit_state = i830_emit_state; | |||
i830->intel.vtbl.lost_hardware = i830_lost_hardware; | |||
i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; | |||
i830->intel.vtbl.set_draw_offset = i830_set_draw_offset; | |||
i830->intel.vtbl.set_draw_region = i830_set_draw_region; | |||
i830->intel.vtbl.update_texture_state = i830UpdateTextureState; | |||
i830->intel.vtbl.emit_flush = i830_emit_flush; | |||
i830->intel.vtbl.flush_cmd = i830_flush_cmd; | |||
i830->intel.vtbl.render_start = i830_render_start; | |||
} |
@@ -44,6 +44,7 @@ | |||
#define I915_UPLOAD_CONSTANTS 0x10 | |||
#define I915_UPLOAD_FOG 0x20 | |||
#define I915_UPLOAD_INVARIENT 0x40 | |||
#define I915_UPLOAD_DEFAULTS 0x80 | |||
#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) | |||
#define I915_UPLOAD_TEX_ALL (0x00ff0000) | |||
#define I915_UPLOAD_TEX_0_SHIFT 16 | |||
@@ -92,6 +93,15 @@ | |||
#define I915_TEXREG_SS4 5 | |||
#define I915_TEX_SETUP_SIZE 6 | |||
#define I915_DEFREG_C0 0 | |||
#define I915_DEFREG_C1 1 | |||
#define I915_DEFREG_S0 2 | |||
#define I915_DEFREG_S1 3 | |||
#define I915_DEFREG_Z0 4 | |||
#define I915_DEFREG_Z1 5 | |||
#define I915_DEF_SETUP_SIZE 6 | |||
#define I915_MAX_CONSTANT 32 | |||
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) | |||
@@ -190,6 +200,7 @@ struct i915_hw_state { | |||
GLuint Buffer[I915_DEST_SETUP_SIZE]; | |||
GLuint Stipple[I915_STP_SETUP_SIZE]; | |||
GLuint Fog[I915_FOG_SETUP_SIZE]; | |||
GLuint Defaults[I915_DEF_SETUP_SIZE]; | |||
GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; | |||
GLuint Constant[I915_CONSTANT_SIZE]; | |||
GLuint ConstantSize; |
@@ -824,6 +824,10 @@ | |||
#define ST1_ENABLE (1<<16) | |||
#define ST1_MASK (0xffff) | |||
#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) | |||
#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) | |||
#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) | |||
#define MI_FLUSH ((0<<29)|(4<<23)) | |||
#define FLUSH_MAP_CACHE (1<<0) |
@@ -896,6 +896,19 @@ static void i915_init_packets( struct i915_context *i915 ) | |||
} | |||
#if 0 | |||
{ | |||
I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); | |||
i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; | |||
i915->state.Default[I915_DEFREG_C1] = 0; | |||
i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; | |||
i915->state.Default[I915_DEFREG_S1] = 0; | |||
i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; | |||
i915->state.Default[I915_DEFREG_Z1] = 0; | |||
} | |||
#endif | |||
/* These will be emitted every at the head of every buffer, unless | |||
* we get hardware contexts working. | |||
*/ |
@@ -245,7 +245,7 @@ static void i915_emit_state( struct intel_context *intel ) | |||
if (dirty & I915_UPLOAD_BUFFERS) { | |||
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); | |||
BEGIN_BATCH(I915_DEST_SETUP_SIZE, 0); | |||
BEGIN_BATCH(I915_DEST_SETUP_SIZE+2, 0); | |||
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); | |||
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); | |||
OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0); | |||
@@ -370,7 +370,6 @@ void i915InitVtbl( struct i915_context *i915 ) | |||
{ | |||
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; | |||
i915->intel.vtbl.destroy = i915_destroy_context; | |||
i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state; | |||
i915->intel.vtbl.emit_state = i915_emit_state; | |||
i915->intel.vtbl.lost_hardware = i915_lost_hardware; | |||
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; |
@@ -67,9 +67,9 @@ | |||
* modifying cliprects ??? | |||
*/ | |||
static void intel_dump_batchbuffer( unsigned offset, | |||
int *ptr, | |||
int count ) | |||
static void intel_dump_batchbuffer( GLuint offset, | |||
GLuint *ptr, | |||
GLuint count ) | |||
{ | |||
int i; | |||
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count/4); |
@@ -113,7 +113,7 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, | |||
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) | |||
#define OUT_RELOC(buf,flags,delta) do { \ | |||
assert(delta >= 0); \ | |||
assert((delta) >= 0); \ | |||
intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ | |||
} while (0) | |||
@@ -67,6 +67,9 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) | |||
* should work regardless. | |||
*/ | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable && | |||
intel->driDrawable->numClipRects) | |||
{ | |||
intelScreenPrivate *intelScreen = intel->intelScreen; | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
@@ -117,9 +120,9 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) | |||
ADVANCE_BATCH(); | |||
} | |||
} | |||
intel->last_swap_fence = intel_batchbuffer_flush( intel->batch ); | |||
intel->last_swap_fence = intel_batchbuffer_flush( intel->batch ); | |||
} | |||
UNLOCK_HARDWARE( intel ); | |||
} | |||
@@ -299,6 +302,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, | |||
intelFlush( &intel->ctx ); | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
drm_clip_rect_t clear; | |||
@@ -367,8 +372,9 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, | |||
ADVANCE_BATCH(); | |||
} | |||
} | |||
intel_batchbuffer_flush( intel->batch ); | |||
} | |||
intel_batchbuffer_flush( intel->batch ); | |||
UNLOCK_HARDWARE( intel ); | |||
} | |||
@@ -216,8 +216,6 @@ void intelWindowMoved( struct intel_context *intel ) | |||
static void emit_clip_rect_quads(struct intel_context *intel, | |||
const drm_clip_rect_t *clear) | |||
{ | |||
GLuint i; | |||
/* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the | |||
* drawing origin may not be correctly emitted. | |||
*/ | |||
@@ -243,59 +241,63 @@ static void intelClearWithTris(struct intel_context *intel, | |||
drm_clip_rect_t clear; | |||
LOCK_HARDWARE(intel); | |||
intel->vtbl.install_meta_state(intel); | |||
if(!all) { | |||
clear.x1 = cx; | |||
clear.y1 = cy; | |||
clear.x2 = cx + cw; | |||
clear.y2 = cy + ch; | |||
} else { | |||
clear.x1 = 0; | |||
clear.y1 = 0; | |||
clear.x2 = dPriv->w; | |||
clear.y2 = dPriv->h; | |||
} | |||
if (intel->driDrawable->numClipRects) { | |||
/* Back and stencil cliprects are the same. Try and do both | |||
* buffers at once: | |||
*/ | |||
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) { | |||
intel->vtbl.meta_draw_region(intel, | |||
intel->back_region, | |||
intel->depth_region ); | |||
intel->vtbl.install_meta_state(intel); | |||
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_depth_stencil_write(intel); | |||
if(!all) { | |||
clear.x1 = cx; | |||
clear.y1 = cy; | |||
clear.x2 = cx + cw; | |||
clear.y2 = cy + ch; | |||
} else { | |||
clear.x1 = 0; | |||
clear.y1 = 0; | |||
clear.x2 = dPriv->w; | |||
clear.y2 = dPriv->h; | |||
} | |||
/* Back and stencil cliprects are the same. Try and do both | |||
* buffers at once: | |||
*/ | |||
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) { | |||
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_depth_stencil_write(intel); | |||
/* Do cliprects explicitly: | |||
/* Do cliprects explicitly: | |||
*/ | |||
emit_clip_rect_quads(intel, &clear); | |||
} | |||
/* Front may have different cliprects: | |||
*/ | |||
emit_clip_rect_quads(intel, &clear); | |||
} | |||
if (mask & BUFFER_BIT_FRONT_LEFT) { | |||
intel->vtbl.meta_no_depth_stencil_write(intel); | |||
intel->vtbl.meta_color_mask(intel, GL_TRUE ); | |||
intel->vtbl.meta_draw_region(intel, | |||
intel->front_region, | |||
intel->depth_region); | |||
/* Front may have different cliprects: | |||
*/ | |||
if (mask & BUFFER_BIT_FRONT_LEFT) { | |||
intel->vtbl.meta_no_depth_stencil_write(intel); | |||
intel->vtbl.meta_color_mask(intel, GL_TRUE ); | |||
intel->vtbl.meta_draw_region(intel, | |||
intel->front_region, | |||
intel->depth_region); | |||
emit_clip_rect_quads(intel, &clear); | |||
} | |||
emit_clip_rect_quads(intel, &clear); | |||
intel->vtbl.leave_meta_state( intel ); | |||
intel_batchbuffer_flush( intel->batch ); | |||
} | |||
intel->vtbl.leave_meta_state( intel ); | |||
intel_batchbuffer_flush( intel->batch ); | |||
UNLOCK_HARDWARE(intel); | |||
} | |||
@@ -113,7 +113,6 @@ struct intel_context | |||
struct { | |||
void (*destroy)( struct intel_context *intel ); | |||
void (*emit_state)( struct intel_context *intel ); | |||
void (*emit_invarient_state)( struct intel_context *intel ); | |||
void (*lost_hardware)( struct intel_context *intel ); | |||
void (*update_texture_state)( struct intel_context *intel ); | |||
@@ -128,10 +127,6 @@ struct intel_context | |||
GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected ); | |||
void (*clear_with_tris)( struct intel_context *intel, GLbitfield mask, | |||
GLboolean all, | |||
GLint cx, GLint cy, GLint cw, GLint ch); | |||
/* Metaops: | |||
*/ |
@@ -66,6 +66,7 @@ GLboolean intel_check_meta_tex_fragment_ops( GLcontext *ctx ) | |||
* fragment programs on i915. | |||
*/ | |||
return !(ctx->_ImageTransferState || | |||
ctx->Fog.Enabled || /* not done yet */ | |||
ctx->Texture._EnabledUnits || | |||
ctx->FragmentProgram._Enabled); | |||
} |
@@ -91,6 +91,34 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, | |||
if (!src || !dst || type != GL_COLOR) | |||
return GL_FALSE; | |||
/* Can't handle overlapping regions. Don't have sufficient control | |||
* over rasterization to pull it off in-place. Punt on these for | |||
* now. | |||
* | |||
* XXX: do a copy to a temporary. | |||
*/ | |||
{ | |||
drm_clip_rect_t src; | |||
drm_clip_rect_t dst; | |||
drm_clip_rect_t tmp; | |||
src.x1 = srcx; | |||
src.y1 = srcy; | |||
src.x2 = srcx + width; | |||
src.y2 = srcy + height; | |||
dst.x1 = dstx; | |||
dst.y1 = dsty; | |||
dst.x1 = dstx + width * ctx->Pixel.ZoomX; | |||
dst.y2 = dsty + height * ctx->Pixel.ZoomY; | |||
if (intel_intersect_cliprects(&tmp, &src, &dst)) { | |||
_mesa_printf("%s: regions overlap\n", __FUNCTION__); | |||
return GL_FALSE; | |||
} | |||
} | |||
intelFlush( &intel->ctx ); | |||
intel->vtbl.install_meta_state(intel); | |||
@@ -131,7 +159,8 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
@@ -171,11 +200,11 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, | |||
0x00ff00ff, | |||
srcx, srcx+width, | |||
srcy, srcy+height); | |||
} | |||
out: | |||
intel->vtbl.leave_meta_state(intel); | |||
intel_batchbuffer_flush(intel->batch); | |||
out: | |||
intel->vtbl.leave_meta_state(intel); | |||
intel_batchbuffer_flush(intel->batch); | |||
} | |||
UNLOCK_HARDWARE( intel ); | |||
return GL_TRUE; | |||
} | |||
@@ -215,6 +244,8 @@ static GLboolean do_blit_copypixels( GLcontext *ctx, | |||
intel->vtbl.emit_state(intel); | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
drm_clip_rect_t *box = dPriv->pClipRects; | |||
@@ -279,9 +310,10 @@ static GLboolean do_blit_copypixels( GLcontext *ctx, | |||
rect.x2 - rect.x1, | |||
rect.y2 - rect.y1 ); | |||
} | |||
out: | |||
intel_batchbuffer_flush( intel->batch ); | |||
} | |||
out: | |||
intel_batchbuffer_flush( intel->batch ); | |||
UNLOCK_HARDWARE( intel ); | |||
return GL_TRUE; | |||
} |
@@ -136,6 +136,7 @@ static GLboolean do_texture_drawpixels( GLcontext *ctx, | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
GLint srcx, srcy; | |||
@@ -174,11 +175,10 @@ static GLboolean do_texture_drawpixels( GLcontext *ctx, | |||
0x00ff00ff, | |||
srcx, srcx+width, | |||
srcy+height, srcy); | |||
out: | |||
intel->vtbl.leave_meta_state(intel); | |||
intel_batchbuffer_flush(intel->batch); | |||
} | |||
out: | |||
intel->vtbl.leave_meta_state(intel); | |||
intel_batchbuffer_flush(intel->batch); | |||
UNLOCK_HARDWARE( intel ); | |||
_mesa_printf("%s - DONE\n", __FUNCTION__); | |||
return GL_TRUE; | |||
@@ -215,7 +215,7 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, | |||
struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); | |||
GLuint src_offset; | |||
GLuint rowLength; | |||
GLuint fence; | |||
GLuint fence = 0; | |||
if (INTEL_DEBUG & DEBUG_PIXEL) | |||
_mesa_printf("%s\n", __FUNCTION__); | |||
@@ -283,6 +283,8 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, | |||
intelFlush( &intel->ctx ); | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
int nbox = dPriv->numClipRects; | |||
@@ -314,12 +316,12 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, | |||
rect.x2 - rect.x1, | |||
rect.y2 - rect.y1 ); | |||
} | |||
fence = intel_batchbuffer_flush( intel->batch ); | |||
} | |||
fence = intel_batchbuffer_flush( intel->batch ); | |||
UNLOCK_HARDWARE( intel ); | |||
bmFinishFence(intel->bm, fence); | |||
if (intel->driDrawable->numClipRects) | |||
bmFinishFence(intel->bm, fence); | |||
_mesa_printf("%s - DONE\n", __FUNCTION__); | |||
@@ -110,49 +110,52 @@ do_texture_readpixels( GLcontext *ctx, | |||
} | |||
LOCK_HARDWARE( intel ); | |||
intel->vtbl.install_meta_state(intel); | |||
intel->vtbl.meta_no_depth_stencil_write(intel); | |||
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { | |||
UNLOCK_HARDWARE( intel ); | |||
SET_STATE(i830, state); | |||
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); | |||
return GL_TRUE; | |||
} | |||
y = dPriv->h - y - height; | |||
x += dPriv->x; | |||
y += dPriv->y; | |||
if (intel->driDrawable->numClipRects) { | |||
intel->vtbl.install_meta_state(intel); | |||
intel->vtbl.meta_no_depth_stencil_write(intel); | |||
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { | |||
UNLOCK_HARDWARE( intel ); | |||
SET_STATE(i830, state); | |||
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); | |||
return GL_TRUE; | |||
} | |||
y = dPriv->h - y - height; | |||
x += dPriv->x; | |||
y += dPriv->y; | |||
/* Set the frontbuffer up as a large rectangular texture. | |||
*/ | |||
intel->vtbl.meta_tex_rect_source( intel, | |||
src_region, | |||
textureFormat ); | |||
/* Set the frontbuffer up as a large rectangular texture. | |||
*/ | |||
intel->vtbl.meta_tex_rect_source( intel, | |||
src_region, | |||
textureFormat ); | |||
intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat ); | |||
intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat ); | |||
/* Set the 3d engine to draw into the destination region: | |||
*/ | |||
/* Set the 3d engine to draw into the destination region: | |||
*/ | |||
intel->vtbl.meta_draw_region(intel, dest_region); | |||
intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */ | |||
intel->vtbl.meta_draw_region(intel, dest_region); | |||
intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */ | |||
/* Draw a single quad, no cliprects: | |||
*/ | |||
intel->vtbl.meta_disable_cliprects(intel); | |||
/* Draw a single quad, no cliprects: | |||
*/ | |||
intel->vtbl.meta_disable_cliprects(intel); | |||
intel->vtbl.draw_quad(intel, | |||
0, width, 0, height, | |||
0x00ff00ff, | |||
x, x+width, | |||
y, y+height ); | |||
intel->vtbl.draw_quad(intel, | |||
0, width, 0, height, | |||
0x00ff00ff, | |||
x, x+width, | |||
y, y+height ); | |||
intel->vtbl.leave_meta_state(intel); | |||
intel->vtbl.leave_meta_state(intel); | |||
} | |||
UNLOCK_HARDWARE( intel ); | |||
intel_region_wait_fence( ctx, dest_region ); /* required by GL */ | |||
@@ -176,7 +179,7 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, | |||
struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); | |||
GLuint dst_offset; | |||
GLuint rowLength; | |||
GLuint fence; | |||
GLuint fence = 0; | |||
if (INTEL_DEBUG & DEBUG_PIXEL) | |||
_mesa_printf("%s\n", __FUNCTION__); | |||
@@ -237,6 +240,8 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, | |||
*/ | |||
intelFlush( &intel->ctx ); | |||
LOCK_HARDWARE( intel ); | |||
if (intel->driDrawable->numClipRects) | |||
{ | |||
__DRIdrawablePrivate *dPriv = intel->driDrawable; | |||
int nbox = dPriv->numClipRects; | |||
@@ -274,10 +279,12 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, | |||
} | |||
UNLOCK_HARDWARE( intel ); | |||
bmFinishFence(intel->bm, fence); | |||
if (intel->driDrawable->numClipRects) | |||
bmFinishFence(intel->bm, fence); | |||
if (INTEL_DEBUG & DEBUG_PIXEL) | |||
_mesa_printf("%s - DONE\n", __FUNCTION__); | |||
return GL_TRUE; | |||
} | |||
@@ -111,7 +111,7 @@ static void intelDmaPrimitive( struct intel_context *intel, GLenum prim ) | |||
if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); | |||
INTEL_FIREVERTICES(intel); | |||
intel->vtbl.reduced_primitive_state( intel, reduced_prim[prim] ); | |||
intelStartInlinePrimitive( intel, hw_prim[prim] ); | |||
intelStartInlinePrimitive( intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS ); | |||
} | |||
@@ -120,10 +120,15 @@ static void intelDmaPrimitive( struct intel_context *intel, GLenum prim ) | |||
do { \ | |||
intelDmaPrimitive( intel, prim ); \ | |||
} while (0) | |||
#define FLUSH() INTEL_FIREVERTICES( intel ) | |||
#define FLUSH() \ | |||
do { \ | |||
if (intel->prim.flush) \ | |||
intel->prim.flush(intel); \ | |||
} while (0) | |||
#define GET_SUBSEQUENT_VB_MAX_VERTS() \ | |||
(((intel->alloc.size / 2) - 1500) / (intel->vertex_size*4)) | |||
((BATCH_SZ - 1500) / (intel->vertex_size*4)) | |||
#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() | |||
#define ALLOC_VERTS( nr ) \ | |||
@@ -199,10 +204,6 @@ static GLboolean intel_run_render( GLcontext *ctx, | |||
struct vertex_buffer *VB = &tnl->vb; | |||
GLuint i; | |||
/* disabled | |||
*/ | |||
return GL_TRUE; | |||
/* Don't handle clipping or indexed vertices. | |||
*/ | |||
if (intel->RenderIndex != 0 || | |||
@@ -229,6 +230,9 @@ static GLboolean intel_run_render( GLcontext *ctx, | |||
} | |||
tnl->Driver.Render.Finish( ctx ); | |||
if (intel->prim.flush) | |||
intel->prim.flush(intel); | |||
return GL_FALSE; /* finished the pipe */ | |||
} |
@@ -83,7 +83,6 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, | |||
{ | |||
GLcontext *ctx = &intel->ctx; | |||
struct intel_region *src = get_teximage_source(intel, internalFormat); | |||
GLuint ret = GL_TRUE; | |||
if (!intelImage->mt || !src) | |||
return GL_FALSE; | |||
@@ -99,51 +98,45 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, | |||
GLint orig_y = y; | |||
GLuint window_y; | |||
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { | |||
ret = GL_TRUE; | |||
goto out; | |||
} | |||
/* Update dst for clipped src. Need to also clip the source rect. | |||
*/ | |||
dstx += x - orig_x; | |||
dsty += y - orig_y; | |||
if (intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { | |||
/* Update dst for clipped src. Need to also clip the source rect. | |||
*/ | |||
dstx += x - orig_x; | |||
dsty += y - orig_y; | |||
x += dPriv->x; | |||
x += dPriv->x; | |||
window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); | |||
window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); | |||
y = window_y + y; | |||
y = window_y + y; | |||
/* A bit of fiddling to get the blitter to work with -ve | |||
* pitches. But we get a nice inverted blit this way, so it's | |||
* worth it: | |||
*/ | |||
intelEmitCopyBlit( intel, | |||
intelImage->mt->cpp, | |||
/* A bit of fiddling to get the blitter to work with -ve | |||
* pitches. But we get a nice inverted blit this way, so it's | |||
* worth it: | |||
*/ | |||
intelEmitCopyBlit( intel, | |||
intelImage->mt->cpp, | |||
-src->pitch, | |||
src->buffer, | |||
src->height * src->pitch * src->cpp, | |||
-src->pitch, | |||
src->buffer, | |||
src->height * src->pitch * src->cpp, | |||
intelImage->mt->pitch, | |||
intelImage->mt->region->buffer, | |||
image_offset, | |||
intelImage->mt->pitch, | |||
intelImage->mt->region->buffer, | |||
image_offset, | |||
x, y + height, | |||
dstx, dsty, | |||
width, height ); | |||
x, y + height, | |||
dstx, dsty, | |||
width, height ); | |||
out: | |||
intel_batchbuffer_flush( intel->batch ); | |||
intel_batchbuffer_flush( intel->batch ); | |||
} | |||
} | |||
UNLOCK_HARDWARE(intel); | |||
if (!ret) | |||
return GL_FALSE; | |||
#if 0 | |||
/* GL_SGIS_generate_mipmap -- this can be accelerated now. |
@@ -48,20 +48,7 @@ | |||
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ); | |||
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); | |||
/* The simplest but least-good technique for integrating new buffer | |||
* management: | |||
* | |||
* LOCK_HARDWARE | |||
* validate_buffers | |||
* emit_state to batch | |||
* emit_vertices to batch | |||
* flush batch | |||
* fence_buffers | |||
* UNLOCK_HARDWARE | |||
* | |||
* Will look later at ways to get the emit_state and emit_vertices out | |||
* of the locked region - vertex buffers, second batch buffer for | |||
* primitives, relocation fixups for texture addresses. | |||
/* | |||
*/ | |||
static void intel_flush_inline_primitive( struct intel_context *intel ) | |||
{ | |||
@@ -581,6 +568,9 @@ intel_fallback_tri( struct intel_context *intel, | |||
if (0) | |||
fprintf(stderr, "\n%s\n", __FUNCTION__); | |||
if (intel->prim.flush) | |||
intel->prim.flush(intel); | |||
_swsetup_Translate( ctx, v0, &v[0] ); | |||
_swsetup_Translate( ctx, v1, &v[1] ); | |||
@@ -602,6 +592,9 @@ intel_fallback_line( struct intel_context *intel, | |||
if (0) | |||
fprintf(stderr, "\n%s\n", __FUNCTION__); | |||
if (intel->prim.flush) | |||
intel->prim.flush(intel); | |||
_swsetup_Translate( ctx, v0, &v[0] ); | |||
_swsetup_Translate( ctx, v1, &v[1] ); | |||
intelSpanRenderStart( ctx ); | |||
@@ -610,8 +603,6 @@ intel_fallback_line( struct intel_context *intel, | |||
} | |||
/**********************************************************************/ | |||
/* Render unclipped begin/end objects */ | |||
/**********************************************************************/ | |||
@@ -742,7 +733,6 @@ void intelChooseRenderState(GLcontext *ctx) | |||
intel->draw_tri = intel_draw_triangle; | |||
} | |||
#if 0 | |||
/* Hook in fallbacks for specific primitives. | |||
*/ | |||
if (flags & ANY_FALLBACK_FLAGS) | |||
@@ -758,8 +748,6 @@ void intelChooseRenderState(GLcontext *ctx) | |||
index |= INTEL_FALLBACK_BIT; | |||
} | |||
#endif | |||
} | |||
if (intel->RenderIndex != index) { |