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]); }
static void intelClearColor(GLcontext * ctx, const GLfloat color[4]) { struct intel_context *intel = intel_context(ctx); GLubyte clear[4]; CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); /* compute both 32 and 16-bit clear values */ intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], clear[2], clear[3]); intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); }
static void i915ImportTexObjState( struct gl_texture_object *texObj ) { i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData; int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0; if(INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); switch (texObj->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: break; } if ( texObj->MaxAnisotropy > 1.0 ) { minFilt = FILTER_ANISOTROPIC; magFilt = FILTER_ANISOTROPIC; } else { switch (texObj->MagFilter) { case GL_NEAREST: magFilt = FILTER_NEAREST; break; case GL_LINEAR: magFilt = FILTER_LINEAR; break; default: break; } } if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && texObj->Target != GL_TEXTURE_3D) { shadow = SS2_SHADOW_ENABLE; shadow |= intel_translate_compare_func( texObj->CompareFunc ); minFilt = FILTER_4X4_FLAT; magFilt = FILTER_4X4_FLAT; } t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK | SS2_MIP_FILTER_MASK | SS2_MAG_FILTER_MASK | SS2_SHADOW_ENABLE | SS2_SHADOW_FUNC_MASK); t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | (mipFilt << SS2_MIP_FILTER_SHIFT) | (magFilt << SS2_MAG_FILTER_SHIFT) | shadow); { GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK | SS3_TCY_ADDR_MODE_MASK | SS3_TCZ_ADDR_MODE_MASK); GLenum ws = texObj->WrapS; GLenum wt = texObj->WrapT; GLenum wr = texObj->WrapR; t->refs_border_color = 0; if (texObj->Target == GL_TEXTURE_3D && (texObj->MinFilter != GL_NEAREST || texObj->MagFilter != GL_NEAREST)) { /* Try to mimic GL_CLAMP functionality a little better - * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is * in use. Only do this for 3D textures at the moment -- * doing it universally would fix the conform texbc.c * failure, though. */ if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER; if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER; if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER; /* 3D textures don't seem to respect the border color. * Fallback if there's ever a danger that they might refer to * it. */ if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; } ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT; ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT; ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT; if (ss3 != t->Setup[I915_TEXREG_SS3]) { t->intel.dirty = I915_UPLOAD_TEX_ALL; t->Setup[I915_TEXREG_SS3] = ss3; } } { const GLubyte *color = texObj->_BorderChan; t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1], color[2],color[3]); } }
/* 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) { 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; GLuint *state = i830->state.Tex[unit], format, pitch; memset(state, 0, sizeof(state)); /*We need to refcount these. */ if (i830->state.tex_buffer[unit] != NULL) { dri_bo_unreference(i830->state.tex_buffer[unit]); i830->state.tex_buffer[unit] = NULL; } if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) return GL_FALSE; /* Get first image here, since intelObj->firstLevel will get set in * the intel_finalize_mipmap_tree() call above. */ firstImage = tObj->Image[0][intelObj->firstLevel]; if (intelObj->imageOverride) { i830->state.tex_buffer[unit] = NULL; i830->state.tex_offset[unit] = intelObj->textureOffset; switch (intelObj->depthOverride) { case 32: format = MAPSURF_32BIT | MT_32BIT_ARGB8888; break; case 24: default: format = MAPSURF_32BIT | MT_32BIT_XRGB8888; break; case 16: format = MAPSURF_16BIT | MT_16BIT_RGB565; break; } pitch = intelObj->pitchOverride; } else { dri_bo_reference(intelObj->mt->region->buffer); i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, intelObj-> firstLevel); format = translate_texture_format(firstImage->TexFormat->MesaFormat); pitch = intelObj->mt->pitch * intelObj->mt->cpp; } state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | (LOAD_TEXTURE_MAP0 << unit) | 4); /* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ /* t->intel.TextureOffset); */ state[I830_TEXREG_TM0S1] = (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format); state[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); { if (tObj->Target == GL_TEXTURE_CUBE_MAP) state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) | CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE | CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE | CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE); else state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit)); } { 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; } 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; } } state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; #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 state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - intelObj->firstLevel) * 4) << TM0S3_MIN_MIP_SHIFT; state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | (mipFilt << TM0S3_MIP_FILTER_SHIFT) | (magFilt << TM0S3_MAG_FILTER_SHIFT)); } { GLenum ws = tObj->WrapS; GLenum wt = tObj->WrapT; /* 3D textures not available on i830 */ if (tObj->Target == GL_TEXTURE_3D) return GL_FALSE; state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | MAP_UNIT(unit) | ENABLE_TEXCOORD_PARAMS | ss3 | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt)) | ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(translate_wrap_mode (ws))); } state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], tObj->_BorderChan[1], tObj->_BorderChan[2], tObj->_BorderChan[3]); 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: */ I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); return GL_TRUE; }
/* * Render a bitmap. */ static GLboolean do_blit_bitmap( GLcontext *ctx, GLint dstx, GLint dsty, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { struct intel_context *intel = intel_context(ctx); struct intel_region *dst = intel_drawbuf_region(intel); GLfloat tmpColor[4]; GLubyte ubcolor[4]; GLuint color8888, color565; if (!dst) return GL_FALSE; if (unpack->BufferObj->Name) { bitmap = map_pbo(ctx, width, height, unpack, bitmap); if (bitmap == NULL) return GL_TRUE; /* even though this is an error, we're done */ } COPY_4V(tmpColor, ctx->Current.RasterColor); if (NEED_SECONDARY_COLOR(ctx)) { ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor); } UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]); UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]); UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]); color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]); color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); /* Does zoom apply to bitmaps? */ if (!intel_check_blit_fragment_ops(ctx) || ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) return GL_FALSE; LOCK_HARDWARE(intel); if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t dest_rect; GLint nbox = dPriv->numClipRects; GLint srcx = 0, srcy = 0; GLint orig_screen_x1, orig_screen_y2; GLuint i; orig_screen_x1 = dPriv->x + dstx; orig_screen_y2 = dPriv->y + (dPriv->h - dsty); /* Do scissoring in GL coordinates: */ if (ctx->Scissor.Enabled) { GLint x = ctx->Scissor.X; GLint y = ctx->Scissor.Y; GLuint w = ctx->Scissor.Width; GLuint h = ctx->Scissor.Height; if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) goto out; } /* Convert from GL to hardware coordinates: */ dsty = dPriv->y + (dPriv->h - dsty - height); dstx = dPriv->x + dstx; dest_rect.x1 = dstx < 0 ? 0 : dstx; dest_rect.y1 = dsty < 0 ? 0 : dsty; dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width; dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height; for (i = 0; i < nbox; i++) { drm_clip_rect_t rect; int box_w, box_h; GLint px, py; GLuint stipple[32]; if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) continue; /* Now go back to GL coordinates to figure out what subset of * the bitmap we are uploading for this cliprect: */ box_w = rect.x2 - rect.x1; box_h = rect.y2 - rect.y1; srcx = rect.x1 - orig_screen_x1; srcy = orig_screen_y2 - rect.y2; #define DY 32 #define DX 32 /* Then, finally, chop it all into chunks that can be * digested by hardware: */ for (py = 0; py < box_h; py += DY) { for (px = 0; px < box_w; px += DX) { int h = MIN2(DY, box_h - py); int w = MIN2(DX, box_w - px); GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY; assert(sz <= sizeof(stipple)); memset(stipple, 0, sz); /* May need to adjust this when padding has been introduced in * sz above: */ if (get_bitmap_rect(width, height, unpack, bitmap, srcx + px, srcy + py, w, h, (GLubyte *)stipple, 8, GL_TRUE) == 0) continue; /* */ intelEmitImmediateColorExpandBlit( intel, dst->cpp, (GLubyte *)stipple, sz, (dst->cpp == 2) ? color565 : color8888, dst->pitch, dst->buffer, 0, dst->tiled, rect.x1 + px, rect.y2 - (py + h), w, h, logic_op); } } } intel->need_flush = GL_TRUE; out: intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); if (unpack->BufferObj->Name) { /* done with PBO so unmap it now */ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, unpack->BufferObj); } return GL_TRUE; }